🎮 JavaScriptで作る「FPSゲーム」
ギターを持って一番はじめに弾くコードは「AM7」の大田です。
以前投稿した「JavaScriptで作る「15パズル」」に続き、JavaScriptで作るゲーム第2弾として作成したのがこの「FPSゲーム」です。
Q:なぜFPSゲームなのか?
最近「three.js」というJavaScriptのライブラリを勉強しており、試しになにか作りたいなと思ったのがきっかけです。
加えて、普段からゲームを全くしない自分にとって、FPSというジャンルは未知の世界だったため、まずはWASDの操作に慣れるための練習ゲームを作成することにしました。
Q:three.jsとは?
three.jsは、Webブラウザ上で3Dグラフィックスを表示するためのJavaScriptライブラリです。
WebGLを簡単に扱えるように抽象化されており、3Dモデルの表示、アニメーション、光源や影の表現などを手軽に実装できます。
👉 three.js 公式サイト
ゲーム概要
このゲームは、three.js を活用して開発されたブラウザ上で動作する 一人称視点(FPS)迷路探索ゲームです。
プレイヤーは3D空間内の迷路に配置され、視点移動・移動・ジャンプ・ダッシュ・しゃがみといった動作を駆使してゴールを目指します。
技術要件
- three.js・・・WebGLを抽象化し、3D描画全般を担当
- PointerLockControls・・・FPS視点のマウス制御機能
- HTML/CSS・・・UI構築(操作説明、ゴール表示、DASHボタン、マップ)
- JavaScript・・・ゲームロジック・迷路生成・プレイヤー操作・衝突判定
ルール
- スタート地点から出発し、ゴール地点(金色のキューブ)に到達するとゲームクリアとなります
- 迷路は毎回ランダムで生成されます
- PCでのみ起動します ※スマートフォンからは操作できません
実際に遊んでみる
- W / A / S / D:移動(前進 / 左移動 / 後退 / 右移動)
- マウス移動:視点の操作(上下左右)
- スペースキー:ジャンプ
- Ctrlキー:しゃがむ
- Shiftキー:ダッシュ
- Qキー:ミニマップ表示
ソースコード
開発のポイント
1. 迷路生成は「再帰的バックトラッキング法」で構築
function generateMaze(rows, cols) { ... }
- 壁をベースにして、再帰的に通路を掘り進めるアルゴリズム
- 通路は奇数のインデックスのみ、2マス飛ばしで掘ることで、正しい構造の迷路が完成
- 初期化・方向シャッフル・壁削りの処理が明快で、アルゴリズム学習にも最適
2. PointerLockControls による FPS 視点制御
controls = new THREE.PointerLockControls(camera, document.body);
- マウスカーソルを非表示にし、マウス移動だけで自然な視点回転を実現
- UI要素(クリックでロック開始)との連携もスムーズ
3. ダッシュ・しゃがみ・ジャンプを加えた移動処理
const speedFactor = isDashing ? dashMultiplier : 1;
const targetHeight = isCrouching ? crouchHeight : standingHeight;
- 通常速度に加え、ダッシュによる移動スピードの切替が可能
- カメラY座標を変更することで、しゃがみ状態の視点変化も表現
- canJump フラグにより、地面接地時のみジャンプ可能という自然な挙動を再現
4. 壁との衝突を回避する簡易コリジョン(当たり判定)
if (dx < threshold && dz < threshold) {
collided = true;}
- 各フレームでプレイヤーの位置と全壁の位置を比較
- XY軸での衝突範囲(閾値)を計算し、当たったら元の位置に戻して衝突を無効化
- 複雑な物理エンジンなしで、シンプルなロジックで衝突防止を実装
5. マップ機能をCanvasで別描画
mapCanvas.getContext('2d').fillRect(...);
- HTMLの canvas 要素を使い、迷路の縮小版と現在地・ゴール位置を描画
- ゲーム画面とは別にマップ情報を提供することで探索の視認性向上を実現
まとめ
three.jsは、普段の業務で直接使うことのない技術ですが、「おもしろそう」という純粋な興味から学び始め、自分の理解度を確かめるためにゲーム制作に挑戦しました。
日常業務と直結しない技術であっても、IT業界で働く以上、新しい技術を探求し続ける姿勢は不可欠だと考えています。
そのため、まずは「興味を持つこと」、そして「理解を形にすること」を意識しながら、今後も積極的に技術の幅を広げていきたいと思います。