螺旋状に弾を発射

XNA で ArrayList を使って螺旋状に弾を発射します。

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

ArrayList の説明

  1. C# の ArrayList を使って弾丸を発射します。
    ArrayList は List で連鎖された配列のようなもので、要素の「追加/挿入/削除」が簡単に出来るようになっています。
    ArrayList の基礎は「C#入門」を参照して下さい。
    ArrayList を使うときは System.Collections; を追加して下さい。
    using System;
    using System.Collections;               //Arrayを使うのに必要
    using System.Collections.Generic;
            :
    
  2. ArrayList の宣言です。
    array は個々の弾丸を管理する Fire Class の配列で ArrayList を使って登録します。
    ArrayList array; //弾を制御する ArrayList
  3. ArrayList は最初に初期化して下さい。
    array = new ArrayList(); //ArrayList の初期化
  4. ArrayList に弾丸(Fire Class)を一個登録します。
    Fire(2, 400, 300, i, add + (j * 90)) で Fire Class のコンストラクタを呼び出します。
    array.Add(new Fire(2, 400, 300, i, add + (j * 90)));
  5. ArrayList から弾丸(Fire Class)を削除します。
    index は ArrayList のインデックスで、削除する番号を指定します。
    array.RemoveAt(index);
  6. ArrayList に登録されている要素数だけループするコードです。
    Fire Class のメソッドや領域を参照するときは ((Fire)array[index]).flg のようにキャストして下さい。
        index = 0;
        while(index < array.Count)
        {
            if (!((Fire)array[index]).flg)
            {
                array.RemoveAt(index);
            }
            index++;
        }
        
    または、
        for(index=0; index < array.Count; index++)
        {
            if (!((Fire)array[index]).flg)
            {
                array.RemoveAt(index);
            }
        }
        
    index を使う必要が無いときは、次のように書くことが出来ます。
    Fire Class のメソッドを呼ぶときは FIRE を使います。
        foreach (Fire FIRE in array)
        {
            FIRE.Move();
        }
        

プログラムの説明

  1. Space キーで弾丸を螺旋状に発射します。
    メニューから [ファイル][新規作成][プロジェクト] で新しいプロジェクトを作成して下さい。
    このプログラムでは、4種類の弾丸を横に並べて透明色を設定した画像を使っています。
    読者がプログラムを作成するときは、適当な画像を調達して来て下さい。
    画像 説明
    tama4.png 4種類の弾丸を横に並べて透明色を設定した画像(32*32 を4枚)

  2. Game1.cs を編集して、弾丸を発射するプログラムを作成します。
    プログラムの最初に Fire Object Class を定義します。
    Fire Class のソースコードはページの後部からリンクしているので、こちらを参照して下さい。
    Fire Object Class の説明は Image Object Class に準じるので、 詳細は Image Class でアニメーション を参照して下さい。
    namespace Main
    {
        #region ★弾を管理するクラス
        public class Fire
        {
            //Fire Object Class を定義する
        }
        #endregion
    
  3. class Game1 の最初に、次の領域を宣言して下さい。
    tama は発射する弾丸の画像で、横=32, 縦=32 の画像を横に四枚ならべています。
    array は個々の弾丸を管理する Fire Class の配列で ArrayList で定義しています。
    Delay は弾を登録するタイミングを調整するフラグです。
    add は螺旋状に登録する回転角度を計算する領域です。
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
    
            Texture2D   tama;        //弾テクスチャ
            ArrayList   array;       //弾の制御 List
            int         Delay = 1;   //弾を登録するタイミングの調整
            int         add = 0;     //登録する回転角度
        
  4. Initialize() メソッドで ArrayList を初期化します。
            protected override void Initialize()
            {
                // TODO: Add your initialization logic here
                base.Initialize();
                base.Window.Title = "XNA Game Studio";
    
                array = new ArrayList();       //弾の制御 List
            }
        
  5. LoadContent() メソッドで Texture2D に画像をロードします。
    tama4.png が弾丸の画像です。
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
    
                // TODO: use this.Content to load your game content here
                tama = Texture2D.FromFile(graphics.GraphicsDevice, "c:\\data\\test\\tama4.png");
            }
        
  6. Update() メソッドで弾丸の発射と移動を行います。
    Delay がゼロのとき、array に 40 個の弾を登録します。
    array.Add() が ArrayList にセルを追加するコードで、new で Fire Class を生成して登録します。
    2 は弾の種類で、400,300 が弾の座標で、i が回転角度で、add+(j*90) が基本座標です。
    次に、座標がウインドウの外に出ている弾丸(flg==off)を削除します。
    最後に FIRE.Move() で array に登録されている弾丸の座標を移動します。
            protected override void Update(GameTime gameTime)
            {
                int index,i,j;
    
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
                KeyboardState keyState;
                keyState = Keyboard.GetState();
                if (keyState.IsKeyDown(Keys.Escape)) this.Exit();
    
                // TODO: Add your update logic here
                //弾丸の登録
                if (Delay == 0)         //Delay==0 のとき 40 個の弾を登録
                {
                    Delay = 1;
                    for (j = 0; j < 4; j++)
                    {
                        for (i = 0; i < 10; i++)
                        {
                            array.Add(new Fire(2, 400, 300, i, add + (j * 90)));
                        }
                    }
                    add = (add + 5) % 360;
                }
                else    Delay -= 1;
    
                //ウインドウの外(flg==OFF)を削除
                index = 0;
                while (index < array.Count)
                {
                    if (!((Fire)array[index]).flg)
                    {
                        array.RemoveAt(index);
                    }
                    else    index++;
                }
                foreach (Fire FIRE in array)            //弾の移動
                {
                    FIRE.Move();
                }
    
                base.Update(gameTime);
    
            }
        
  7. Draw() メソッドに画像を描画するコードを追加します。
    Array に登録されているフラグがオンの弾丸を回転しながら描画します。
    Sprite の回転は spBatch で画像を回転 を参照して下さい。
            protected override void Draw(GameTime gameTime)
            {
                graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
                // ArrayList の弾を描画
                foreach (Fire FIRE in array)
                {
                    if (FIRE.flg)
                        spriteBatch.Draw(tama, FIRE.pos, new Rectangle(FIRE.img * 32, 0, 32, 32), Color.White,
                                         FIRE.turn, new Vector2(32, 32), 1.0f, SpriteEffects.None, 1.0f);
                }
                spriteBatch.End();
    
                base.Draw(gameTime);
            }
        

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

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

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