今回は矢を飛ばすゲームをつくります。放たれた矢は重力の影響をうけて飛びます。発射地点は固定で時間の経過とともに発射可能方向がかわります。敵を撃ち落とすことができなかった場合は爆弾を投下され、一定のダメージをうけたらゲームオーバーという仕様です。

HTML部分

HTML部分を示します。ゲームで使うボタンはスタートボタンを除くと1つだけです。タイミングよく発射しましょう。

style.css

グローバル変数と定数

JavaScript部分を示します。

Arrowクラスの定義

矢の状態を更新・描画できるようにArrowクラスを定義します。

コンストラクタ

最初にコンストラクタを示します。引数はXYの初期座標とXY方向の初速です。これらをメンバ変数に格納します。

更新処理

更新処理を示します。経過時間(更新回数)と重力加速度から現在の速度を求め移動させます。そのあと当たり判定で必要になる先端部分の座標を求めます。また一番下まで落下していた場合は死亡フラグをセットします。

描画処理

描画処理を示します。矢の本体は先端と根元を直線でつなぐだけですが、矢らしく見えるように先端も描画することにしました。

Enemyクラスの定義

敵の状態の更新と描画処理をするためにEnemyクラスを定義します。

コンストラクタ

敵は左右から現れ反対側にむけて移動します。中央までくると爆弾を1発だけ投下します。そのため出現して移動した距離と爆弾を投下したかを示すメンバ変数を定義します。

更新処理と描画処理

更新処理と描画処理を示します。

矢との当たり判定

矢との当たり判定をおこなう処理を示します。

Bombクラスの定義

爆弾の状態と描画処理をするためにBombクラスを定義します。やっていることはコメントのとおりです(説明手抜き)。

ページが読み込まれたときの処理

ページが読み込まれたときの処理を示します。

まず画像ファイル(敵の画像ファイルはimagesフォルダ内にenemy0.png~enemy2.png)を読み込んで敵のイメージを配列に格納します。そのあと爆弾とライフ表示用の画像ファイルも読み込みます。また次に発射される矢のオブジェクトを生成します。引数は発射地点の座標を渡します。初速は更新処理で変化するので適当な値(0)でOKです。

そのあとcanvasサイズを調整して黒で塗りつぶします。イベントリスナーの追加します。

ゲーム開始の処理

ゲームを開始するときにおこなわれる処理を示します。

isPlayingフラグをセットしてスコア、ライフ、ゲームスピードに初期値をセットします。矢が発射可能かを示すフラグをセットして矢の発射角は60度とします。矢の発射角は時間の経過とともに変化しますが、最初は発射角は大きくしていきます。そのため矢の先端は左方向に移動していきます。

配列 arrows、enemies、bombsをクリアして最初の敵を生成します。そのあとスタートボタンを非表示にして発射ボタンを表示させます。

矢を発射する処理

矢を発射する処理を示します。

矢を無制限に発射できるとゲーム的に面白くないので連射制限をかけます。矢を発射したあとは0.5秒待たないとallowShotフラグがtrueになりません。発射可能でない場合はこの関数は呼び出されてもなにもしません。プレイ中でない場合も同様です。

発射処理をおこなう場合は現在の発射角度からXY方向の初速を求めます。Arrowオブジェクトを生成したらarrowsに格納します。そのあと効果音を鳴らします。

更新処理

更新処理を示します。プレイ中でない場合は何もしません。

ゲームスピードを少し速くしてupdateCountをインクリメントします。そのあと次に発射される矢の角度を変更するとともに各キャラクタを移動します。そのあと当たり判定をして死亡フラグが立っているオブジェクトを配列から除去します。

条件(後述)を満たしているのであれば新しい敵を生成します。また生きのこっている敵が中央まで移動しているのであれば爆弾を投下(ただし1回だけ)する処理をおこないます。

矢の発射角の変更

矢の発射角を変更する処理を示します。更新されるたびに矢の発射角を60~120度で変更します。

当たり判定

当たり判定の処理を示します。矢が当たっている敵があるか調べてあれば敵と矢に死亡フラグをセットします。そして効果音を鳴らして50点を加算します。

新しい敵の生成

新しい敵を生成する処理を示します。updateCountが128の倍数の場合、新しい敵を生成します。出現する場所は左端か右端、Y座標は80~180です(あまり高い位置だと矢が届かない)。水平方向の移動速度は 0.4 とゲームスピードの積です。

爆弾投下の処理

敵が爆弾を投下する処理を示します。

描画処理

描画処理の部分を示します。canvas全体を黒で塗りつぶし、爆弾、敵、矢、スコアを描画します。
矢を発射できる状態であれば次に発射される矢も描画します。

スコアとライフを描画する処理を示します。

次の矢の発射方向がわかるように次の矢を描画する処理を示します。描画は発射可能の場合だけおこないます。

ゲームオーバー時の処理

ゲームオーバー時の処理を示します。

isPlayingフラグをクリアして発射ボタンを非表示にします。isPlayingフラグがfalseになることで更新処理は行なわれなくなります。そのあとcanvas中央に’GAME OVER’と描画し、効果音を鳴らします。そのあとしばらく待機してからゲームスタート用のボタンを再表示させます。