2013-05-27 80 views
2

我正在試圖讓側面滾動遊戲的敵人產卵/移動系統。
應該發生的事情是敵人會產卵並向右移動,直到它們與特定物體發生碰撞,然後它們會沿相反的方向行進。XNA多級碰撞

我已經完成了研究並問了一些問題讓我走得這麼遠: 我製作了一個敵人的課程,然後創建了一個列表,可以添加更多的敵人並設置他們各自的產卵位置。然後我創建了一個EnemyBlock類,這樣我就可以設置各種碰撞對象的位置(在這種情況下,它們只是磚方格)。

我遇到了一些麻煩
答:讓敵人離開遊戲屏幕時轉身。
和B寫作的敵人和enemyblocks碰撞代碼,當我嘗試foreach (Enemy enemy in enemies)下譜寫Game1.cs Update部分碰撞碼不挑的enemyblock的矩形。如果這是有道理的。很抱歉,我對XNA代碼很陌生。

Game1.cs代碼

public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 

    public Rectangle bounds; 

    List<Enemy> Enemies = new List<Enemy>(); 
    List<EnemyBlock> Blocks = new List<EnemyBlock>(); 

    public Game1() 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
    } 


    protected override void Initialize() 
    { 
     // TODO: Add your initialization logic here 

     base.Initialize(); 
    } 


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

     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(50, 100))); 
     Enemies.Add(new Enemy(Content.Load<Texture2D>("Mario_Sprite"), new Vector2(100, 100), new Vector2(1, 0))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(500, 100))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(50, 200))); 
     Enemies.Add(new Enemy(Content.Load<Texture2D>("Mario_Sprite"), new Vector2(100, 200), new Vector2(1, 0))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(400, 200))); 

     foreach (Enemy enemy in Enemies) 
     { 
      enemy.bounds = new Rectangle((int)(enemy.position.X - enemy.texture.Width), (int)(enemy.position.Y - enemy.texture.Height), enemy.texture.Width, enemy.texture.Height); 
     } 
     foreach (EnemyBlock block in Blocks) 
     { 
      block.bounds = new Rectangle((int)(block.position.X - block.texture.Width), (int)(block.position.Y - block.texture.Height), block.texture.Width, block.texture.Height); 
     } 

    } 


    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 


    protected override void Update(GameTime gameTime) 
    { 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     foreach (Enemy enemy in Enemies) 
     { 
      if (!GraphicsDevice.Viewport.Bounds.Contains(enemy.bounds)) 
      { 
       enemy.velocity = -enemy.velocity; 
       enemy.position += enemy.velocity; 

      } 

      else 
      { 

       enemy.position += enemy.velocity; 

      } 
     } 

     base.Update(gameTime); 
    } 


    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 

     spriteBatch.Begin(); 
     foreach (Enemy enemy in Enemies) 
     { 
      spriteBatch.Draw(enemy.texture, enemy.position, Color.White); 
     } 
     foreach (EnemyBlock block in Blocks) 
     { 
      spriteBatch.Draw(block.texture, block.position, Color.White); 
     } 
     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 
} 
} 

敵人類代碼

class Enemy 
    { 
     public Texture2D texture; 
     public Rectangle bounds; 
     public Vector2 position; 
     public Vector2 velocity; 

     public Enemy(Texture2D Texture, Vector2 Position, Vector2 Velocity) 
     { 
      texture = Texture; 
      position = Position; 
      velocity = Velocity; 
     } 
    } 

EnemyBlock類代碼

class EnemyBlock 
{ 
    public Texture2D texture; 
    public Rectangle bounds; 
    public Vector2 position; 

    public EnemyBlock(Texture2D Texture, Vector2 Position) 
    { 
     texture = Texture; 
     position = Position; 
    } 
} 

回答

2

您的代碼似乎是結構良好,組織良好。使您能夠更輕鬆地找到任何這些問題,並感謝您的代碼組織。這是一個好習慣,它使大型項目更容易。

反正我覺得我可能會回答你的問題。

您的矩形沒有被拾起的原因是因爲你是初始化爲你的敵人和塊矩形您加載內容的方法。

這是除了你似乎沒有更新矩形的位置很好。儘管您檢查與邊界矩形的碰撞,但您更新了敵人和區塊的速度和位置。

這意味着你的敵人就可以移出屏幕,並通過對象,因爲你的抽籤位置已經移動,但矩形沒有這意味着它不會檢測到衝突。

我相信其它問題是與指定的矩形位置。我相信你的代碼可能有點關閉,但如果它工作的很好,那就離開它。但是如果碰撞檢測有一點關閉,那麼請嘗試以下操作。您的代碼

enemy.bounds = new Rectangle((int)(enemy.position.X - enemy.texture.Width), (int)(enemy.position.Y - enemy.texture.Height), enemy.texture.Width, enemy.texture.Height); 

應該像

enemy.bounds = new Rectangle(enemy.position.X, enemy.position.Y, enemy.texture.Width, enemy.texture.Height); 

根據你如何繪製圖像。

矩形的構造函數指定的左上角的x,y位置和矩形的寬度/高度。矩形r =新的Rectangle(100,100,200,200)創建在100,100和200寬,高大200的矩形。

這將匹配你如何畫你的敵人和街區。

而最後的碰撞代碼是相當簡單:

foreach(Enemy enemy in Enemies) 
{ 
    foreach(EnemyBlock block in Blocks) 
    { 
    if(enemy.bounds.Contains(block.bounds)) 
    { 
     //what to do on collision 
    } 
    } 
} 

我希望這是正確的,並幫助。

+0

你,卡明先生,是一個生命的救星。非常感謝。我一直在嘗試通宵不同的方式來讓代碼工作。製作新課程,新列表,新項目! 而且我喜歡讓我的代碼整齊這個確切原因。所以我可以去解決問題並輕鬆找到它們。 新代碼就像一個魅力。 – FLAVAred

+0

沒問題,我很樂意提供幫助。 :) –

0

我不精通的XNA,反正 嘗試刪除否定,因爲代碼看起來總是會反轉速度,而不是視口的速度邊緣

if (GraphicsDevice.Viewport.Bounds.Contains(enemy.bounds)) 
{ 
    enemy.velocity *= -1; 
} 
    enemy.position += enemy.velocity; 

有了這個,敵人的速度只有在到達邊界時纔會反轉。 因爲敵人總是在移動,所以不需要再聲明一下。

至於與敵方街區的碰撞,這裏有一個很好的來自MSDN的關於製作像馬里奧這樣的2D側面滾動遊戲的教程。 CLICK HERE

教程一切

被作爲二維數組地圖和更新圖塊對象處理,它會針對這裏的敵人正在站在陣列的區塊(敵人的位置)