前回はC# Windows Formsで昔なつかしいミサイルコマンドのようなゲームを作ってみましたが、今回はTypeScriptで同じようなゲームをつくってみました。

前回の記事

ミサイルコマンドのようなゲームをつくる(1)
ミサイルコマンドのようなゲームをつくる(2)

今回TypeScriptで作成したゲーム

動作確認はこちらからどうぞ。

ではコードを示します。C#をTypeScriptで書き換えただけです。

まずhtml部分をしめします。

これだけです。あとはapp.tsに以下のコードを書いてコンパイルすればapp.jsがつくられます。あと同じディレクトリに画像ファイルとmp3ファイルをおいておきましょう。

都市を描画するためのCityクラス

都市を描画するためのCityクラスを示します。考え方はC#のときとあまり変わりません。コンストラクタ内で都市が描画される矩形の上下左右の座標と中央の座標を計算しています。

敵のミサイルを描画するためのEnemyMissileクラス

次に敵のミサイルを描画するためのEnemyMissileクラスを示します。これもC#をTypeScriptに置き換えただけです。

迎撃ミサイルを描画するためのMyMissileクラス

迎撃ミサイルを描画するためのMyMissileクラスを示します。

爆発を描画するExplosionクラス

爆発を描画するExplosionクラスを示します。前回のプログラムでは敵ミサイルが爆発に巻き込まれたら撃墜成功ということで無条件に得点にしていましたが、敵ミサイルが都市に着弾して爆発、そこで別の敵ミサイルがきた場合、これも誘爆して得点としてカウントされるという問題がありました。そこで敵ミサイルが都市に着弾して爆発した場合はこれを判別するフラグをつくって得点にはならないようにしています。

ここからはクラスは使いません。

Init関数はゲームの初期化をするための関数です。都市のイメージを読み込み、ターゲットを中心にもっていきます。

1秒間に60回Update関数が呼び出されます。各オブジェクトの状態が変更されてDraw関数が呼び出されます。

Draw関数では敵ミサイルとプレイヤーの迎撃ミサイル、残存都市、爆発、迎撃目標を選択するためのターゲット(+マークのもの)を描画します。

キーが押されたときの動作です。ターゲットがどちら側に移動するかを示すグローバル変数 MoveLeftなどをtrueにします。迎撃ミサイルの発射やゲームオーバー後の再挑戦の処理もここでおこなわれます。

キーが離されたときの動作です。ターゲットの動きが停止します。

Update関数内で呼び出されます。方向キーをおしたままだとターゲットが移動しますが、画面の外には出ないようにしています。

DrawTarget関数は、グローバル変数のTargetXとTargetYをもとにターゲットを描画する処理を行ないます。

MoveEnemyMissile関数は1秒間に60回、敵を移動させる処理をおこないます。

CreateEnemyMissile関数は敵ミサイルを新たに出現させる処理をおこないます。

Shot関数は敵ミサイルを迎撃するためのミサイルを発射する処理をおこないます。

MoveMyMissiles関数は迎撃ミサイルを移動させる処理をおこないます。そして目標地点に到達すると爆発処理にはいります。

UpdateExplosions関数はExplosionクラスのUpdate関数を呼び出して、爆発を状態を変更させます。

CheckEnemyMissileLanding関数は敵のミサイルが着弾したかどうかを調べます。

CheckHitEnemyMissile関数は迎撃ミサイルの爆発で敵のミサイルを撃墜できたかを調べます。撃墜成功の場合はOnHitEnemyMissile関数を呼び出して得点を加算します。しかし敵のミサイルが都市に着弾した場合は近くにある敵のミサイルを誘爆させません。

OnHitEnemyMissile関数は敵のミサイルを撃墜したときに呼び出されます。25点を追加します。また爆発音を鳴らします。

DrawScore関数はスコアを表示するための関数です。

DrawStringIfGameOver関数はゲームオーバーになっているときにDraw関数のなかで呼び出されます。文字が中央にくるようにCanvasRenderingContext2D.measureText関数を使用して中心に描画するために適切な座標を調べています。

Retry関数はゲームオーバーになったあと、もう一度ゲームをするときに呼び出される関数です。得点と敵ミサイルの落下速度の鍵となるUpdateCountをリセットしています。そして破壊された都市を復元し、ターゲットを中心に戻してゲームを再開させます。

あとはグローバル変数だけです。これでInit関数を実行すればゲームを開始することができます。