JavaScriptでミスタードリラーもどきを作る(2)の続きです。今回はブロックを落下させる処理を実装します。

ブロックの落下処理

ブロックが破壊されることで落下を開始するブロックがある場合は落下処理をおこないます。カプセル以外のブロックは支えがなくなるとグラグラ振動し、しばらくすると落下を開始ます。

支えがないブロックを取得する

そこでまず「支えがないブロック」を取得します。その取得方法ですが、幅優先探索で取得します。

一番下の行にある破壊されていないブロックを起点とする
上に破壊されていないし落下を開始していないブロックがあるならたどっていく
上下左右に破壊されていないし落下を開始していない同色のブロックがあるならたどっていく
(ただしエアカプセルはくっつかないので下・左・右にはたどらない)
たどりつくことができなかったブロックは支えがないブロックである

落下待機モードへの変更

支えがないブロックを取得したら落下待機状態にします。ただしエアカプセルはただちに落下させます。ただし、
エアカプセルであっても下にブロックがある場合はただちに落下することができないので待機状態にします。

ブロックの更新

ブロックの更新処理は以下のようになります。

Block.Update()を実行する
Block.FinishedFall == true になっているものがあれば落下が完了したブロックなのであるなら確認する
Block.FinishedFall == true になっているブロックはBlock.Rowの値をインクリメントし、二次元配列 blocks2x2の格納位置を変更する
落下が完了したブロックがない場合はこれで処理は終了
そうでない場合は他のブロックとくっつくものと引き続き落下するものにわける
引き続き落下する場合は待機時間なしで次の落下処理を開始する。ただし下(同色のブロックであれば上下左右)に落下待機モードのブロックがある場合は自分自身もその時間は待機する
くっつくものは同色で4つ以上くっついている場合、消滅させる
消滅した場合、新たな支えがないブロックが発生するので blocksToFallMode(getNoSupportBlocks()); を実行する

あたり判定

あたり判定(プレイヤーの死亡判定)は以下のようにおこないます。

すでにプレイヤー死亡の場合はなにもしない
エアカプセル以外の破壊されていないブロックがプレイヤーと同じ位置に存在する場合、プレイヤーと同じX座標でY座標の差がBLOCK_SIZE / 8未満の位置に存在する場合はプレイヤー死亡とする
プレイヤーがいる位置にカプセルがある場合はカプセル回収の処理をおこなう

カプセルを回収時の処理

カプセルを回収したときの処理を示します。

エアカプセルの死亡フラグのセット
回収数の加算
カプセルが破壊されることで支えがないブロックが発生するかもしれないので blocksToFallMode(getNoSupportBlocks()) を実行する
エアの回復(最大値を超えない範囲で最大値の10%分)
スコアの加算
爆発の火花の発生
効果音の再生

プレイヤー死亡時の処理

プレイヤー死亡時は以下の処理をおこないます。

死亡フラグのセット
残機 1 減らす
効果音の再生
爆発の火花の発生
自機がまだ存在する場合はプレイヤーを復活させる
存在しない場合はゲームオーバー処理

プレイヤーを復活させる処理を示します。

プレイヤーがいる位置から上にあるブロックは必要ないので対応するblocks2x2[row][col]にnullを代入しています。またそれよりも下の部分は残すのですが、落下中のブロックが宙ぶらりんの状態で浮いてしまうので落下状態と待機状態をいずれも解除して落下処理前の位置に再設定しています。

そのあと死亡位置の中央でプレイヤーを復活させます。

ゲームオーバー時とステージクリア時の処理

ゲームオーバー時は以下の処理をおこないます。

効果音の再生とBGMの停止
スマホ用の操作ボタンの非表示
ゲームスタートボタンの再表示
press◯◯Keyフラグのクリア

地味に重要なのがプレイヤーを移動させるためのpress◯◯Keyフラグのクリアです。スマホでプレイしていてゲームオーバーになった場合、これにともなって操作用ボタンが消えてしまうのでこれらのフラグはユーザーの操作ではクリアされなくなるのです(PCからの操作であれば問題ない)。

ステージクリア時の処理を示します。

移動不可、あたり判定無効にしたいので死んではないけど死亡フラグをセットする
BGMの停止と効果音の再生
落下中のブロックに関する情報のクリア
ステージクリアを示す文字列の表示
次のステージのブロックの生成
プレイヤーの位置の初期化
停止していたBGMの再生

ステージクリアを示す文字列(DOM要素を使う)を下から上へ移動するように表示させます。

描画処理

描画処理を示します。

canvas全体を黒で塗りつぶす
ブロックを描画する
ゴールが見える位置にあるときは描画する
火花があるときは描画する
プレイヤーが生存するときは描画する
上部にスコア等を描画する