現在、WebGLを使用して、ブラウザーで3D一人称シューティングゲームを作成しています。そのようなゲームにマウスルック/フリールックを実装するにはどうすればよいですか?
現在、WebGLを使用して、ブラウザーで3D一人称シューティングゲームを作成しています。そのようなゲームにマウスルック/フリールックを実装するにはどうすればよいですか?
回答:
Mouselookは、W3C ポインターロック仕様を介してChromeとFirefoxでサポートされるようになりました。基本的に:
document.onmousemove = function (e) {
document.body.innerHTML = "<div>dx: " +
(e.movementX || e.mozMovementX || e.webkitMovementX || 0);
}
document.body.onclick = document.body.requestPointerLock ||
document.body.mozRequestPointerLock ||
document.body.webkitRequestPointerLock;
優れたチュートリアル記事は、HTML5RocksのPointer LockおよびFirst Person Shooter Controlsです。
mousemove
イベントをキャプチャし、イベントオブジェクトのscreenX
およびscreenY
プロパティを使用してカメラの位置を更新します(最後までのデルタscreenX
とscreenY
位置を使用して、移動量を取得します)。
何らかのシーングラフがある場合は、次のようなノード設定を作成できます。
CameraNode (Scene Node)
|
+- YawNode (Scene Node)
|
+- PitchNode (Scene Node)
|
+- Camera (actual Camera Object)
X軸の動きはYawNodeを回転させ、Y軸の動きはPitchNodeを回転させます。プレーヤーが移動すると、CameraNodeも移動します。
これは非常に単純で、2つのことを実行するだけです。
以下は、イベント処理を行うためのサンプルソースコードです。システムモジュール(すべてのゲーム<->ブラウザインタラクションを処理する)は、2つの変数を追跡します:lastMousePosition
およびlastMouseDelta
。
マウスでカメラを追跡するには、lastMouseDelta
フレーム間で回転する角度を知る方法が必要です。
var canvas = /* WebGL rendering context */
canvas.onmousedown = function (event) { me.handleMouseDown(event); };
canvas.onmouseup = function (event) { me.handleMouseUp(event); };
canvas.onmousemove = function (event) { me.handleMouseMove(event); };
// snip
engine.SystemModule.prototype.handleMouseMove = function(event) {
this.lastMouseDelta = [event.clientX - this.lastMousePosition[0],
event.clientY - this.lastMousePosition[1]];
this.lastMousePosition = [event.clientX, event.clientY];
};
以下は、カメラの回転を処理するためのサンプルコードです。マウスがXまたはY方向に移動したピクセル数を指定して、カメラをその度数だけ回転させます。
/**
* degrees/pixel
* @const
*/
var cameraMouseRotation = 0.5;
// Mouse movement for camera angle.
if (sys.isMouseDown()) {
var positionChange = sys.getLastMousePositionDelta();
camera.rotateYDegs(cameraMouseRotation * positionChange[0]);
camera.rotateXDegs(-cameraMouseRotation * positionChange[1]);
}
その後、実際に世界をレンダリングするときに、カメラからモデルビューマトリックスを生成するだけです。(カメラの位置、ヨー、ピッチ、ロールをベクトルに変換して、gluLookAtに渡すことができます。)そして、これで問題ありません。