mirror of
https://github.com/photonstorm/phaser
synced 2024-11-27 23:20:59 +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.justDown = false;
|
||||||
this.justUp = false;
|
this.justUp = false;
|
||||||
this.justMoved = 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)
|
positionToCamera: function (camera, output)
|
||||||
|
@ -109,6 +121,8 @@ var Pointer = new Class({
|
||||||
this.justDown = false;
|
this.justDown = false;
|
||||||
this.justUp = false;
|
this.justUp = false;
|
||||||
this.justMoved = false;
|
this.justMoved = false;
|
||||||
|
this.movementX = 0;
|
||||||
|
this.movementY = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
touchmove: function (event, time)
|
touchmove: function (event, time)
|
||||||
|
@ -135,6 +149,13 @@ var Pointer = new Class({
|
||||||
this.x = this.manager.transformX(event.pageX);
|
this.x = this.manager.transformX(event.pageX);
|
||||||
this.y = this.manager.transformY(event.pageY);
|
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.justMoved = true;
|
||||||
|
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
|
|
|
@ -113,6 +113,11 @@ var GlobalInputManager = new Class({
|
||||||
this.events.dispatch(new MouseEvent.UP(event));
|
this.events.dispatch(new MouseEvent.UP(event));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'pointerlockchange':
|
||||||
|
|
||||||
|
this.events.dispatch(new MouseEvent.POINTER_LOCK_CHANGE(event, this.mouse.locked));
|
||||||
|
break;
|
||||||
|
|
||||||
case 'touchmove':
|
case 'touchmove':
|
||||||
|
|
||||||
pointer.touchmove(event, time);
|
pointer.touchmove(event, time);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
var Class = require('../../utils/Class');
|
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://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
||||||
// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
|
// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
|
||||||
|
@ -19,6 +21,12 @@ var MouseManager = new Class({
|
||||||
this.target;
|
this.target;
|
||||||
|
|
||||||
this.handler;
|
this.handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {boolean} locked - If the mouse has been pointer locked successfully this will
|
||||||
|
* be set to true.
|
||||||
|
*/
|
||||||
|
this.locked = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
boot: function ()
|
boot: function ()
|
||||||
|
@ -55,6 +63,52 @@ var MouseManager = new Class({
|
||||||
return this;
|
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 ()
|
startListeners: function ()
|
||||||
{
|
{
|
||||||
var queue = this.manager.queue;
|
var queue = this.manager.queue;
|
||||||
|
@ -82,6 +136,14 @@ var MouseManager = new Class({
|
||||||
this.target.addEventListener('mousemove', handler, false);
|
this.target.addEventListener('mousemove', handler, false);
|
||||||
this.target.addEventListener('mousedown', handler, false);
|
this.target.addEventListener('mousedown', handler, false);
|
||||||
this.target.addEventListener('mouseup', 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 ()
|
stopListeners: function ()
|
||||||
|
@ -89,6 +151,13 @@ var MouseManager = new Class({
|
||||||
this.target.removeEventListener('mousemove', this.handler);
|
this.target.removeEventListener('mousemove', this.handler);
|
||||||
this.target.removeEventListener('mousedown', this.handler);
|
this.target.removeEventListener('mousedown', this.handler);
|
||||||
this.target.removeEventListener('mouseup', 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 = {
|
module.exports = {
|
||||||
DOWN: require('./MouseDownEvent'),
|
DOWN: require('./MouseDownEvent'),
|
||||||
UP: require('./MouseUpEvent'),
|
UP: require('./MouseUpEvent'),
|
||||||
MOVE: require('./MouseMoveEvent')
|
MOVE: require('./MouseMoveEvent'),
|
||||||
|
POINTER_LOCK_CHANGE: require('./PointerLockChangeEvent')
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue