2013-05-27 162 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

教程一切

被作为二维数组地图和更新图块对象处理,它会针对这里的敌人正在站在阵列的区块(敌人的位置)