2

横スクロールゲームの敵の出現・移動システムを作ろうとしています。
起こるはずのことは、敵がスポーンし、特定のオブジェクトと衝突するまで右に移動し、その後反対方向に移動することです。

私は調査を行い、ここまで来るために質問をしました。敵のクラスを作成し、さらに敵を追加して個々のスポーン位置を設定できるリストを作成しました。次にEnemyBlock、さまざまな衝突オブジェクトが配置される場所を設定できるようにクラスを作成しました (この場合、それらは単なるレンガの正方形です)。


A. 敵がゲーム画面から出たときに、敵を振り向かせるのに苦労しています。B. 敵と敵ブロックの衝突コードを書いても、その下のセクションに
衝突コードを書き込もうとすると、敵ブロックの四角形が選択されません。それが理にかなっていれば。申し訳ありませんが、私は XNA コードにかなり慣れていません。Game1.cs Updateforeach (Enemy enemy in enemies)

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;
    }
}
4

2 に答える 2

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 位置と幅/高さを指定します。Rectangle r = new 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
    }
  }
}

これがすべて正しく、役立つことを願っています。

于 2013-05-27T11:50:55.680 に答える
0

とにかく、否定を削除してみてください。コードは、ビューポートの端にない間は常に速度を逆転させるように見えるため

 if (GraphicsDevice.Viewport.Bounds.Contains(enemy.bounds))
 {
     enemy.velocity *= -1;
 }
     enemy.position += enemy.velocity;

これにより、敵の速度は境界に達したときにのみ反転します。敵は常に動いているのでelse文を入れる必要はありません。

敵のブロックとの衝突については、マリオのような 2D 横スクロール ゲームの作成に関する MSDN の優れたチュートリアルを参照してください。ここをクリック

チュートリアルでは、すべてが 2D 配列マップ上のタイル オブジェクトとして扱われ、更新時に、敵が現在立っている配列のタイル (敵の位置) に対してチェックします。

于 2013-05-27T11:26:24.247 に答える