0

まず、同じ質問をする別のスレッドを (多かれ少なかれ) 作成して申し訳ありませんが、私は答えを切望しており、他のスレッドは死んでしまいました。

私は現在、単純な 2D シューティングゲームを作ろうとしている学校向けのプロジェクトに取り組んでいます。問題は、2 つのリスト (タイトルに記載されている弾丸と敵) 間の衝突検出を実装する方法がわからないことです。私はプログラミングに非常に慣れていないため、ガイドとしてさまざまなチュートリアルを使用しています。一部のチュートリアルでは、ネストされた for ループと if ステートメントを使用するように言われていますが、if ステートメントを使用している他のチュートリアルを見たことがあります。 pixel by pixel one と呼ばれていたと思います。前もって感謝します!:)

これが私のコードです:

主要:

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

それを行うにはいくつかの方法があります...そのうちの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

ピタゴラスの定理はあなたのために働くことができます。

public float radius = 15;

以下を update void/subclass に入れて、毎秒発生するようにします。プレイヤーの X 位置を float にして、弾丸の 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 を作成します。

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

プレイヤーの半径がプレイヤーと弾丸の間の距離よりも小さい場合、弾丸はプレイヤーに当たったことになります。

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