はじめに
ブラウザ上で、心地よい操作感とリッチな3D空間を楽しめるフライトアクションのプロトタイプ「High-Mobility Engine Demo (PDE)」を開発しました。
外部の画像ファイルや音声ファイルなどのアセットは一切読み込まず、Three.js と Vanilla JavaScript(1つのHTMLファイル) のみで構築しています。PCだけでなく、スマートフォンでの直感的なタッチ操作にも最適化しています。
👉 [実際に遊んでみる(公開URL)] (https://ksan260307.github.io/RandD/PDE%20Perceptual%20Dynamics%20Engine/src/High-Mobility%20Engine%20Demo/main.html)
主な機能とアクション体験
本デモでは、独自の物理ロジック「Perceptual Dynamics Engine (PDE)」による、爽快な高機動アクションを実装しています。
-
直感的なタッチ&スワイプ操作
画面ドラッグで機体を操作。ダブルタップで「ダッシュ」、左右の小刻みなスワイプで「バレルロール」が発動します。 -
U-TURN(緊急反転)と自動回避
背後へ瞬時に向きを変えるU-TURNアクションを搭載。さらに、障害物(小惑星)に正面衝突しそうになった際は、機体が自動で宙返りして回避するアシスト機能も組み込んでいます。 -
スマホ最適化とUI設計
パラメータをスライドさせるだけで直感的に設定できるカメラスライダー(Camera Sensitivity)や、プレイ状況を視覚化するHUDを実装。スマホでもPCでも誰にでも分かりやすい設計を目指しました。
技術スタック・実装の工夫点
「アセットレス(外部ファイルなし)」かつ「高パフォーマンス」を実現するため、コード内で完結するさまざまな工夫を取り入れています。
① プロシージャルテクスチャ(Canvas 2D APIの活用)
機体のサイバーな模様や、小惑星の岩肌感、パーティクルの発光表現などは、外部の画像ファイルを読み込むのではなく、すべてJavaScriptの CanvasRenderingContext2D を使って動的に描画し、THREE.CanvasTexture に変換して適用しています。
// プロシージャルなサイバーテクスチャの生成例(抜粋)
function createCyberTexture() {
const canvas = document.createElement('canvas');
canvas.width = 512; canvas.height = 512;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#05101a';
ctx.fillRect(0, 0, 512, 512);
ctx.strokeStyle = '#0066aa';
// グリッド線の描画
for (let i = 0; i <= 512; i += 32) {
ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, 512); ctx.stroke();
ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(512, i); ctx.stroke();
}
// ...ランダムな発光パターンの描画...
const texture = new THREE.CanvasTexture(canvas);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
return texture;
}
② BufferGeometryによる軽量パーティクルシステム
スラスターの軌跡や衝突時の火花を描画するために、独自のエフェクトマネージャー(ParticleSystem)を実装しています。
都度オブジェクトを生成・破棄するのではなく、Float32Array で座標(positions)と色(colors)のバッファを事前に確保し、それらを直接書き換えて THREE.Points を更新することで、ガベージコレクションの発生を抑え、数千個のパーティクルを処理してもカクつかないパフォーマンスを確保しています。
③ クォータニオンを用いた PDE (Perceptual Dynamics Engine)
機体の姿勢制御にはオイラー角を避け、すべてクォータニオン(THREE.Quaternion)を用いて計算しています。
特にU-TURNアクションでは、現在の進行方向から回転軸となる外積(Cross Product)を算出し、イージング関数を用いて滑らかに180度反転+ロール回転を組み合わせる複雑な遷移を数式ベースで構築しています。
// U-TURNアクションの姿勢計算(抜粋)
let easeProgress = progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2;
let currentAngle = easeProgress * Math.PI;
// ピッチ回転とロール回転を合成
let pitchQuat = new THREE.Quaternion().setFromAxisAngle(this.uTurnAxis, currentAngle);
let rollAngle = 0;
// ...後半でロール回転を付加...
let rollQuat = new THREE.Quaternion().setFromAxisAngle(forwardDir, rollAngle);
this.baseRotation.copy(this.uTurnStartQuat).multiply(pitchQuat).multiply(rollQuat);
④ 無限空間ループと衝突回避スリップ
宇宙空間の「果て」を感じさせないよう、自機から一定距離(SPAWN_RANGE)以上離れた小惑星や星屑(Starfield)の座標は、反対側にワープさせるループ処理を実装しています。
また、小惑星への衝突判定では、単にぶつかって止まるのではなく、「力場」のような反発力を計算して機体を滑らせる(Slip)軌道修正ロジックを組むことで、アクションゲームとしてのストレスを軽減しています。
おわりに
Three.jsの強力なレンダリング機能と、素のJavaScriptによる物理ロジック計算を組み合わせることで、ブラウザ単体でもここまで表現できるというR&D(研究開発)の成果です。
URLからPCでもスマホでもすぐに遊べますので、ぜひ高機動アクションの気持ちよさを体験してみてください!
