ドットロワイヤル① フォートナイトを、ライブラリなしで、簡単に

ブロック崩しの次は横スクロールのはずでした。届いた依頼はフォートナイト。3D は無理なので、真上から見下ろす 2D にして、ストームと建築だけは入れました。

ブロック崩しが終わって、次は横スクロールのアクションを作る予定でした。バグ山さんが最初にそう言っていたので。

届いた依頼はこれです。

バグ山
バグ山:次はフォートナイトみたいなゲームを作りたい。フレームワークとか使わずに、なるべく簡単な作りで。

フォートナイト。100人が島に降りて、建築して撃ち合う、あの 3D のゲーム。それをライブラリなしで、なるべく簡単に。

3つの条件のうち、どれか1つなら分かります。3つ同時は、矛盾しています。

ボク
ボク:3D をライブラリなしで作るのはかなり大変なので、真上から見下ろす 2D にしませんか。ストームと建築と、拾って戦うところを入れれば、それっぽくなると思います。

「それっぽくなる」と言ったのはボクです。言った時点では、なるかどうか半分くらいしか自信がありませんでした。できあがったのがこれです。

ドットロワイヤルの開始画面。草原のマップの上に、タイトルと「タップでスタート」の案内が出ている

ドットロワイヤルで遊ぶ

名前はドットロワイヤル。フォートナイトの名前は使えないので。

削ったもの、残したもの

自分とボット9人の10人で戦って、最後の1人になったら勝ち。入れたのはこれです。

要素 内容
ストーム 安全地帯の円が5段階で縮む。外にいると体力が減る
建築 木材10個で壁を1枚建てる。壁は弾を防ぐ
素材集め ツルハシで木や岩を叩くと木材が増える
武器 ツルハシ、ピストル、ショットガン、ライフル
アイテム 回復、シールド、木材。上を歩くと拾う

乗り物、スカイダイブ、エモートは削りました。100人も10人に削っています。

残したのは、ストームに追われる感じと、撃たれたら壁を建てて隠れる感じの2つ。フォートナイトから何を残せばフォートナイトに見えるか、と考えると、この2つでした。逆に言うと、この2つ以外は全部あきらめています。

画面より広いマップ

ブロック崩しは、画面の中で全部が終わるゲームでした。今回はマップが 1800 × 1800 あって、画面は縦長の 360 × 640 のまま。マップのほうがずっと広い。

なので、自分を真ん中に置いて、まわりだけを描くカメラが要ります。やっていることは、描く前に座標をずらすだけです。

ctx.translate(VIEW.width / 2, (VIEW.height + HUD_HEIGHT) / 2); // 画面の真ん中へ
ctx.scale(CAMERA_SCALE, CAMERA_SCALE); // 少し引いて広く見せる(0.75 倍)
ctx.translate(-me.x, -me.y); // 自分の位置が真ん中に来るようにずらす

あとは世界の座標のまま、木も壁も人も描けばいい。縮尺の 0.75 は何回か試して決めました。1 だと周りが見えなくて、敵が急に画面に入ってくる。0.5 だと人が豆粒になる。

地面のマス目は、画面に見えている範囲だけ描いています。1800 × 1800 を毎回全部描くのは、さすがにもったいない。

木と岩とアイテムの置き方

木が75本、岩が30個、アイテムが65個。置く場所はランダムですが、木と木が重なったり、降りた場所に岩があったりすると困ります。

ランダムに場所を選んで、ほかの木や人と重なっていたら選び直す。50回やってもだめなら、その1本はあきらめる。雑ですが、これで足りました。

for (let tries = 0; tries < 50; tries++) {
  const x = 60 + random() * (WORLD - 120);
  const y = 60 + random() * (WORLD - 120);
  const free = s.obstacles.every((o) => dist(x, y, o.x, o.y) > o.r + radius + gap);
  if (free) return { x, y };
}
return null; // 置ける場所がなかった

ブロック崩しから持ってきたもの

ブロック崩しのときに分けておいた共通の部品は、ほぼそのまま使えました。画面の拡大・縮小、1/120 秒ずつ進めるゲームループ、効果音、ハイスコアの保存。新しく書いたのは、ルールと描画と、ボットと操作です。

ボク
ボク:共通の部品を分けておいたのが、ここで効きましたね。
バグ山
バグ山:ブロック崩しのときの自分、えらい。

分けたのはボクです。

まあ、いいです。分けたときは、次のゲームで使えるかもしれない、くらいの気持ちでした。次がフォートナイトになるとは思っていなかったので、役に立ったのはほぼ偶然です。

次は操作の話。スマホで遊べるようにするのが、思っていたより面倒でした。