我正在尝试为侧滚动游戏制作敌人产卵/移动系统 应该发生的是敌人会产生并向右移动直到它们与特定物体碰撞然后它们将以相反的方向行进。
我做了研究,并提出问题让我这么做:
我制作了一个敌人类,然后制作了一个列表,可以添加更多的敌人并设置他们各自的产卵位置。然后我创建了一个EnemyBlock
类,这样我就可以设置各种碰撞对象的位置(在这种情况下,它们只是砖块)。
我遇到了一些麻烦
A.让敌人离开游戏画面时转身
并且B.为敌人和敌人编写碰撞代码,就像我在Game1.cs Update
下foreach (Enemy enemy in enemies)
部分尝试编写碰撞代码一样,它不会选择敌人的矩形。如果这是有道理的。对不起,我对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;
}
}
答案 0 :(得分: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 =新矩形(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
}
}
}
我希望这一切都是正确和有帮助的。
答案 1 :(得分:0)
无论如何,我对XNA并不精通 尝试删除否定,因为代码看起来总是会反转速度,而不是在视口的边缘
if (GraphicsDevice.Viewport.Bounds.Contains(enemy.bounds))
{
enemy.velocity *= -1;
}
enemy.position += enemy.velocity;
这样,敌人的速度只有在到达边界时才会反转。 因为敌人永远都会移动,所以不需要另外发表声明。
至于与敌人的碰撞,这是MSDN制作像马里奥这样的2D侧滚动游戏的好教程。 CLICK HERE
教程中的所有内容都被视为二维数组地图上的一个tile对象,在更新时,它会检查敌人当前所在阵列的一个区块(敌人的位置)