The Input system will now order input based on the scenes from top to bottom

If the global top only flag is on and a scene consumes an input event then they won't flow any further down the scene list. This is optional (but on by default), allowing you to now correctly create a UI Scene above a game scene without the input events polluting one to the other.
This commit is contained in:
Richard Davey 2018-01-20 04:44:54 +00:00
parent 864fa638af
commit 4e05ad0655
2 changed files with 63 additions and 7 deletions

View file

@ -38,9 +38,16 @@ var InputManager = new Class({
this.scale = { x: 1, y: 1 }; this.scale = { x: 1, y: 1 };
// If the top-most Scene in the Scene List receives an input it will stop input from
// propagating any lower down the scene list, i.e. if you have a UI Scene at the top
// and click something on it, that click will not then be passed down to any other
// Scene below. Disable this to have input events passed through all Scenes, all the time.
this.globalTopOnly = true;
this.ignoreEvents = false;
this.bounds; this.bounds;
// this._tempMatrix = new TransformMatrix();
this._tempPoint = { x: 0, y: 0 }; this._tempPoint = { x: 0, y: 0 };
this._tempHitTest = []; this._tempHitTest = [];
@ -85,6 +92,8 @@ var InputManager = new Class({
this.keyboard.update(); this.keyboard.update();
this.gamepad.update(); this.gamepad.update();
this.ignoreEvents = false;
var len = this.queue.length; var len = this.queue.length;
// Currently just 1 pointer supported // Currently just 1 pointer supported

View file

@ -210,6 +210,8 @@ var InputPlugin = new Class({
// Contains ALL Game Objects currently over in the array // Contains ALL Game Objects currently over in the array
this.emit('pointerdown', pointer, currentlyOver); this.emit('pointerdown', pointer, currentlyOver);
var total = 0;
// Go through all objects the pointer was over and fire their events / callbacks // Go through all objects the pointer was over and fire their events / callbacks
for (var i = 0; i < currentlyOver.length; i++) for (var i = 0; i < currentlyOver.length; i++)
{ {
@ -220,10 +222,14 @@ var InputPlugin = new Class({
continue; continue;
} }
total++;
gameObject.emit('pointerdown', pointer, gameObject.input.localX, gameObject.input.localY, pointer.camera); gameObject.emit('pointerdown', pointer, gameObject.input.localX, gameObject.input.localY, pointer.camera);
this.emit('gameobjectdown', pointer, gameObject); this.emit('gameobjectdown', pointer, gameObject);
} }
return total;
}, },
processDragEvents: function (pointer, time) processDragEvents: function (pointer, time)
@ -231,7 +237,7 @@ var InputPlugin = new Class({
if (this._draggable.length === 0) if (this._draggable.length === 0)
{ {
// There are no draggable items, so let's not even bother going further // There are no draggable items, so let's not even bother going further
return; return 0;
} }
var i; var i;
@ -481,6 +487,8 @@ var InputPlugin = new Class({
pointer.dragState = 0; pointer.dragState = 0;
} }
return (pointer.dragState > 0);
}, },
processMoveEvents: function (pointer) processMoveEvents: function (pointer)
@ -489,6 +497,8 @@ var InputPlugin = new Class({
this.emit('pointermove', pointer, currentlyOver); this.emit('pointermove', pointer, currentlyOver);
var total = 0;
// Go through all objects the pointer was over and fire their events / callbacks // Go through all objects the pointer was over and fire their events / callbacks
for (var i = 0; i < currentlyOver.length; i++) for (var i = 0; i < currentlyOver.length; i++)
{ {
@ -499,6 +509,8 @@ var InputPlugin = new Class({
continue; continue;
} }
total++;
gameObject.emit('pointermove', pointer, gameObject.input.localX, gameObject.input.localY); gameObject.emit('pointermove', pointer, gameObject.input.localX, gameObject.input.localY);
this.emit('gameobjectmove', pointer, gameObject); this.emit('gameobjectmove', pointer, gameObject);
@ -508,6 +520,8 @@ var InputPlugin = new Class({
break; break;
} }
} }
return total;
}, },
processOverOutEvents: function (pointer) processOverOutEvents: function (pointer)
@ -611,6 +625,8 @@ var InputPlugin = new Class({
// Then sort it into display list order // Then sort it into display list order
this._over[pointer.id] = this.sortGameObjects(previouslyOver); this._over[pointer.id] = this.sortGameObjects(previouslyOver);
return previouslyOver.length;
}, },
processUpEvents: function (pointer) processUpEvents: function (pointer)
@ -808,6 +824,13 @@ var InputPlugin = new Class({
return this; return this;
}, },
setGlobalTopOnly: function (value)
{
this.manager.globalTopOnly = value;
return this;
},
setTopOnly: function (value) setTopOnly: function (value)
{ {
this.topOnly = value; this.topOnly = value;
@ -887,9 +910,27 @@ var InputPlugin = new Class({
return interactiveObjects.sort(this.sortHandlerIO.bind(this)); return interactiveObjects.sort(this.sortHandlerIO.bind(this));
}, },
stopPropagation: function ()
{
if (this.manager.globalTopOnly)
{
this.manager.ignoreEvents = true;
}
return this;
},
update: function (time, delta) update: function (time, delta)
{ {
var pointer = this.manager.activePointer; var manager = this.manager;
// Another Scene above this one has already consumed the input events
if (manager.globalTopOnly && manager.ignoreEvents)
{
return;
}
var pointer = manager.activePointer;
var runUpdate = (pointer.dirty || this.pollRate === 0); var runUpdate = (pointer.dirty || this.pollRate === 0);
@ -921,16 +962,16 @@ var InputPlugin = new Class({
this._temp.splice(1); this._temp.splice(1);
} }
this.processDragEvents(pointer, time); var total = this.processDragEvents(pointer, time);
if (!pointer.wasTouch) if (!pointer.wasTouch)
{ {
this.processOverOutEvents(pointer); total += this.processOverOutEvents(pointer);
} }
if (pointer.justDown) if (pointer.justDown)
{ {
this.processDownEvents(pointer); total += this.processDownEvents(pointer);
} }
if (pointer.justUp) if (pointer.justUp)
@ -940,7 +981,13 @@ var InputPlugin = new Class({
if (pointer.justMoved) if (pointer.justMoved)
{ {
this.processMoveEvents(pointer); total += this.processMoveEvents(pointer);
}
if (total > 0 && manager.globalTopOnly)
{
// We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame
manager.ignoreEvents = true;
} }
}, },