首先,我很抱歉让另一个线程问同样的问题(或多或少),但我迫切需要一个答案,而另一个线程已经死了。
我目前正在为学校做一个项目,我正在尝试制作一个简单的 2d 射击游戏。问题是,我不知道如何在我的两个列表(如标题中所述的子弹和敌人)之间实现碰撞检测。我对编程很陌生,一直在使用各种教程作为指导,一些教程说使用嵌套的 for 循环和 if 语句,而我看到其他人使用 if 语句,哦,我使用的是矩形碰撞方法而不是我认为它被逐个像素地调用。提前致谢!:)
这是我的代码:
主要的:
namespace Software_Design_Major_Project
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D ship; // Declaring the sprite
Vector2 shipposition = Vector2.Zero; // Creating a vector for the sprite.
List<bullets> bullets = new List<bullets>(); // a list is created here so that there can be multiple copies of this item at once without writing the extra code.
Texture2D texture;
KeyboardState pastkey;
//bullet sound effect.
SoundEffect effect;
List<enemies> Enemies = new List<enemies>();
Random random2 = new Random();
float spawn = 0;
public enum GameState
{
MainMenu,
Playing,
}
GameState CurrentGameState = GameState.MainMenu;
int screenWidth = 600, screenHeight = 480;
cButton play;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
//changes width of screen to 600px.
graphics.PreferredBackBufferWidth = 600;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
// This statement positions the ship.
ship = Content.Load<Texture2D>("ship"); // Loads the ship into the memory.
shipposition = new Vector2((graphics.GraphicsDevice.Viewport.Width / 2) - (ship.Width / 2), 420);
// loads bullet sprite
texture = Content.Load<Texture2D>("bullet");
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.ApplyChanges();
IsMouseVisible = true;
play = new cButton(Content.Load<Texture2D>("play"), graphics.GraphicsDevice);
play.setPosition(new Vector2(225, 220));
effect = Content.Load<SoundEffect>("laser");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
spawn += (float)gameTime.ElapsedGameTime.TotalSeconds;
// spawns enemy every second.
foreach (enemies enemy in Enemies)
enemy.update(graphics.GraphicsDevice);
MouseState mouse = Mouse.GetState();
switch (CurrentGameState)
{
case GameState.MainMenu:
if (play.isClicked == true)
CurrentGameState = GameState.Playing;
play.Update(mouse);
break;
case GameState.Playing:
if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.E))
{
Exit();
}
break;
}
// Allows the ship to move left and stops the ship going off the screen.
if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Left) && shipposition.X >= 0)
{
shipposition.X -= 7;
}// same as above except for the right direction.
if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) && shipposition.X < ((graphics.GraphicsDevice.Viewport.Width) - (ship.Width)))
{
shipposition.X += 7;
}
// this prevents the player from holding down space to spam bullets.
if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastkey.IsKeyUp(Keys.Space))
{
bullets bullet = new bullets(texture);
// the ships coordinates are gathered from the top left hand corner of the sprites rectangle therefore 'new Vector2(shipposition.X + 32, shipposition.Y)' had to
// be added rather than just = 'shipposition' to avoid having the bullets shoot from the wing.
bullet.position = new Vector2(shipposition.X + 32, shipposition.Y);
bullets.Add(bullet);
effect.Play();
}
pastkey = Keyboard.GetState();
//calls upon the update method from the bullets class.
foreach (bullets bullet in bullets)
bullet.update();
LoadEnemies();
base.Update(gameTime);
}
public void LoadEnemies()
{
int randX = random2.Next(10, 540);
if (spawn <= 1)
{
spawn = 0;
//limits amount of enemies on screen to 5.
if (Enemies.Count() < 5)
Enemies.Add(new enemies(Content.Load<Texture2D>("enemy"), new Vector2(randX, -100)));
}
for (int i = 0; i < Enemies.Count; i++)
{
if (!Enemies[i].enemyVisble)
{
//removes the enemies when they go off screen.
Enemies.RemoveAt(i);
i--;
}
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// calls draw method in bullets class
foreach (bullets bullet in bullets)
{
bullet.Draw(spriteBatch);
}
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(ship, shipposition, Color.White); // draws ship sprite
switch (CurrentGameState)
{
case GameState.MainMenu:
play.draw(spriteBatch);
spriteBatch.Draw(Content.Load<Texture2D>("menu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
break;
case GameState.Playing:
break;
}
foreach (enemies enemy in Enemies)
{
enemy.draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
子弹类:
namespace Software_Design_Major_Project
{
class bullets // A new class needs to be created to allow for bullets.
{
public Texture2D texture;
public Vector2 position;
public bool isvisible;
public bullets(Texture2D newtexture)
{
texture = newtexture;
isvisible = false;
}
public void update()
{
position.Y -= 3; // velocity of the bullet
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(texture, position, Color.White);
spriteBatch.End();
}
}
}
敌人等级:
namespace Software_Design_Major_Project
{
public class enemies
{
public Texture2D enemyTexture;
public Vector2 enemyPosition;
public bool enemyVisble = true;
public float enemyMoveSpeed;
public int Value;
Random random = new Random();
int randY;
public enemies (Texture2D newEnemyTexture, Vector2 newEnemyPosition)
{
enemyTexture = newEnemyTexture;
enemyPosition = newEnemyPosition;
randY = random.Next(1, 4);
enemyMoveSpeed = randY;
enemyVisble = true;
Value = 100;
}
public void update(GraphicsDevice graphics)
{
enemyPosition.Y += enemyMoveSpeed;
if (enemyPosition.Y > 500)
enemyVisble = false;
}
public void draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(enemyTexture, enemyPosition, Color.White);
enemyVisble = true;
}
}
}