0

首先,我很抱歉让另一个线程问同样的问题(或多或少),但我迫切需要一个答案,而另一个线程已经死了。

我目前正在为学校做一个项目,我正在尝试制作一个简单的 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;

        }

    }

}
4

2 回答 2

1

你有几种方法可以做到这一点......其中一种可能会为敌人和子弹添加无线电属性......

  for (int bi=0; bi<bullets.count; )
  {
      bool should_destroy_bullet = false;
      Bullet b = bullets[bi];
      for (int ei=0; ei<enemies.count; )
      {
         Enemy e = ememies[ei];
         if (b.radio + e.radio < Vector2.Distance(b.Pos, e.Pos))  // Check collision
         {
             e.Died();
             enemies[ei] = enemies[enemies.Count-1];
             enemies.RemoveAt(enemies.Count-1);
             should_destroy_bullet = true;  // This lets a bullet kill more than one enemy
         } else ei++;
      }

      if (should_destroy_bullet) {
            b.Died();
            bullets[bi] = bullets[bullets.count-1];
            bullets.RemoveAt(bullets.count-1);
      } else bi++;
  }               

或者你可以为每个精灵建立一个矩形并检查它们是否相交......

   if (b.Bounds.Intersects(e.Bounds)) ....
于 2012-07-28T13:24:00.600 回答
0

勾股定理可以为你工作。(A平方加B平方=C平方)让你的玩家和敌人有一个半径。把它放在你的构造函数中。

public float radius = 15;

将以下内容放入更新无效/子类中,以便每秒发生一次。使玩家的 X 位置浮动并减去子弹的 X 位置。平方它。

float XDist = Math.Pow(player1.location.X - bullet.location.X,2);

使播放器的 Y 位置浮动并减去它的 Y 位置bullet.Square

float YDist = Math.Pow(player1.location.X - bullet.location.X,2);

做一个浮点数来计算 Xdist 和 Ydist 之和的平方根。

float actualDist = Math.Sqrt(Xdist + Ydist);

现在如果你的玩家的半径小于玩家和子弹之间的距离,子弹已经击中了玩家。

if(actualDist < radius)
   bullethit == true;
于 2013-02-17T01:39:21.730 回答