以前、C# WindowsFormsで『スペースウォー!』(Spacewar!)をつくりました。今回はJavaScriptでつくります。

スペースウォー!は1962年、当時マサチューセッツ工科大学(MIT)の学生であったスティーブ・ラッセルを中心に、DEC社のミニコンPDP-1上で稼動するデモンストレーションプログラムとして開発されました。世界初のシューティングゲームとされています。

特徴として、方向転換しただけでは進行方向を変えることはできません。また中心には太陽があり、プレイヤーの移動に影響を与えます。近づきすぎると重力に引き込まれてミスとなります。操作が難しいゲームといえます。

HTML部分

style.css

使用する画像

グローバル変数と定数

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

playerOuterPointsとplayerInnerPointsは当たり判定のときに使用します。プレイヤーを原点が中心になるように配置したときの点の位置です。この黄色い点で構成される部分の内部に弾丸が入ったときは弾丸が命中したことになり、wedgeの青い点で構成される部分の内部にneedleの青い点が入ったときは両者が衝突したことになります。

index.js

Bulletクラスの定義

弾丸の状態を更新し描画するためにBulletクラスを定義します。

レーザーっぽく見せるために更新前の弾丸の座標を記憶しておき、これを利用してぼかしがついた直線を描画します。弾丸は自機と敵で色を変え、命中しなくてもLife回更新されたら消えてしまうようにします。

コンストラクタ

index.js

更新処理

更新の処理を示します。

更新ごとにLifeをデクリメントし、現在の座標をHistoryXYの先頭に追加し先頭の20個を取ります。これでレーザーが一定の長さを超えなくなります。canvasの外に出て行ったものやLifeが0になったオブジェクトには死亡フラグをセットします。

描画処理

描画の処理を示します。

現在の座標とHistoryXYの最後に格納されている座標を結ぶ直線を描画します。

Playerクラスの定義

自機と敵の状態を更新し描画するためみPlayerクラスを定義します。

Playerにはくさび形とニードル型の2つがあります。前者が自機、後者が敵機です。

コンストラクタと初期化

Init関数は次のゲームが開始されるまえにプレイヤーの状態を初期化するために呼び出されます。座標、方向、発射した弾丸、移動速度の初期化、死亡フラグのクリアをおこないます。

方向転換と加速

プレイヤーの速度と方向を取得する処理を示します。GetAngle関数は -πからπまでの値を返します。

プレイヤーの方向転換、加速時におこなわれる処理を示します。このゲームは方向転換しても加速しなければ進行方向はかわりません。

更新処理

更新処理を示します。

座標を速度分だけ変更し、canvas内から外に出た場合は反対側にワープさせます。そして弾丸についても更新処理をおこないます。そして死亡フラグがセットされた弾丸は配列のなかから取り除きます。

描画処理

描画処理を示します。

弾丸を描画したあと自分自身を描画します。

弾丸の発射

弾丸を発射する処理を示します。

弾丸を発射したら0.1秒間は発射できないようにして連射制限をかけます。また死亡時やゲーム開始前は発射できないようにします。発射時は自機の中心を弾丸の初期位置とし、発射方向は自機の向き、初速はBULLET_SPEEDだけでなく自機の速度を加算します。

Fireballクラスの定義

爆発の描画をするためにFireballクラスを定義します。

やっていることは 爆発のエフェクトをシミュレーションする とあまり変わりません。火球を大量生成するため、一度生成したイメージを再利用できるように配列のなかに格納しているのと、火球の色が複数ある点が異なるだけです。

爆発を発生させる処理を示します。