自分だけのクイズ作成 - Quipha公開中

【#6】C#でゲームを作ろう【敵クラスの作成2】

C#
スポンサーリンク

敵クラスの作成2

実際に敵を表示してみましょう。
メイン画面(F_Main)のコードを表示してください。
ここでは敵クラスを配列に格納し、複数の敵を作成します。

そこで敵を格納する配列の定義と、その他変数を定義します。
メイン画面(F_Main)の先頭に定義します。

        // ランダム変数
        private Random _rnd = new Random();

        // 複数の敵を格納する変数
        private ArrayList _enemies = new ArrayList();

先頭に以下を追記します。

using System.Collections;

メイン画面(F_Main)のスタートボタン(B_Start)のクリックイベントを定義します。

クリックイベントに以下をコーディングしましょう。
配列に敵クラスを格納する理由は、次以降でランダムに動かしたりするために使いやすいようにです。

        /// <summary>
        /// スタートボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void B_Start_Click(object sender, EventArgs e)
        {
            // スタートボタンを使えなくする
            B_Start.Enabled = false;

            // 敵を生成します
            for (int i = 0; i <= 9; i++)
            {
                // 配列に敵クラスを生成します。その際にオーナーのパネルとランダム変数を渡します。
                _enemies.Add(new CEnemy(P_Enemy, _rnd));
                // ループの中でDoEventsを呼んでおく
                Application.DoEvents();
            }
        }

ここで以下のプロジェクトのフォルダに敵画像を配置します。(exeファイルと同じ階層におきます)
プロジェクトがC:\ClickBusterであれば以下の場所に画像を配置します。

C:\ClickBuster\ClickBuster\bin\Debug

敵画像は以下です。右クリックで画像を保存してください。

敵画像1

画像2

画像3

敵クラスの「_RandPlace」の実装で画像を指定しました。
得点はそれぞれ3000、1000、500と設定しましたので、大きい画像・中くらいの画像・小さい画像にしました。

それではアプリケーションを実行してみましょう。
初級ボタンをクリックし、スタートボタンをクリックすると敵が10体、ランダムな画像で、
ランダムな場所に出現したと思います。(画像が10体ない場合は大きい画像の後ろに隠れています)

一度メイン画面を閉じて、再度、初級ボタン→スタートボタンでまた違う場所に表示されると思います。

やっと半分くらい実装できました。
次に敵をランダムに動かす処理を実装していきます。

敵クラスの実装2

敵クラスをもう少し実装しましょう。CEnemyクラス(Class1.cs)を開きます。
敵をランダムに動かすメソッドを実装します。
メイン画面側では、ある一定間隔で次のメソッドを実行し、敵を動かします。
つまり呼ばれる度に、今いる位置より一歩移動します。

まず骨組みを作りましょう。
Case 1, 2, 3 はそれぞれenemy1、enemy2、enemy3の動きになります。

        /// <summary>
        /// 動かす(オーナーの中での動き)
        /// </summary>
        public void MvEnm()
        {
            switch (_intMovePattern)
            {
                case 1:

                    break;
                case 2:
 
                    break;
                case 3:
 
                    break;
            }
        }

動きのプログラミングは少し難しいかもしれませんが、一つずつ確認しましょう。

enemy1

まずはenemy1の動きを実装してみましょう。case 1の中に記述します。

仕様
  • enemy1はメイン画面のパネルの上を完全にランダムに移動します。
  • 上下左右にランダムに移動します。

コンストラクタで初期化したintMvwdは移動する幅です。この幅が大きいと移動する幅が増えます。
画像がパネルからはみ出さない場合、画像の場所(Top, Left)を移動しているところがポイントです。

                    //--------------------
                    // enemy1
                    // 完全ランダムな動き
                    //-------------------
                    var intMv = _rnd.Next(1, 5);
                    switch (intMv)
                    {
                        case 1:
                            // 下
                            if ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) < _enemyOwner.Height)
                            {
                                _pbImgEnemy.Top += _intMvwd;
                            }
                            break;
                        case 2:
                            // 上
                            if ((_pbImgEnemy.Top - _intMvwd) > 0)
                            {
                                _pbImgEnemy.Top -= _intMvwd;
                            }
                            break;
                        case 3:
                            // 右
                            if ((_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) < _enemyOwner.Width)
                            {
                                _pbImgEnemy.Left += _intMvwd;
                            }
                            break;
                        case 4:
                            // 左
                            if ((_pbImgEnemy.Left - _intMvwd) > 0)
                            {
                                _pbImgEnemy.Left -= _intMvwd;
                            }
                            break;
                    }

enemy2

次にenemy2の動きを実装してみましょう。case 2の中に記述します。

仕様
  • enemy2は上下左右に動きますが、上に移動したらぶつかるまで上に移動します。
  • ぶつかった時点で、今度はまた上下左右ランダムに動き、またぶつかるまで移動します。
                    //--------------------------
                    // enemy2
                    // 上下左右にぶつかるまで動く
                    //--------------------------
                    if (_intMvud == 0)
                    {
                        // 初回時だけは上下左右どちらに進むか決める
                        _intMvud = _rnd.Next(1, 5);
                    }

                    switch (_intMvud)
                    {
                        case 1:
                            // 下
                            if ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) < _enemyOwner.Height)
                            {
                                _pbImgEnemy.Top += _intMvwd;
                            }
                            else
                            {
                                _intMvud = _rnd.Next(1, 5);
                            }
                            break;
                        case 2:
                            // 上
                            if ((_pbImgEnemy.Top - _intMvwd) > 0)
                            {
                                _pbImgEnemy.Top -= _intMvwd;
                            }
                            else
                            {
                                _intMvud = _rnd.Next(1, 5);
                            }
                            break;
                        case 3:
                            // 右
                            if ((_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) < _enemyOwner.Width)
                            {
                                _pbImgEnemy.Left += _intMvwd;
                            }
                            else
                            {
                                _intMvud = _rnd.Next(1, 5);
                            }
                            break;
                        case 4:
                            // 左
                            if ((_pbImgEnemy.Left - _intMvwd) > 0)
                            {
                                _pbImgEnemy.Left -= _intMvwd;
                            }
                            else
                            {
                                _intMvud = _rnd.Next(1, 5);
                            }
                            break;
                    }

enemy3

さて最後の敵の動きです。case 3の中に記述します。

仕様
  • enemy3は斜めにぶつかるまで移動します。
  • ぶつかったらそれに跳ね返るような動きをします。

少し条件分岐が多くなります。

                    //--------------------------
                    // enemy3
                    // ななめに動く
                    //--------------------------
                    if (_intMvud == 0)
                    {
                        // 初回時だけは上下左右のななめに進むか決める
                        _intMvud = _rnd.Next(1, 5);
                    }

                    switch (_intMvud)
                    {
                        case 1:
                            // 斜め右下 
                            if ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) < _enemyOwner.Height)
                            {
                                _pbImgEnemy.Top += _intMvwd;
                            }
                            else
                            {
                                _intMvud = _rnd.Next(1, 5);
                            }

                            if (((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) < _enemyOwner.Height) &&
                                ((_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) < _enemyOwner.Width))
                            {
                                _pbImgEnemy.Top += _intMvwd;
                                _pbImgEnemy.Left += _intMvwd;
                            }
                            else
                            {
                                // 次は跳ね返った位置
                                if ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) >= _enemyOwner.Height)
                                {
                                    // 斜め右上
                                    _intMvud = 2;
                                }
                                else if ((_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) >= _enemyOwner.Width)
                                {
                                    // 斜め左下
                                    _intMvud = 3;
                                }
                            }
                            break;
                        case 2:
                            // 斜め右上
                            if (((_pbImgEnemy.Top - _intMvwd) > 0) &&
                                 (_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) < _enemyOwner.Width)
                            {
                                _pbImgEnemy.Top -= _intMvwd;
                                _pbImgEnemy.Left += _intMvwd;
                            }
                            else
                            {
                                // 次は跳ね返った位置
                                if ((_pbImgEnemy.Top - _intMvwd) <= 0)
                                {
                                    // 斜め右下
                                    _intMvud = 1;
                                }
                                else if ((_pbImgEnemy.Left + _pbImgEnemy.Width + _intMvwd) >= _enemyOwner.Width)
                                {
                                    // 斜め左上
                                    _intMvud = 4;
                                }
                            }
                            break;
                        case 3:
                            // 斜め左下
                            if (((_pbImgEnemy.Left - _intMvwd) > 0) &&
                               ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) < _enemyOwner.Height))
                            {
                                _pbImgEnemy.Top += _intMvwd;
                                _pbImgEnemy.Left -= _intMvwd;
                            }
                            else
                            {
                                // 次は跳ね返った位置
                                if ((_pbImgEnemy.Left - _intMvwd) <= 0)
                                {
                                    // 斜め右下
                                    _intMvud = 1;
                                }
                                else if ((_pbImgEnemy.Top + _pbImgEnemy.Height + _intMvwd) >= _enemyOwner.Height)
                                {
                                    // 斜め左上
                                    _intMvud = 4;
                                }
                            }
                            break;
                        case 4:
                            // 斜め左上
                            if (((_pbImgEnemy.Left - _intMvwd) > 0) &&
                               ((_pbImgEnemy.Top - _intMvwd) > 0))
                            {
                                _pbImgEnemy.Top -= _intMvwd;
                                _pbImgEnemy.Left -= _intMvwd;
                            }
                            else
                            {
                                // 次は跳ね返った位置
                                if ((_pbImgEnemy.Left - _intMvwd) <= 0)
                                {
                                    //斜め右上
                                    _intMvud = 2;
                                }
                                else if ((_pbImgEnemy.Top - _intMvwd) <= 0)
                                {
                                    // 斜め左下
                                    _intMvud = 3;
                                }
                            }
                            break;
                    }

敵の動きは実装できました。
少し難しいかも知れませんが、一行ずつ解読してみてください。

あと敵クラスで実装しておくべき処理は以下だけです。
敵が倒されたイベントです。倒された場合、また違う場所に出現します。
クラス内の下の方に関数を定義してください。

        /// <summary>
        /// 敵が倒されたイベント
        /// </summary>
        public void EnemyDown()
        {
            // 違う場所に出現する
            _RandPlace();
        }

また敵の得点のゲットです。

        /// <summary>
        /// 敵の得点のゲット
        /// </summary>
        /// <returns></returns>
        public int GetTokuten()
        {
            return _intTokuten;
        }

以上でやっと敵クラスの実装が完了しました。
次はメイン画面を実装していきます。

コメント

タイトルとURLをコピーしました