mirror of
https://github.com/photonstorm/phaser
synced 2024-11-24 05:33:35 +00:00
Improved pointer lock api
Some improvements over v2: - You can access movementXY on pointer without needing to perform a manual `resetMovement()` - Fixes bug where `releasePointerLock` would unregister event listeners before a final `pointerLockChange` could be called. Results in mouse.locked not having the right state and a final 'POINTER_LOCK_CHANGE_EVENT' not firing.
This commit is contained in:
parent
b5e8a60530
commit
d563cabadd
5 changed files with 117 additions and 1 deletions
|
@ -65,6 +65,18 @@ var Pointer = new Class({
|
|||
this.justDown = false;
|
||||
this.justUp = false;
|
||||
this.justMoved = false;
|
||||
|
||||
/**
|
||||
* @property {number} movementX - If the mouse is locked, the horizontal relative movement
|
||||
* of the Pointer in pixels since last frame.
|
||||
*/
|
||||
this.movementX = 0;
|
||||
|
||||
/**
|
||||
* @property {number} movementY - If the mouse is locked, the vertical relative movement of
|
||||
* the Pointer in pixels since last frame.
|
||||
*/
|
||||
this.movementY = 0;
|
||||
},
|
||||
|
||||
positionToCamera: function (camera, output)
|
||||
|
@ -109,6 +121,8 @@ var Pointer = new Class({
|
|||
this.justDown = false;
|
||||
this.justUp = false;
|
||||
this.justMoved = false;
|
||||
this.movementX = 0;
|
||||
this.movementY = 0;
|
||||
},
|
||||
|
||||
touchmove: function (event, time)
|
||||
|
@ -135,6 +149,13 @@ var Pointer = new Class({
|
|||
this.x = this.manager.transformX(event.pageX);
|
||||
this.y = this.manager.transformY(event.pageY);
|
||||
|
||||
if (this.manager.mouse.locked)
|
||||
{
|
||||
// Potentially multiple DOM events within one frame, but only one Phaser event will fire
|
||||
this.movementX += event.movementX || event.mozMovementX || event.webkitMovementX || 0;
|
||||
this.movementY += event.movementY || event.mozMovementY || event.webkitMovementY || 0;
|
||||
}
|
||||
|
||||
this.justMoved = true;
|
||||
|
||||
this.dirty = true;
|
||||
|
|
|
@ -113,6 +113,11 @@ var GlobalInputManager = new Class({
|
|||
this.events.dispatch(new MouseEvent.UP(event));
|
||||
break;
|
||||
|
||||
case 'pointerlockchange':
|
||||
|
||||
this.events.dispatch(new MouseEvent.POINTER_LOCK_CHANGE(event, this.mouse.locked));
|
||||
break;
|
||||
|
||||
case 'touchmove':
|
||||
|
||||
pointer.touchmove(event, time);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
var Class = require('../../utils/Class');
|
||||
var Features = require('../../device/Features');
|
||||
var MouseEvents = require('./events');
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
||||
// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
|
||||
|
@ -19,6 +21,12 @@ var MouseManager = new Class({
|
|||
this.target;
|
||||
|
||||
this.handler;
|
||||
|
||||
/**
|
||||
* @property {boolean} locked - If the mouse has been pointer locked successfully this will
|
||||
* be set to true.
|
||||
*/
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
boot: function ()
|
||||
|
@ -55,6 +63,52 @@ var MouseManager = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* If the browser supports it, you can request that the pointer be locked to the browser window.
|
||||
* This is classically known as 'FPS controls', where the pointer can't leave the browser until
|
||||
* the user presses an exit key. If the browser successfully enters a locked state, a
|
||||
* 'POINTER_LOCK_CHANGE_EVENT' will be dispatched - from the game's input manager - with an
|
||||
* `isPointerLocked` property.
|
||||
* It is important to note that pointer lock can only be enabled after an 'engagement gesture',
|
||||
* see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture.
|
||||
*/
|
||||
requestPointerLock: function ()
|
||||
{
|
||||
if (Features.pointerLock)
|
||||
{
|
||||
var element = this.target;
|
||||
element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
|
||||
element.requestPointerLock();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal pointerLockChange handler.
|
||||
*
|
||||
* @param {Event} event - The native event from the browser.
|
||||
*/
|
||||
pointerLockChange: function (event)
|
||||
{
|
||||
var element = this.target;
|
||||
this.locked = document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element
|
||||
? true : false;
|
||||
this.manager.queue.push(event);
|
||||
},
|
||||
|
||||
/**
|
||||
* If the browser supports pointer lock, this will request that the pointer lock is released. If
|
||||
* the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be
|
||||
* dispatched - from the game's input manager - with an `isPointerLocked` property.
|
||||
*/
|
||||
releasePointerLock: function ()
|
||||
{
|
||||
if (Features.pointerLock)
|
||||
{
|
||||
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock;
|
||||
document.exitPointerLock();
|
||||
}
|
||||
},
|
||||
|
||||
startListeners: function ()
|
||||
{
|
||||
var queue = this.manager.queue;
|
||||
|
@ -82,6 +136,14 @@ var MouseManager = new Class({
|
|||
this.target.addEventListener('mousemove', handler, false);
|
||||
this.target.addEventListener('mousedown', handler, false);
|
||||
this.target.addEventListener('mouseup', handler, false);
|
||||
|
||||
if (Features.pointerLock)
|
||||
{
|
||||
this.pointerLockChange = this.pointerLockChange.bind(this);
|
||||
document.addEventListener('pointerlockchange', this.pointerLockChange, true);
|
||||
document.addEventListener('mozpointerlockchange', this.pointerLockChange, true);
|
||||
document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true);
|
||||
}
|
||||
},
|
||||
|
||||
stopListeners: function ()
|
||||
|
@ -89,6 +151,13 @@ var MouseManager = new Class({
|
|||
this.target.removeEventListener('mousemove', this.handler);
|
||||
this.target.removeEventListener('mousedown', this.handler);
|
||||
this.target.removeEventListener('mouseup', this.handler);
|
||||
|
||||
if (Features.pointerLock)
|
||||
{
|
||||
document.removeEventListener('pointerlockchange', this.pointerLockChange, true);
|
||||
document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true);
|
||||
document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
20
v3/src/input/mouse/events/PointerLockChangeEvent.js
Normal file
20
v3/src/input/mouse/events/PointerLockChangeEvent.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
var Class = require('../../../utils/Class');
|
||||
var Event = require('../../../events/Event');
|
||||
|
||||
var PointerLockChangeEvent = new Class({
|
||||
|
||||
Extends: Event,
|
||||
|
||||
initialize:
|
||||
|
||||
function PointerLockChangeEvent (nativeEvent, isPointerLocked)
|
||||
{
|
||||
Event.call(this, 'POINTER_LOCK_CHANGE_EVENT');
|
||||
|
||||
this.data = nativeEvent;
|
||||
this.isPointerLocked = isPointerLocked;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = PointerLockChangeEvent;
|
|
@ -3,5 +3,6 @@
|
|||
module.exports = {
|
||||
DOWN: require('./MouseDownEvent'),
|
||||
UP: require('./MouseUpEvent'),
|
||||
MOVE: require('./MouseMoveEvent')
|
||||
MOVE: require('./MouseMoveEvent'),
|
||||
POINTER_LOCK_CHANGE: require('./PointerLockChangeEvent')
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue