2014-02-15 64 views
1

對不起,所有的代碼,但我是完全新的Visual C#和XNA。XNA 4.0敵人產卵,反彈牆壁

這個程序了學習XNA 4.0亞倫蘆葦。我的教授修改了它應該做的一些東西(本書涵蓋了一些但不是全部)。大多數代碼是從書中複製的。

這些都是成品的最低要求:

  1. 您可以代替3戒指和骷髏球使用任何2幅圖像(或你仍然可以使用同樣的,如果你願意的話) - 一個是玩家(3個戒指),另一個是參與者(也稱爲敵人)
  2. 玩家精靈只能使用箭頭鍵移動(鼠標未激活)
  3. 參與者精靈會自動移動,你希望),他們反彈的邊界(以任何你選擇的方式)
  4. 在遊戲開始時有1個播放器和5參與者精靈
  5. 本場比賽持續了整整120秒,在比賽結束時,如果玩家精靈已經銷燬了所有參與者(敵方精靈)在屏幕上打印指示玩家獲勝的消息;否則打印玩家失去
  6. 每10秒的敵人精靈的新的化身出現在任何位置的消息
  7. 的玩家精靈,只有當它碰撞和「A」鍵在按下可以摧毀敵方精靈同時。如果「A」鍵無衝突按下那麼敵人的2個化身出現
  8. 敵人精靈必須以合理的速度移動(不是很慢,我的意思)的遊戲是有意義的
  9. 你需要有你的節目中的一些聲音 - 一種總是播放的背景聲音,一種當敵人被摧毀時播放的聲音,一種當玩家發射時發出不同聲音但敵人不會因爲沒有碰撞而被摧毀的聲音,一種新的敵人出現時的聲音(每10秒)

我試圖讓敵人(骷髏球)逃避玩家(threerings),但敵人或者不會對所有方面做出迴應(玩家在右邊或左邊, Ë nemy不會逃避,直到玩家在上面或下面),當敵人逃避時,他們會消失在屏幕外晃動(他們只是突然直行或向下,他們正在迅速晃動。

在10秒後的新敵人產卵,從左上角開始,它反彈的底壁,然後消失離屏幕當它回來了。

頭骨在10秒後也不會隨機產生在屏幕周圍。

此外,我不知道如何讓2個敵人產卵,當一個按鈕被按下,沒有衝突。

SpriteManager。CS

namespace Assignment_2 
{ 
    public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent 
    { 
     //SpriteBatch for drawing 
     SpriteBatch spriteBatch; 

     //A sprite for the player and a list of automated sprites 
     UserControlledSprite player; 
     List<Sprite> spriteList = new List<Sprite>(); 

     int enemySpawnMinMilliseconds = 10000; 
     int enemySpawnMaxMilliseconds = 10000; 
     int enemyMinSpeed = 10; 
     int enemyMaxSpeed = 10; 
     int nextSpawnTime = 0; 

     public SpriteManager(Game game) 
      : base(game) 
     { 
      // TODO: Construct any child components here 
     } 

     public override void Initialize() 
     { 
      // TODO: Add your initialization code here 
      ResetSpawnTime(); 
      base.Initialize(); 
     } 

     protected override void LoadContent() 
     { 
      spriteBatch = new SpriteBatch(Game.GraphicsDevice); 

      //Load the player sprite 
      player = new UserControlledSprite(
       Game.Content.Load<Texture2D>(@"Images/threerings"), 
       Vector2.Zero, new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(6, 6)); 

      //Load several different automated sprites into the list to test 
      //spriteList.Add(new AutomatedSprite(
      // Game.Content.Load<Texture2D>(@"Images/skullball"), 
      // new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0), 
      // new Point(6, 8), new Vector2(3, 0), "skullcollision")); 
      //spriteList.Add(new AutomatedSprite(
      // Game.Content.Load<Texture2D>(@"Images/skullball"), 
      // new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0), 
      // new Point(6, 8), new Vector2(-2, 0), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(3, 4), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(0, -3), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(-3, 7), "skullcollision")); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 0), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(-2, 0), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(0, -3), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(-3, 7), "skullcollision", this, .75f, 150)); 
      base.LoadContent(); 
     } 

     public override void Update(GameTime gameTime) 
     { 
      nextSpawnTime -= gameTime.ElapsedGameTime.Milliseconds; 
      if (nextSpawnTime < 0) 
      { 
       SpawnEnemy(); 

       //reset spawn timer 
       ResetSpawnTime(); 
      } 
      // Update player 
      player.Update(gameTime, Game.Window.ClientBounds); 

      // Update all sprites 
      for (int i = 0; i < spriteList.Count; ++i) 
      { 
       Sprite s = spriteList[i]; 

       s.Update(gameTime, Game.Window.ClientBounds); 

       // Check for collisions 
       if (s.collisionRect.Intersects(player.collisionRect) && (Keyboard.GetState().IsKeyDown(Keys.A))) 
       { 
        // Play collision sound 
        if (s.collisionCueName != null) 
         ((Game1)Game).PlayCue(s.collisionCueName); 

        // Remove collided sprite from the game 
        spriteList.RemoveAt(i); 
        --i; 
       } 
      } 

      base.Update(gameTime); 
     } 

     public override void Draw(GameTime gameTime) 
     { 
      spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend); 

      // Draw the player 
      player.Draw(gameTime, spriteBatch); 

      // Draw all sprites 
      foreach (Sprite s in spriteList) 
       s.Draw(gameTime, spriteBatch); 

      spriteBatch.End(); 
      base.Draw(gameTime); 
     } 
     // Return current position of the player sprite 
     public Vector2 GetPlayerPosition() 
     { 
      return player.GetPosition; 
     } 

     private void SpawnEnemy() 
     { 
      Vector2 speed = Vector2.Zero; 
      Vector2 position = Vector2.Zero; 

      // Default frame size 
      Point frameSize = new Point(75, 75); 
      // Create the sprite. NOTE: This sprite bounces off the bottom wall then goes back and disappears offscreen 
      spriteList.Add(
       new EvadingSprite(Game.Content.Load<Texture2D>(@"images\skullball"), 
       position, new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150)); 

     } 

     private void ResetSpawnTime() 
     { 
      nextSpawnTime = ((Game1)Game).rnd.Next(
      enemySpawnMinMilliseconds, 
      enemySpawnMaxMilliseconds); 
     } 
    } 
} 

EvadingSprite

class EvadingSprite : Sprite 
{ 
    // Save a reference to the sprite manager to 
    // use to get the player position 
    SpriteManager spriteManager; 

    // Variables to delay evasion until player is close 
    float evasionSpeedModifier; 
    int evasionRange; 
    bool evade = false; 

    public EvadingSprite(Texture2D textureImage, Vector2 position, 
     Point frameSize, int collisionOffset, Point currentFrame, 
     Point sheetSize, Vector2 speed, string collisionCueName, 
     SpriteManager spriteManager, float evasionSpeedModifier, 
     int evasionRange) 
     : base(textureImage, position, frameSize, collisionOffset, 
     currentFrame, sheetSize, speed, collisionCueName) 
    { 
     this.spriteManager = spriteManager; 
     this.evasionSpeedModifier = evasionSpeedModifier; 
     this.evasionRange = evasionRange; 
    } 

    public EvadingSprite(Texture2D textureImage, Vector2 position, 
     Point frameSize, int collisionOffset, Point currentFrame, 
     Point sheetSize, Vector2 speed, int millisecondsPerFrame, 
     string collisionCueName, SpriteManager spriteManager, 
     float evasionSpeedModifier, int evasionRange) 
     : base(textureImage, position, frameSize, collisionOffset, 
     currentFrame, sheetSize, speed, millisecondsPerFrame, 
     collisionCueName) 
    { 
     this.spriteManager = spriteManager; 
     this.evasionSpeedModifier = evasionSpeedModifier; 
     this.evasionRange = evasionRange; 
    } 

    public override Vector2 direction 
    { 
     get { return speed; } 
    } 

    public override void Update(GameTime gameTime, Rectangle clientBounds) 
    { 
     // First, move the sprite along its direction vector 
     position += speed; 

     // Use the player position to move the sprite closer in 
     // the X and/or Y directions 
     Vector2 player = spriteManager.GetPlayerPosition(); 

     if (evade) 
     { 
      // Move away from the player horizontally 
      if (player.X < position.Y) 
       position.X += Math.Abs(speed.Y); 
      else if (player.X > position.X) 
       position.X -= Math.Abs(speed.Y); 

      // Move away from the player vertically 
      if (player.Y < position.Y) 
       position.Y += Math.Abs(speed.X); 
      else if (player.Y > position.Y) 
       position.Y -= Math.Abs(speed.X); 

     } 
     else 
     { 
      if (Vector2.Distance(position, player) < evasionRange) 
      { 
       // Player is within evasion range, 
       // reverse direction and modify speed 
       speed *= -evasionSpeedModifier; 
       evade = true; 
      } 
     } 

     //make them bounce off walls 
     if (position.X > clientBounds.Width - frameSize.X || 
      position.X < 0) 
      speed *= -1; 

     if (position.Y > clientBounds.Height - frameSize.Y || 
      position.Y < 0) 
      speed *= -1; 
     base.Update(gameTime, clientBounds); 
    } 
} 
+0

我認爲你的問題是廣泛的,包含很多代碼的方式。請具體並明確您遇到問題的位置以及最終結果應該如何。 「我試圖讓精靈逃避。」沒有很多信息。規避代碼在哪裏?你打算做什麼?等等。 – Measuring

+0

@測量我把它裁減了一下。現在更清楚了嗎? – user3313728

+0

是的,現在好多了。所以在敵人的更新中,似乎有一個可能的循環,你設置evade = true,你從來沒有真正將它設置爲false(這也是有道理的,因爲你看到敵人在顫抖)。你有沒有試過調試那部分? – Measuring

回答

1

爲了您的碰撞代碼:

if (position.Y > clientBounds.Height - frameSize.Y || 
     position.Y < 0) 
     speed *= -1; 

你告訴精靈去只會上漲。基本上,當它在y方向上-1時,它沿正方向移動直到它變爲正值,在這種情況下它的移動負值。所以你一直在正面和負面的屏幕之間切換。我的建議是將這些陳述分成兩部分,這樣當你不避開你的時候,你就準確地從牆上彈開了。

if (position.X > clientBounds.Width - frameSize.X) 
     speed *= -1; 
    else if (position.X<=0) 
     speed*=1; 
    if (position.Y > ClientBounds.Height - frameSize.Y) 
      speed *= -1; 
    else if(position.Y > 0) 
      speed *= 1;