Enemy が動き回るルートを設定

Enemy の画像と、動き回るルートを構造体の配列で設定します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. シューティングゲームでは、Enemy の出現パターンがゲームを面白くする大切なファクターです。
    一般的にゲームの最終調整はゲームデザイイナー(企画者)が行います。
    このとき、いちいちプログラマの手を借りずにテーブルの値を変更するだけで、調整できるこのような機能は必須です。
    ゲームを実行するプログラムを「エンジン」と言いますが、エンジンは同じでも与えるコンテンツ(画像や音声)が違えば別のゲームかと思われます。
    コンテンツに加えて様々な制御データをテーブルで定義して、新しいゲームプログラムを作成すると言う考え方があります。
    ゲームツクールはその代表例ですが、そこまで行かなくても多かれ少なかれこのような方法が用いられています。
  2. C# では C++ のように構造体の定義と同時に初期値を設定することは出来ません。
    そこで Struct の宣言にコンストラクタを定義して new で初期値を設定します。
    struct Course の説明は 構造体で Enemy のコースを設定 を参照して下さい。
  3. Enemy が動き回るルートを struct Course を使って、構造体の配列で定義します。
    下記の例では、Enemy が姿を変えながら5つのコースを順番に動き回ります。
    Vector2.One は現在の座標をそのまま継続して使用すると言う特別の目的で使っています。
            public Course[] tbl = new Course[]
            {   new Course(400, 0, new Vector2(-80, 20), new Vector2(2, 0)),
                new Course(200, 1, Vector2.One, new Vector2(-2, 0.5f)),
                new Course(200, 2, Vector2.One, new Vector2(0, 1)),
                new Course(200, 3, Vector2.One, new Vector2(-2, 1)),
                new Course(400, 4, new Vector2(800, 600), new Vector2(-2, -1.5f))
            };
        
  4. 設定されたルートに従って Enemy を移動する領域の定義です。
    t_no は tbl[] の番号(インデックス)で、-1 のときは Enemy を描画しません。
    その他の説明は 構造体で Enemy のコースを設定 を参照して下さい。
            Texture2D   texture;                    //画像テクスチャ
            Vector2     pos;     //画像の座標
            Vector2     vect;    //画像の移動
            int         sp_no;                      //画像の番号
    
            double      Timew = 0;                  //前回の切り替え時間
            double      Speed = 20;                 //切り替え速度
            int         t_no = -1;                  //tbl の番号
            int         fcnt = 0;                   //フレームカウント
        
  5. Update() メソッドです。
    構造体の配列 tbl[] の定義に従って Enemy が動き回ります。
    tbl[t_no].pos.X と tbl[t_no].pos.Y が共に1のときは、現在の座標をそのまま継続します。
    Enter キーをタイプすると、最初に戻ります。
            protected override void Update(GameTime gameTime)
            {
                // ゲームを終了する
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed  ||
                    Keyboard.GetState().IsKeyDown(Keys.Escape)) this.Exit();
    
                // TODO: Add your update logic here
                if (Timew + Speed < gameTime.TotalGameTime.TotalMilliseconds)
                {   Timew = gameTime.TotalGameTime.TotalMilliseconds;
                    // 画像の移動
                    if (fcnt>0)
                    {   fcnt--;
                        pos += vect;
                    }
                    else
                    {   if (t_no<tbl.GetLength(0))  t_no++;
                        if (t_no<tbl.GetLength(0))
                        {   fcnt = tbl[t_no].frame;
                            sp_no = tbl[t_no].img_no;
                            if (tbl[t_no].pos.X != 1 && tbl[t_no].pos.Y != 1)   pos = tbl[t_no].pos;
                            vect = tbl[t_no].vect;
                        }
                    }
                }
    
                if (Keyboard.GetState().IsKeyDown(Keys.Enter))
                {   t_no = -1;
                    fcnt = 0;
                }
    
                base.Update(gameTime);
            }
        

【演習】

  1. 幾つかのコースを設定して Enemy を動かしてみて下さい。
  2. どのコースをたどるかを乱数を使って選びながら動かして下さい。

前田稔(Maeda Minoru)の超初心者のプログラム入門

超初心者のプログラム入門(XNA(C#) game program)