Attualmente sto creando un gioco sparatutto in prima persona 3D nel browser usando WebGL. Come implementerei mouselook / free look per un gioco del genere?
Attualmente sto creando un gioco sparatutto in prima persona 3D nel browser usando WebGL. Come implementerei mouselook / free look per un gioco del genere?
Risposte:
Mouselook è ora supportato in Chrome e Firefox tramite la specifica W3C Pointer Lock . Essenzialmente:
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;
Un buon articolo tutorial è Pointer Lock e controlli sparatutto in prima persona su HTML5Rocks.
Cattura mousemoveeventi e usa le proprietà screenXe screenYdell'oggetto evento per aggiornare la posizione della telecamera (usa il delta all'ultima screenXe la screenYposizione per ottenere la quantità di movimento).
Se hai una sorta di scenegraph , potresti costruire una configurazione del nodo come la seguente:
CameraNode (Scene Node)
|
+- YawNode (Scene Node)
|
+- PitchNode (Scene Node)
|
+- Camera (actual Camera Object)
Il movimento nell'asse X ruota il nodo Yaw e il movimento nell'asse Y ruota il nodo Pitch. Il CameraNode verrà spostato quando il giocatore si sposta.
È abbastanza semplice e richiede solo due cose.
Ecco un po 'di codice sorgente di esempio per eseguire la gestione degli eventi. Il modulo di sistema (che gestisce tutte le interazioni del browser <--> di gioco) tiene traccia di due variabili: lastMousePositione lastMouseDelta.
Per tenere traccia della fotocamera con il mouse, è sufficiente lastMouseDeltasapere qual è il grado di rotazione da un fotogramma all'altro.
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];
};
Ecco alcuni esempi di codice per gestire la rotazione della videocamera. Dato il numero di pixel che il mouse ha spostato nella direzione X o Y, ruotare la videocamera di quel grado.
/**
* 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]);
}
Più tardi, quando si esegue il rendering del mondo, è sufficiente generare una matrice di visualizzazione del modello dalla fotocamera. (Convertendo posizione, imbardata, inclinazione e rollio della videocamera in vettori, puoi passare a gluLookAt.) E dovresti essere bravo ad andare.