前回は肝心の自機がありませんでした。そこで今回は自機を表示させます。また自機めがけてミサイルを発射させます。

そのまえに上の画像をみると、フォームの大きさを変更するとマップの見える部分が変わっていることに気づきます。これではよくないのでフォームの大きさは一定(640×480ピクセル)にします。

自機の位置を管理するクラスを作成します。

コンストラクタ内でSetStartPosition()メソッドを実行しています。自機の位置はフィールド変数 XとYで表しますが、SetStartPosition()メソッドでXとYの値を最初に表示されるべき位置にセットしているわけです。そのときにForm1.ProjectionWidthの値を利用しています。またフィールド変数 startXにこのとき得られた値を保存しています(あとで使う)。

Move(float x, float y)メソッドの引数は「どれだけ移動するか」です。

次に自機を操縦できるようにします。

これは自機が移動する方向を示す列挙体ですが、「後ろ」がありません。戦闘機なので加速はできてもバックすることはできないのです。

まずゲームがスタートしたら自機を表示させます。

CurDirectプロパティに移動したい方向をセットして、Timer.Tickイベントを待ちます。イベントが発生したらStageクラスの自作メソッド Update()を実行します。

StageクラスのUpdateメソッドで自機を動かします(ここでは座標を設定しているだけ)。それから動かさなくても自機は前方に移動しています(通常の飛行)。ただし加速後の減速時には通常の飛行はしません。この場合、自機は後方に移動します。これを利用すると垂直に移動させることができます。この技が使えないとステージクリアは難しいです。

加速後の状態かどうかは、自機のX座標と(カメラのX座標+Jiki.startX)を比較して判別しています。

次に自機めがけてミサイルを発射させます。発射すれば命中するタイミングで発射するようにしないといけないのですが、全部のミサイルをそのようにしてしまうとよけやすくなるので早めのタイミングで発射したり、あえて発射しないという工夫が必要です。

Missileクラスのコンストラクタを少し変更しました。コンストラクタのなかで発射のタイミングを決めてしまいます。(生成した乱数-3)が0であれば最適のタイミング、正数であれば早め、負数であれば遅めのタイミングで発射されます。

StageクラスのMissilesLaunch()メソッドは自機と各ミサイルの座標からどれだけX座標が違っていれば発射のタイミングが最適かを調べます。これと各ミサイルに設定されているタイミングを比較して、本当にミサイルを発射するかどうかを決めます。

発射するときはミサイルクラスのフィールド変数 isMoveをtrueにします。MissilesMove()メソッドが実行されると撃墜されていないミサイルでisMoveがtrueのものだけ上昇していきます。