three.js (WebGL) で TPS / FPS ゲームエンジン
去年 (2014 年) は three.js (WebGL) で TPS ゲームエンジンのような JS ライブラリーを作っていました。
ライブラリーの名前は未だに迷っているので名前空間ごと変えるかもしれませんが、今のところ用意している機能として:
- height field (高さマップ)、つまり、凸凹の地形を歩ける機能
- three.js のメッシュを剛体( height field も含む) に変換する機能
- プレイヤー 対 壁や天井との衝突
- 「崖」に接地している場合は滑り落ちる機能
- どれくらい急な斜面を「崖」として扱うか
- ジャンプと着地
- 基本的なキーボード (WASD、矢印キー、Spaceキー) 入力
- TPS カメラ (プレイヤーとの距離を 0 に近づけると FPS になる)
- TPS カメラと壁との衝突 (カメラが壁の中にめり込まない)
などがあります。
上記のそれぞれの機能については、リポジトリーの readme 内のリンクから実際に動かして試すことができます。
プレイヤーと剛体との衝突は、物理演算エンジンを使わずに独自に用意しています。なので必要以上のことはしていません。例えば、物理演算エンジンを利用する際の基礎となる重力や重さ、摩擦などの概念はこのライブラリーには今のところ存在しません。かわりに移動速度、ジャンプ力、降下速度などが存在します。
物理演算エンジンのようなリアルさがないので「凸凹の地形を歩ける機能」が実現できます。
例えば、リアルな物理演算エンジンでは、ゆるやかな上り坂であったとしても、それを登った後は慣性で飛んでしまいます。
しかし、ゲームでは、ゆるやかな坂であっても通常の地面のように歩きたいでしょうし、このライブラリーでも慣性を無視できるように実装しています。
「カメラが壁の中にめり込まない」機能は、例えば普通に 3D でカメラを配置すると、壁の中にカメラがめり込んでしまったり、そうでない場合でも、near より手前が表示されません。そうした場合、自動でカメラを手前に引くようにしています。
three.js をある程度扱える知識があれば、扱える程度の API で構成されていますので、使いやすいかなと思います。使い方について、詳しくはリポジトリ内の readme の Usage and Learning からのリンク先を見ればわかるようにしていますが、簡単な流れとしては以下の 4 ステップです。
- world を作る
- octree を world の中に手動で作る。(octree は衝突判定の絞り込みのために使います)
- octree は直方体で、2つの角と分割数を指定する
- 2つの角の座標の範囲内にこれから作る地形や障害物が収まるようにする
- three.js で用意した地形や障害物のメッシュを octree に突っ込む
- プレイヤーを world に投入する
また、もし、いい追加機能やアイディアがありましたらプルリクエストをいただけると嬉しいです。ゲームエンジンについての知識はなく、普段プレイしているゲームの挙動から想像してコードを書いただけですので…。