今回はJavaScriptでミスタードリラーもどきを作ります。

もともとのミスタードリラーとは?

『ミスタードリラー』 (Mr. Driller) は、ナムコ(現バンダイナムコエンターテインメント)が開発・発売したアクションパズルゲームです。

主人公のホリ・ススムを操り、色分けされたブロックで構成された地面をひたすら掘っていき、地下のゴールを目指します。主人公がブロックで押し潰されるとミスになります。

空中であっても落下中のブロックは停止している同色のブロックが隣にあるとこれとくっついて停止します。4個以上くっつくと消滅します。またブロックが消滅することでその上にある他色のブロックの落下が開始されることがあります。パズル的要素があるゲームです。

エア(酸素)という時間制限があり、時間の経過とともにエアの量が減っていきます。酸欠でミスになることを回避するために途中に存在するエアカプセルを取ってエアの補給をしなければならないのですが、ブロックの中には壊してしまうとエアが急激に減少してしまう×ブロックが存在し、これがエアカプセルの四方全てを囲んでいることが多いです。

HTML部分

それではさっそく作っていきましょう。

最初にHTMLとCSSを示します。スマホで操作するためのボタンも表示させますが、これはPCのようにディスプレイの幅が広い時は表示させません(後述)。

style.css

グローバル変数と定数

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

Blockクラスの定義

ブロックを操作できるようにするためにBlockクラスを定義します。

colにBLOCK_SIZEを掛けた値がブロックを描画するときのX座標、rowにBLOCK_SIZEを掛けてスクロール量を引いた値がブロックを描画するときのY座標となります。

ブロックのタイプはオブジェクトの生成時にランダムに決めます。通常のブロック(タイプ番号が 2以上のもの)は4種類なので 2 ~ 5の整数をランダムに割り振り、0と1のものは座標が決まってからあとで再設定します。

タイプ0は破壊するとエアが激減するブロック、1はエアを回復するアイテム、それ以外は普通のブロックです。エアを回復するアイテム(イメージが卵のもの)はブロックと落下時の挙動が違うのですが、ブロックの一種として扱います。

プレイヤーの移動先にあるブロックは原則すぐに破壊できるのですが、破壊するとエアが激減するブロックだけは5回叩かないと破壊できない仕様にしています(原作と合わせている)。

FallingGroupクラスの定義

同時に落下するブロックをまとめて操作できるようにFallingGroupクラスを定義します。

エアカプセル以外のブロックは落下可能状態になってからしばらくしてから落下を開始します。エアカプセルは落下可能状態になったらただちに落下します。

落下処理は1段分落下させたあともう一度落下可能かの判定をするのですが、引き続き落下させる場合は待機することなくすぐに落下処理を繰り返します。

こうなると落下しているブロックが下にある落下待機中のブロックを追い抜いてしまう問題が発生します。そこで同一落下グループに属さない他のブロックが直下に存在するかを調べて追い越し禁止の処理をしています。

コンストラクタ

コンストラクタを示します。

下のブロックを追い抜かないようにする

追い越し禁止の処理で必要となる同一落下グループに属さない直下に存在するブロックを取得する処理を示します。ここでは各ブロックの下にあるブロックを取得して、これがコンストラクタ内でSetに追加したブロックとは異なるものかどうかで判定しています。

落下処理

グループに属するブロックを落下させる処理を示します。

追い越しがおきる場合はなにもしません。それ以外の場合はグループに属するブロックのY座標を増加させます。

FallDistance が BLOCK_SIZE 以上になったら落下処理が完了したことになります。この場合は落下状態、落下待機状態のフラグをクリアし、Block.Rowを1増やします。そしてブロックオブジェクトは二次元配列 blocks2x2 のどこかの要素に格納されているのですが、その位置を変更します。

blocks2x2[oldRow][block.Col]をblocks2x2[oldRow + 1][block.Col]に代入してblocks2x2[oldRow][block.Col]にnullを代入するという処理をしていますが、コンストラクタ内で最初にBlock.Rowを大きい順にソートしているので前から順に処理をして問題ありません。

Playerクラスの定義

プレイヤーを操作できるようにするためにPlayerクラスを定義します。

XY座標がBLOCK_SIZEの倍数であるときだけユーザーは移動処理を開始できます。それ以外のときは次の倍数まで自動で移動処理を継続します。

また連続でバック(上への移動)できる回数に制限をかけます(2回まで)。この制限は下に移動することでリセットされます。

コンストラクタ

コンストラクタを示します。

初期化

ゲーム開始時やプレイヤー死亡状態から復活したときに状態を初期化する処理を示します。

更新処理

更新処理を示します。

Directに空文字以外がセットされているときはその方向に座標を移動させます。そして移動先の座標に到達したらDirectに空文字をセットしてそれ以上動かないようにします(移動ボタンが押しっぱなしの場合はすぐにDirectに移動方向の文字列がセットされるが・・・)。

描画

描画処理を示します。死亡時以外はプレイヤーを描画します。

Sparkクラスの定義

爆発で発生した火花を操作するためにSparkクラスを定義します。

コンストラクタ

コンストラクタの引数は火花が発生した座標と火花の移動速度です。

移動

火花を移動させる処理を示します。移動回数によって描画で使用するイメージを変更します。使用できるイメージがなくなったらその火花は消滅します。

描画

描画処理を示します。

すでに寿命を終えた火花と描画範囲がcanvasの範囲外のものは描画の処理をしません。描画するときはImageIndexから描画で使用するイメージを取得して描画処理をおこないます。

使用するクラスの定義が完了したので次回はこれを使ってゲームを完成させます。