今回は初歩的なシューティングゲームをつくります。簡単なシューティングゲーム 本当に鳩でも分かるC#講座のJavaScript版です。

HTML部分

最初にHTMLとCSS部分を示します。

style.css

JavaScript部分

主なグローバル変数と定数を示します。

app.js

画像ファイルの全体から一部を描画する

読み込む画像はこれです。

ここから必要な部分を切り取って表示させます。drawImage関数の引数は9個ありますが、1つ目が画像、2つ目から5つ目が切り取る左上のX座標とY座標、幅、高さです。6つ目から最後までが描画したい場所の左上の座標のX座標とY座標、幅、高さです。

プレーヤーの動作に関する処理

プレーヤーの描画に必要なグローバル変数を示します。

PlayerBulletクラスの定義

プレーヤーから放たれた弾丸に関する処理をするためにPlayerBulletクラスを定義します。

コンストラクタの引数は弾丸が発射された座標と移動速度です。PlayerBulletオブジェクトを生成したら配列に格納します。弾丸はまっすぐ上方向に移動します。敵に命中したり一番上(Y座標が0)まで命中することなく移動したらIsDeadフラグをセットします。IsDeadフラグがセットされたオブジェクトは配列から除去されます。

キーが押されたら自機を移動させます。その方向に移動するフラグをセットして実際の移動は更新時(後述)におこないます。弾丸の発射はスペースキーが押されたときにおこないますが、このままだとキーを押しっぱなしにしていると更新処理のたびに連射されてしまうので、一度キーを押したら一度離してもう一度押さないと発射されないようにします。

キーが離されたらセットしていたフラグをクリアします。

更新時にプレーヤーの座標を変更する処理をしめします。フィールドの外(見えない部分)に移動してしまわないように気をつけます。またIsDeadフラグがセットされているオブジェクトは配列から除去します。

敵の動作に関する処理

敵の動作と描画に関する処理を示します。敵と敵の弾丸も配列にいれて管理します。

Enemyクラスの定義

Enemyクラスを定義します。

敵の生成

敵を生成する処理を示します。上方で左右のどちらかから新しい敵を出現させます。また乱数で色(黄色・ピンク・青)も変化させます。

EnemyBulletクラスの定義

敵の弾丸の移動と描画をするためのEnemyBulletクラスを定義します。生成したオブジェクトは配列に格納します。

コンストラクタの引数は弾丸が出現するXY座標と1回の更新処理で移動する移動量です。自機と命中したりフィールドの外にでるとIsDeadフラグをセットします。そのあと配列のなかから除去されます。

敵弾の発射

敵が弾丸を発射する処理を示します。敵弾は自機がある方向に発射されますが、すべてが自機がある方向にそのまま飛んでくるのを避けるため、角度を乱数で30度ズラします。

敵の更新処理

敵の更新処理を示します。敵と敵弾を移動させ、IsDeadフラグがセットされているオブジェクトを配列から除去します。

火花の描画に関する処理

敵と自機に弾丸が接触したら爆発の描画をおこないます。爆発を構成する火花を管理するためにSparkクラスを定義します。

火花は発生してから消えるまで複数の画像を使います。更新回数を数えてどのイメージを使うかを決めています。

火花を移動させる処理を示します。更新時に火花が描画される座標を変更しIsDeadがセットされているものは配列から除去します。

当たり判定

当たり判定の処理を示します。効果音を出すためにAudioオブジェクトを生成しています。またゲームオーバーになったときは当たり判定はしません。自機も表示させません(後述)。

自機、敵、弾丸をここでは円とみなします。また半径は幅の半分とします。弾丸と接触しているかどうかは自機または敵と弾丸の距離と両者の半径の和を比較すればわかります。距離はX座標とY座標の差をそれぞれ二乗して足したものの平方根です。ただ平方根をとると処理に時間がかかるため、両者の2乗を比較します。

弾丸と敵が命中している場合は両者のIsDeadフラグをtrueにします。すると配列内から取り除かれ、描画もされなくなります。

自機から発射された弾丸が敵に命中した場合はスコアを増やして効果音もならします。敵弾が自機に命中した場合はゲームオーバーとします。どちらの場合も爆発の描画のための処理を開始します。

更新時の処理

更新時の処理を示します。キーが押されている場合は自機を移動させ、一定確率で敵を新しく生成します。ただし敵が1つも存在しない場合は必ず生成します。敵の移動の処理と弾丸の発射、弾丸の移動、当たり判定などを30分の1秒おきにおこないます。

またゲーム中はBGMを鳴らします。エンドレスで鳴り続けるように終わりのほうに近づいたら最初から再生しなおします(音が最後のほうは切れているので単純に繰り返し再生できない)。

描画処理

描画に関する処理を示します。

ゲームオーバー時は’GAME OVER’と描画します。

スコアを描画します。

ゲーム開始のための処理

ゲーム開始時の処理を示します。