今回はディフェンダーに似たオンライン対戦ゲームをつくります。

『ディフェンダー』(Defender)は1980年にウィリアムスが開発したアーケードゲームで任意横スクロールのシューティングゲームです。ランダーという敵が常に地上にいる人間を画面上部へとさらおうとする要素は入れていません。原作では横スクロールですが、これだとスマホで遊びにくいので縦スクロールにしています。左右に移動可能、上下は自機の向きと進行方向、移動速度が変わります。単純に敵を倒すだけでなく複数のプレイヤー同士で互いを攻撃することができる仕様にしています。

ちなみに元々の『ディフェンダー』(Defender)はこのようなゲームです。

ではさっそくつくっていきましょう。名前空間はDefenderとします。

Constクラスの定義

定数に関する定義をします。

Bulletクラスの定義

弾丸を移動させ描画するためにBulletクラスを定義します。

以降は名前空間の部分は省略して書きます。

コンストラクタとプロパティ

コンストラクタとプロパティを示します。

最初はインスタンスだけ生成して弾丸自体は存在しないのでIsDead = true;をセットします。

発射位置と発射速度の設定

Initメソッドは弾丸が発射されたときに各プロパティに初期座標(発射位置)と移動速度(発射速度)をセットするためのものです。

更新処理

Updateメソッドは移動速度分、弾丸の座標を移動させます。このときフィールドの一番上または下に移動したものは反対側へワープさせます。左右からはみ出したものは死亡フラグをセットします。またどこまでも飛び続けないように更新回数や移動距離が一定数に達した場合も死亡フラグをセットしています。

Sparkクラスの定義

爆発したときに発生する火花の描画処理をするためにSparkクラスを定義します。

以降は名前空間の部分は省略して書きます。

コンストラクタとプロパティ

コンストラクタとプロパティを示します。最初はインスタンスを生成だけで火花は存在しないので IsDead = true;をセットします。

Initメソッドは火花が発生したときに発生場所の座標と移動速度を各プロパティにセットします。

発生場所の座標と移動速度の設定

更新処理

Updateメソッドは移動速度分、火花の座標を移動させます。また更新回数によって火花の状態を変化させます。火花が消滅する段階で死亡フラグをセットしています。

Playerクラスの定義

各プレイヤーの移動処理や描画処理をするためにPlayerクラスを定義します。

以降は名前空間の部分は省略して書きます。

コンストラクタと各プロパティを示します。

最初はインスタンスを生成するでプレイヤーはゲームに参加していません。なのでIsGameOvered = true;をセットします。またサーバーサイドアプリケーションでオブジェクトを生成したり破棄するのはあまりよくないので、手持ちの弾丸を最初に生成し、途中で追加の生成はしないでこれを使い回すことにします。

新規参加と復帰時の処理

引数ありのInitメソッドは新しくプレイヤーがゲームに参加したときに呼び出されます。プレイヤー名とconnectionIdをプロパティにセットします。また残機数、スコアを初期値にセットし、IsGameOveredフラグをクリアします。そのあと引数なしのInitメソッドを呼び出します。

引数なしのInitメソッドは自機死亡後に復帰するときに呼び出されます。各プロパティに初期位置と初期速度をセットし、しばらくのあいだ無敵状態にします。

更新処理

Updateメソッドは更新処理をおこないます。

死亡フラグがセットされていないときだけ移動処理をおこないます。無敵状態のときは点滅させ、そうでないときはつねに表示させますが、死亡時は非表示とします。縦方向の移動はフィールドの上下からはみ出したら反対側にワープさせますが、横方向の移動はフィールドからはみ出さない場合だけ行なうことにします。

弾丸の発射

Shotメソッドは弾丸の発射処理をおこないます。

自機死亡時または発射不能時はなにもしません。無制限に連射できてしまうと困るので、発射後0.2秒経過しないと発射できない仕様にします。発射地点の座標と発射方向が求められたら、これらをBullet.Initメソッドに引数として渡します。発射処理が正常に完了したらtrue、そうでない場合はfalseを返します。

移動方向の変更

ユーザーのキー操作、ボタンのクリック、タップで移動方向を変更できるようにします。X方向は一定速度で移動しますが、Y方向は加速、減速があるのでメソッドをわけています。AddVelocityYメソッドは加速処理の結果、速度の絶対値が大きくなったときはtrueを返します(スピードアップ時に効果音を再生したいので)。

Enemyクラスの定義

敵の移動処理や描画処理をするためにEnemyクラスを定義します。

以降は名前空間の部分は省略して書きます。

コンストラクタとプロパティ

コンストラクタとプロパティを示します。

初期化直後と復帰時の処理

Initメソッドはコンストラクタが呼び出されたときと死亡状態から復帰したときに呼び出されます。ここでは出現させる座標と移動速度を乱数で決定しています。

更新処理

更新処理を示します。生成されたばかりの敵は点滅させ、そうでないなら常に表示します。死亡フラグがセットされている敵は表示させません。死亡フラグがセットされていないのであれば移動処理をおこないます。また死亡フラグにかかわらず(生前に発射した弾丸があるかもしれないので)弾丸の移動をおこないます。

弾丸を発射する処理

弾丸を発射する処理を示します。弾丸は放射状に6個発射します。リストのなかに死亡フラグがセットされている弾丸があるはずなので、最初にみつかったものに新たな初期座標と初期速度を設定し