2018-02-12 16:01:20 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
2019-01-15 16:20:22 +00:00
|
|
|
* @copyright 2019 Photon Storm Ltd.
|
2018-02-12 16:01:20 +00:00
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
2018-01-16 16:14:21 +00:00
|
|
|
var Circle = require('../geom/circle/Circle');
|
|
|
|
var CircleContains = require('../geom/circle/Contains');
|
2018-01-26 06:55:15 +00:00
|
|
|
var Class = require('../utils/Class');
|
2018-06-08 14:16:35 +00:00
|
|
|
var CreateInteractiveObject = require('./CreateInteractiveObject');
|
2018-06-08 16:50:47 +00:00
|
|
|
var CreatePixelPerfectHandler = require('./CreatePixelPerfectHandler');
|
2018-01-26 06:55:15 +00:00
|
|
|
var DistanceBetween = require('../math/distance/DistanceBetween');
|
2018-01-16 16:14:21 +00:00
|
|
|
var Ellipse = require('../geom/ellipse/Ellipse');
|
|
|
|
var EllipseContains = require('../geom/ellipse/Contains');
|
2019-01-16 12:13:30 +00:00
|
|
|
var Events = require('./events');
|
2018-01-26 06:55:15 +00:00
|
|
|
var EventEmitter = require('eventemitter3');
|
2018-06-11 10:35:31 +00:00
|
|
|
var GetFastValue = require('../utils/object/GetFastValue');
|
2018-06-08 14:16:35 +00:00
|
|
|
var InputPluginCache = require('./InputPluginCache');
|
2018-06-11 10:35:31 +00:00
|
|
|
var IsPlainObject = require('../utils/object/IsPlainObject');
|
2018-05-15 11:51:50 +00:00
|
|
|
var PluginCache = require('../plugins/PluginCache');
|
2018-01-16 16:14:21 +00:00
|
|
|
var Rectangle = require('../geom/rectangle/Rectangle');
|
|
|
|
var RectangleContains = require('../geom/rectangle/Contains');
|
2019-01-18 13:41:43 +00:00
|
|
|
var SceneEvents = require('../scene/events');
|
2018-01-16 16:14:21 +00:00
|
|
|
var Triangle = require('../geom/triangle/Triangle');
|
|
|
|
var TriangleContains = require('../geom/triangle/Contains');
|
2017-07-20 16:10:12 +00:00
|
|
|
|
2018-02-07 15:27:21 +00:00
|
|
|
/**
|
|
|
|
* @classdesc
|
2018-06-04 14:19:25 +00:00
|
|
|
* The Input Plugin belongs to a Scene and handles all input related events and operations for it.
|
|
|
|
*
|
|
|
|
* You can access it from within a Scene using `this.input`.
|
|
|
|
*
|
|
|
|
* It emits events directly. For example, you can do:
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* this.input.on('pointerdown', callback, context);
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* To listen for a pointer down event anywhere on the game canvas.
|
|
|
|
*
|
|
|
|
* Game Objects can be enabled for input by calling their `setInteractive` method. After which they
|
|
|
|
* will directly emit input events:
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* var sprite = this.add.sprite(x, y, texture);
|
|
|
|
* sprite.setInteractive();
|
|
|
|
* sprite.on('pointerdown', callback, context);
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* Please see the Input examples and tutorials for more information.
|
2018-02-07 15:27:21 +00:00
|
|
|
*
|
|
|
|
* @class InputPlugin
|
2018-03-28 14:03:54 +00:00
|
|
|
* @extends Phaser.Events.EventEmitter
|
2018-10-10 09:49:13 +00:00
|
|
|
* @memberof Phaser.Input
|
2018-02-07 15:27:21 +00:00
|
|
|
* @constructor
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that this Input Plugin is responsible for.
|
2018-02-07 15:27:21 +00:00
|
|
|
*/
|
2018-01-16 16:14:21 +00:00
|
|
|
var InputPlugin = new Class({
|
2017-07-20 16:10:12 +00:00
|
|
|
|
2018-01-12 17:09:09 +00:00
|
|
|
Extends: EventEmitter,
|
|
|
|
|
2017-07-20 16:10:12 +00:00
|
|
|
initialize:
|
|
|
|
|
2018-01-16 16:14:21 +00:00
|
|
|
function InputPlugin (scene)
|
2017-07-20 16:10:12 +00:00
|
|
|
{
|
2018-01-12 17:09:09 +00:00
|
|
|
EventEmitter.call(this);
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Scene that this Input Plugin is responsible for.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#scene
|
|
|
|
* @type {Phaser.Scene}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this.scene = scene;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Scene Systems class.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#systems
|
|
|
|
* @type {Phaser.Scenes.Systems}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-01-16 22:28:29 +00:00
|
|
|
this.systems = scene.sys;
|
|
|
|
|
2018-04-14 03:23:11 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Scene Systems Settings.
|
2018-04-14 03:23:11 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#settings
|
2019-02-13 15:38:50 +00:00
|
|
|
* @type {Phaser.Scenes.Types.SettingsObject}
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-04-14 03:23:11 +00:00
|
|
|
*/
|
|
|
|
this.settings = scene.sys.settings;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Game Input Manager.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#manager
|
|
|
|
* @type {Phaser.Input.InputManager}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-08-15 22:35:35 +00:00
|
|
|
this.manager = scene.sys.game.input;
|
2017-07-20 16:10:12 +00:00
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
/**
|
|
|
|
* Internal event queue used for plugins only.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pluginEvents
|
|
|
|
* @type {Phaser.Events.EventEmitter}
|
|
|
|
* @private
|
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
this.pluginEvents = new EventEmitter();
|
|
|
|
|
2018-04-14 03:23:11 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* If set, the Input Plugin will run its update loop every frame.
|
2018-04-14 03:23:11 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#enabled
|
|
|
|
* @type {boolean}
|
|
|
|
* @default true
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-04-14 03:23:11 +00:00
|
|
|
*/
|
|
|
|
this.enabled = true;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Scene Display List. This property is set during the `boot` method.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#displayList
|
|
|
|
* @type {Phaser.GameObjects.DisplayList}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this.displayList;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Scene Cameras Manager. This property is set during the `boot` method.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#cameras
|
2018-06-04 14:19:25 +00:00
|
|
|
* @type {Phaser.Cameras.Scene2D.CameraManager}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this.cameras;
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
// Inject the available input plugins into this class
|
|
|
|
InputPluginCache.install(this);
|
2018-01-26 06:55:15 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A reference to the Mouse Manager.
|
|
|
|
*
|
|
|
|
* This property is only set if Mouse support has been enabled in your Game Configuration file.
|
|
|
|
*
|
|
|
|
* If you just wish to get access to the mouse pointer, use the `mousePointer` property instead.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#mouse
|
2018-06-04 14:19:25 +00:00
|
|
|
* @type {?Phaser.Input.Mouse.MouseManager}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-21 02:39:55 +00:00
|
|
|
this.mouse = this.manager.mouse;
|
2018-01-26 06:55:15 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* When set to `true` (the default) the Input Plugin will emulate DOM behavior by only emitting events from
|
|
|
|
* the top-most Game Objects in the Display List.
|
|
|
|
*
|
|
|
|
* If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#topOnly
|
|
|
|
* @type {boolean}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @default true
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this.topOnly = true;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* How often should the Pointers be checked?
|
|
|
|
*
|
|
|
|
* The value is a time, given in ms, and is the time that must have elapsed between game steps before
|
|
|
|
* the Pointers will be polled again. When a pointer is polled it runs a hit test to see which Game
|
|
|
|
* Objects are currently below it, or being interacted with it.
|
|
|
|
*
|
|
|
|
* Pointers will *always* be checked if they have been moved by the user, or press or released.
|
|
|
|
*
|
|
|
|
* This property only controls how often they will be polled if they have not been updated.
|
|
|
|
* You should set this if you want to have Game Objects constantly check against the pointers, even
|
|
|
|
* if the pointer didn't move itself.
|
|
|
|
*
|
2018-01-26 06:55:15 +00:00
|
|
|
* Set to 0 to poll constantly. Set to -1 to only poll on user movement.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#pollRate
|
|
|
|
* @type {integer}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @default -1
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this.pollRate = -1;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Internal poll timer value.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_pollTimer
|
|
|
|
* @type {number}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default 0
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
this._pollTimer = 0;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
var _eventData = { cancelled: false };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal event propagation callback container.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#_eventContainer
|
2019-02-13 14:17:36 +00:00
|
|
|
* @type {Phaser.Input.Types.EventData}
|
2018-09-12 11:38:08 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.13.0
|
|
|
|
*/
|
|
|
|
this._eventContainer = {
|
|
|
|
stopPropagation: function ()
|
|
|
|
{
|
|
|
|
_eventData.cancelled = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal event propagation data object.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#_eventData
|
|
|
|
* @type {object}
|
|
|
|
* @private
|
|
|
|
* @since 3.13.0
|
|
|
|
*/
|
|
|
|
this._eventData = _eventData;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* The distance, in pixels, a pointer has to move while being held down, before it thinks it is being dragged.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#dragDistanceThreshold
|
|
|
|
* @type {number}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @default 0
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-27 02:40:58 +00:00
|
|
|
this.dragDistanceThreshold = 0;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* The amount of time, in ms, a pointer has to be held down before it thinks it is dragging.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#dragTimeThreshold
|
|
|
|
* @type {number}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @default 0
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-27 02:40:58 +00:00
|
|
|
this.dragTimeThreshold = 0;
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* Used to temporarily store the results of the Hit Test
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_temp
|
|
|
|
* @type {array}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-25 01:47:26 +00:00
|
|
|
this._temp = [];
|
|
|
|
|
2018-03-01 02:46:17 +00:00
|
|
|
/**
|
|
|
|
* Used to temporarily store the results of the Hit Test dropZones
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#_tempZones
|
|
|
|
* @type {array}
|
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
|
|
|
this._tempZones = [];
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A list of all Game Objects that have been set to be interactive in the Scene this Input Plugin is managing.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_list
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-25 03:10:50 +00:00
|
|
|
this._list = [];
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* Objects waiting to be inserted to the list on the next call to 'begin'.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_pendingInsertion
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-25 03:10:50 +00:00
|
|
|
this._pendingInsertion = [];
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* Objects waiting to be removed from the list on the next call to 'begin'.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_pendingRemoval
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-25 03:10:50 +00:00
|
|
|
this._pendingRemoval = [];
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* A list of all Game Objects that have been enabled for dragging.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_draggable
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @default []
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-27 02:40:58 +00:00
|
|
|
this._draggable = [];
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* A list of all Interactive Objects currently considered as being 'draggable' by any pointer, indexed by pointer ID.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_drag
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {{0:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array}}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-06-11 12:39:28 +00:00
|
|
|
this._drag = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] };
|
2017-07-27 02:40:58 +00:00
|
|
|
|
2019-01-04 16:34:59 +00:00
|
|
|
/**
|
|
|
|
* A array containing the dragStates, for this Scene, index by the Pointer ID.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#_dragState
|
|
|
|
* @type {integer[]}
|
|
|
|
* @private
|
|
|
|
* @since 3.16.0
|
|
|
|
*/
|
2019-01-05 10:03:11 +00:00
|
|
|
this._dragState = [];
|
2019-01-04 16:34:59 +00:00
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* A list of all Interactive Objects currently considered as being 'over' by any pointer, indexed by pointer ID.
|
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_over
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {{0:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array}}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-06-11 12:39:28 +00:00
|
|
|
this._over = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] };
|
2017-07-20 16:10:12 +00:00
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* A list of valid DOM event types.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-02-13 01:13:12 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#_validTypes
|
2018-03-19 12:43:19 +00:00
|
|
|
* @type {string[]}
|
2018-01-26 06:55:15 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-27 17:24:04 +00:00
|
|
|
this._validTypes = [ 'onDown', 'onUp', 'onOver', 'onOut', 'onMove', 'onDragStart', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDrop' ];
|
2018-04-13 16:12:17 +00:00
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
|
|
|
|
scene.sys.events.on(SceneEvents.START, this.start, this);
|
2017-07-20 16:10:12 +00:00
|
|
|
},
|
|
|
|
|
2018-04-17 01:34:07 +00:00
|
|
|
/**
|
|
|
|
* This method is called automatically, only once, when the Scene is first created.
|
|
|
|
* Do not invoke it directly.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#boot
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#BOOT
|
2018-04-17 01:34:07 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.5.1
|
|
|
|
*/
|
|
|
|
boot: function ()
|
|
|
|
{
|
|
|
|
this.cameras = this.systems.cameras;
|
|
|
|
|
|
|
|
this.displayList = this.systems.displayList;
|
2018-04-17 11:25:45 +00:00
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
|
2018-06-08 14:16:35 +00:00
|
|
|
|
|
|
|
// Registered input plugins listen for this
|
2019-01-16 12:13:30 +00:00
|
|
|
this.pluginEvents.emit(Events.BOOT);
|
2018-04-17 01:34:07 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-04-13 16:12:17 +00:00
|
|
|
* This method is called automatically by the Scene when it is starting up.
|
|
|
|
* It is responsible for creating local systems, properties and listening for Scene events.
|
|
|
|
* Do not invoke it directly.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-04-13 16:12:17 +00:00
|
|
|
* @method Phaser.Input.InputPlugin#start
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#START
|
2018-04-13 16:12:17 +00:00
|
|
|
* @private
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-04-13 16:12:17 +00:00
|
|
|
start: function ()
|
2018-01-16 22:28:29 +00:00
|
|
|
{
|
2018-01-18 14:00:31 +00:00
|
|
|
var eventEmitter = this.systems.events;
|
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
eventEmitter.on(SceneEvents.TRANSITION_START, this.transitionIn, this);
|
|
|
|
eventEmitter.on(SceneEvents.TRANSITION_OUT, this.transitionOut, this);
|
|
|
|
eventEmitter.on(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this);
|
|
|
|
eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this);
|
2019-04-24 08:34:40 +00:00
|
|
|
|
|
|
|
if (this.manager.useQueue)
|
|
|
|
{
|
|
|
|
eventEmitter.on(SceneEvents.UPDATE, this.update, this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eventEmitter.on(SceneEvents.UPDATE, this.pluginUpdate, this);
|
|
|
|
}
|
2018-04-14 03:23:11 +00:00
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
|
2017-09-07 21:26:53 +00:00
|
|
|
|
2019-02-10 17:10:13 +00:00
|
|
|
this.manager.events.on(Events.GAME_OUT, this.onGameOut, this);
|
|
|
|
this.manager.events.on(Events.GAME_OVER, this.onGameOver, this);
|
|
|
|
|
2018-04-14 03:23:11 +00:00
|
|
|
this.enabled = true;
|
2018-06-08 14:16:35 +00:00
|
|
|
|
2019-01-05 10:03:11 +00:00
|
|
|
// Populate the pointer drag states
|
|
|
|
this._dragState = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
// Registered input plugins listen for this
|
2019-01-16 12:13:30 +00:00
|
|
|
this.pluginEvents.emit(Events.START);
|
2017-09-07 21:26:53 +00:00
|
|
|
},
|
|
|
|
|
2019-02-10 17:10:13 +00:00
|
|
|
/**
|
|
|
|
* Game Over handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#onGameOver
|
|
|
|
* @fires Phaser.Input.Events#GAME_OVER
|
|
|
|
* @private
|
|
|
|
* @since 3.16.2
|
|
|
|
*/
|
|
|
|
onGameOver: function (event)
|
|
|
|
{
|
|
|
|
if (this.isActive())
|
|
|
|
{
|
|
|
|
this.emit(Events.GAME_OVER, event.timeStamp, event);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Game Out handler.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#onGameOut
|
|
|
|
* @fires Phaser.Input.Events#GAME_OUT
|
|
|
|
* @private
|
|
|
|
* @since 3.16.2
|
|
|
|
*/
|
|
|
|
onGameOut: function (event)
|
|
|
|
{
|
|
|
|
if (this.isActive())
|
|
|
|
{
|
|
|
|
this.emit(Events.GAME_OUT, event.timeStamp, event);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* The pre-update handler is responsible for checking the pending removal and insertion lists and
|
|
|
|
* deleting old Game Objects.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#preUpdate
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#PRE_UPDATE
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-01-16 22:28:29 +00:00
|
|
|
preUpdate: function ()
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-06-08 14:16:35 +00:00
|
|
|
// Registered input plugins listen for this
|
2019-01-16 12:13:30 +00:00
|
|
|
this.pluginEvents.emit(Events.PRE_UPDATE);
|
2018-06-08 14:16:35 +00:00
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
var removeList = this._pendingRemoval;
|
|
|
|
var insertList = this._pendingInsertion;
|
|
|
|
|
|
|
|
var toRemove = removeList.length;
|
|
|
|
var toInsert = insertList.length;
|
|
|
|
|
|
|
|
if (toRemove === 0 && toInsert === 0)
|
|
|
|
{
|
|
|
|
// Quick bail
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var current = this._list;
|
|
|
|
|
|
|
|
// Delete old gameObjects
|
|
|
|
for (var i = 0; i < toRemove; i++)
|
|
|
|
{
|
|
|
|
var gameObject = removeList[i];
|
|
|
|
|
|
|
|
var index = current.indexOf(gameObject);
|
|
|
|
|
|
|
|
if (index > -1)
|
|
|
|
{
|
|
|
|
current.splice(index, 1);
|
|
|
|
|
|
|
|
this.clear(gameObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear the removal list
|
|
|
|
removeList.length = 0;
|
2018-05-18 17:08:37 +00:00
|
|
|
this._pendingRemoval.length = 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
// Move pendingInsertion to list (also clears pendingInsertion at the same time)
|
|
|
|
this._list = current.concat(insertList.splice(0));
|
|
|
|
},
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
/**
|
|
|
|
* Checks to see if both this plugin and the Scene to which it belongs is active.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#isActive
|
|
|
|
* @since 3.10.0
|
|
|
|
*
|
|
|
|
* @return {boolean} `true` if the plugin and the Scene it belongs to is active.
|
|
|
|
*/
|
|
|
|
isActive: function ()
|
|
|
|
{
|
|
|
|
return (this.enabled && this.scene.sys.isActive());
|
|
|
|
},
|
|
|
|
|
2019-04-24 08:34:40 +00:00
|
|
|
/**
|
|
|
|
* The internal update loop for the plugins belong to this Input class.
|
|
|
|
* Called automatically by the Scene Systems step and only used if `useQueue` is false.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#pluginUpdate
|
|
|
|
* @private
|
|
|
|
* @since 3.17.0
|
|
|
|
*
|
|
|
|
* @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now().
|
|
|
|
* @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class.
|
|
|
|
*/
|
|
|
|
pluginUpdate: function (time, delta)
|
|
|
|
{
|
|
|
|
if (!this.isActive())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.pluginEvents.emit(Events.UPDATE, time, delta);
|
|
|
|
},
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
/**
|
|
|
|
* The internal update loop for the Input Plugin.
|
|
|
|
* Called automatically by the Scene Systems step.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#update
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#UPDATE
|
2018-06-08 14:16:35 +00:00
|
|
|
* @private
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now().
|
|
|
|
* @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class.
|
|
|
|
*/
|
|
|
|
update: function (time, delta)
|
|
|
|
{
|
|
|
|
if (!this.isActive())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var manager = this.manager;
|
|
|
|
|
2019-04-24 08:34:40 +00:00
|
|
|
// this.pluginEvents.emit(Events.UPDATE, time, delta);
|
2018-11-28 13:10:54 +00:00
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
// Another Scene above this one has already consumed the input events, or we're in transition
|
|
|
|
if (manager.globalTopOnly && manager.ignoreEvents)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-08 13:39:28 +00:00
|
|
|
var runUpdate = (manager.dirty || this.pollRate === 0 || manager.useQueue);
|
2018-06-08 14:16:35 +00:00
|
|
|
|
|
|
|
if (this.pollRate > -1)
|
|
|
|
{
|
|
|
|
this._pollTimer -= delta;
|
|
|
|
|
|
|
|
if (this._pollTimer < 0)
|
|
|
|
{
|
|
|
|
runUpdate = true;
|
|
|
|
|
|
|
|
// Discard timer diff
|
|
|
|
this._pollTimer = this.pollRate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!runUpdate)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var pointers = this.manager.pointers;
|
2019-01-23 15:51:42 +00:00
|
|
|
var pointersTotal = this.manager.pointersTotal;
|
2018-06-08 14:16:35 +00:00
|
|
|
|
2019-01-23 15:51:42 +00:00
|
|
|
for (var i = 0; i < pointersTotal; i++)
|
2018-06-08 14:16:35 +00:00
|
|
|
{
|
|
|
|
var pointer = pointers[i];
|
|
|
|
|
|
|
|
// Always reset this array
|
|
|
|
this._tempZones = [];
|
|
|
|
|
|
|
|
// _temp contains a hit tested and camera culled list of IO objects
|
|
|
|
this._temp = this.hitTestPointer(pointer);
|
|
|
|
|
|
|
|
this.sortGameObjects(this._temp);
|
|
|
|
this.sortGameObjects(this._tempZones);
|
|
|
|
|
|
|
|
if (this.topOnly)
|
|
|
|
{
|
|
|
|
// Only the top-most one counts now, so safely ignore the rest
|
|
|
|
if (this._temp.length)
|
|
|
|
{
|
|
|
|
this._temp.splice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._tempZones.length)
|
|
|
|
{
|
|
|
|
this._tempZones.splice(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var total = this.processDragEvents(pointer, time);
|
|
|
|
|
2019-01-23 15:51:42 +00:00
|
|
|
// TODO: Enable for touch - the method needs recoding to take ALL pointers at once
|
|
|
|
// and process them all together, in the same batch, otherwise the justOut and stillOver
|
|
|
|
// arrays will get corrupted in multi-touch enabled games. For now, we'll enable it for
|
|
|
|
// single touch games (which is probably the majority anyway).
|
|
|
|
if (pointersTotal < 3 || !pointer.wasTouch)
|
2018-06-08 14:16:35 +00:00
|
|
|
{
|
|
|
|
total += this.processOverOutEvents(pointer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pointer.justDown)
|
|
|
|
{
|
|
|
|
total += this.processDownEvents(pointer);
|
|
|
|
}
|
|
|
|
|
2018-11-22 17:18:31 +00:00
|
|
|
if (pointer.justMoved)
|
2018-06-08 14:16:35 +00:00
|
|
|
{
|
2018-11-22 17:18:31 +00:00
|
|
|
total += this.processMoveEvents(pointer);
|
2018-06-08 14:16:35 +00:00
|
|
|
}
|
|
|
|
|
2018-11-22 17:18:31 +00:00
|
|
|
if (pointer.justUp)
|
2018-06-08 14:16:35 +00:00
|
|
|
{
|
2018-11-22 17:18:31 +00:00
|
|
|
total += this.processUpEvents(pointer);
|
2018-06-08 14:16:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Clears a Game Object so it no longer has an Interactive Object associated with it.
|
|
|
|
* The Game Object is then queued for removal from the Input Plugin on the next update.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#clear
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have its Interactive Object removed.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @return {Phaser.GameObjects.GameObject} The Game Object that had its Interactive Object removed.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
clear: function (gameObject)
|
|
|
|
{
|
|
|
|
var input = gameObject.input;
|
|
|
|
|
2018-05-18 17:08:37 +00:00
|
|
|
// If GameObject.input already cleared from higher class
|
2018-05-24 13:03:29 +00:00
|
|
|
if (!input)
|
2018-05-18 17:08:37 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.queueForRemoval(gameObject);
|
2018-05-24 13:03:29 +00:00
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
input.gameObject = undefined;
|
|
|
|
input.target = undefined;
|
|
|
|
input.hitArea = undefined;
|
|
|
|
input.hitAreaCallback = undefined;
|
|
|
|
input.callbackContext = undefined;
|
|
|
|
|
2018-09-14 13:48:53 +00:00
|
|
|
this.manager.resetCursor(input);
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
gameObject.input = null;
|
|
|
|
|
2018-03-01 02:46:17 +00:00
|
|
|
// Clear from _draggable, _drag and _over
|
|
|
|
var index = this._draggable.indexOf(gameObject);
|
|
|
|
|
|
|
|
if (index > -1)
|
|
|
|
{
|
|
|
|
this._draggable.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
2018-03-01 04:13:30 +00:00
|
|
|
index = this._drag[0].indexOf(gameObject);
|
2018-03-01 02:46:17 +00:00
|
|
|
|
|
|
|
if (index > -1)
|
|
|
|
{
|
2018-03-01 04:13:30 +00:00
|
|
|
this._drag[0].splice(index, 1);
|
2018-03-01 02:46:17 +00:00
|
|
|
}
|
|
|
|
|
2018-03-01 04:13:30 +00:00
|
|
|
index = this._over[0].indexOf(gameObject);
|
2018-03-01 02:46:17 +00:00
|
|
|
|
|
|
|
if (index > -1)
|
|
|
|
{
|
2018-03-01 04:13:30 +00:00
|
|
|
this._over[0].splice(index, 1);
|
2018-03-01 02:46:17 +00:00
|
|
|
}
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
return gameObject;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Disables Input on a single Game Object.
|
|
|
|
*
|
|
|
|
* An input disabled Game Object still retains its Interactive Object component and can be re-enabled
|
|
|
|
* at any time, by passing it to `InputPlugin.enable`.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#disable
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its input system disabled.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
disable: function (gameObject)
|
|
|
|
{
|
|
|
|
gameObject.input.enabled = false;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Enable a Game Object for interaction.
|
|
|
|
*
|
|
|
|
* If the Game Object already has an Interactive Object component, it is enabled and returned.
|
|
|
|
*
|
|
|
|
* Otherwise, a new Interactive Object component is created and assigned to the Game Object's `input` property.
|
|
|
|
*
|
2018-06-11 10:35:31 +00:00
|
|
|
* Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area
|
|
|
|
* for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced
|
|
|
|
* input detection.
|
2018-06-04 14:19:25 +00:00
|
|
|
*
|
2018-06-11 10:35:31 +00:00
|
|
|
* If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If
|
|
|
|
* this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific
|
|
|
|
* shape for it to use.
|
|
|
|
*
|
|
|
|
* You can also provide an Input Configuration Object as the only argument to this method.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#enable
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to be enabled for input.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {(Phaser.Input.Types.InputConfiguration|any)} [shape] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used.
|
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The 'contains' function to invoke to check if the pointer is within the hit area.
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {boolean} [dropZone=false] - Is this Game Object a drop zone or not?
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-01 02:46:17 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This Input Plugin.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-03-01 02:46:17 +00:00
|
|
|
enable: function (gameObject, shape, callback, dropZone)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-03-01 02:46:17 +00:00
|
|
|
if (dropZone === undefined) { dropZone = false; }
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
if (gameObject.input)
|
|
|
|
{
|
|
|
|
// If it is already has an InteractiveObject then just enable it and return
|
|
|
|
gameObject.input.enabled = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Create an InteractiveObject and enable it
|
|
|
|
this.setHitArea(gameObject, shape, callback);
|
|
|
|
}
|
2018-03-19 12:43:19 +00:00
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
if (gameObject.input && dropZone && !gameObject.input.dropZone)
|
2018-04-11 10:25:31 +00:00
|
|
|
{
|
|
|
|
gameObject.input.dropZone = dropZone;
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Takes the given Pointer and performs a hit test against it, to see which interactive Game Objects
|
|
|
|
* it is currently above.
|
|
|
|
*
|
|
|
|
* The hit test is performed against which-ever Camera the Pointer is over. If it is over multiple
|
2018-06-04 21:14:58 +00:00
|
|
|
* cameras, it starts checking the camera at the top of the camera list, and if nothing is found, iterates down the list.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#hitTestPointer
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @return {Phaser.GameObjects.GameObject[]} An array of all the interactive Game Objects the Pointer was above.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
hitTestPointer: function (pointer)
|
|
|
|
{
|
2018-06-04 21:14:58 +00:00
|
|
|
var cameras = this.cameras.getCamerasBelowPointer(pointer);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-06-04 21:14:58 +00:00
|
|
|
for (var c = 0; c < cameras.length; c++)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-06-04 21:14:58 +00:00
|
|
|
var camera = cameras[c];
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-06-27 11:45:03 +00:00
|
|
|
// Get a list of all objects that can be seen by the camera below the pointer in the scene and store in 'over' array.
|
2018-01-16 16:00:37 +00:00
|
|
|
// All objects in this array are input enabled, as checked by the hitTest method, so we don't need to check later on as well.
|
2018-06-04 12:23:51 +00:00
|
|
|
var over = this.manager.hitTest(pointer, this._list, camera);
|
2018-03-01 02:46:17 +00:00
|
|
|
|
|
|
|
// Filter out the drop zones
|
|
|
|
for (var i = 0; i < over.length; i++)
|
|
|
|
{
|
|
|
|
var obj = over[i];
|
|
|
|
|
|
|
|
if (obj.input.dropZone)
|
|
|
|
{
|
|
|
|
this._tempZones.push(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-04 21:14:58 +00:00
|
|
|
if (over.length > 0)
|
|
|
|
{
|
|
|
|
pointer.camera = camera;
|
|
|
|
|
|
|
|
return over;
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-06-04 21:14:58 +00:00
|
|
|
|
2018-06-27 11:45:03 +00:00
|
|
|
// If we got this far then there were no Game Objects below the pointer, but it was still over
|
|
|
|
// a camera, so set that the top-most one into the pointer
|
|
|
|
|
|
|
|
pointer.camera = cameras[0];
|
|
|
|
|
2018-06-04 21:14:58 +00:00
|
|
|
return [];
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* An internal method that handles the Pointer down event.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#processDownEvents
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DOWN
|
|
|
|
* @fires Phaser.Input.Events#POINTER_DOWN
|
|
|
|
* @fires Phaser.Input.Events#POINTER_DOWN_OUTSIDE
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The Pointer being tested.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {integer} The total number of objects interacted with.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
processDownEvents: function (pointer)
|
|
|
|
{
|
2018-09-12 11:38:08 +00:00
|
|
|
var total = 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
var currentlyOver = this._temp;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
var _eventData = this._eventData;
|
|
|
|
var _eventContainer = this._eventContainer;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
_eventData.cancelled = false;
|
|
|
|
|
|
|
|
var aborted = false;
|
2018-01-20 04:44:54 +00:00
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
// Go through all objects the pointer was over and fire their events / callbacks
|
|
|
|
for (var i = 0; i < currentlyOver.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = currentlyOver[i];
|
|
|
|
|
|
|
|
if (!gameObject.input)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-01-20 04:44:54 +00:00
|
|
|
total++;
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_DOWN, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
this.emit(Events.GAMEOBJECT_DOWN, pointer, gameObject, _eventContainer);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-29 13:44:42 +00:00
|
|
|
// If they released outside the canvas, but pressed down inside it, we'll still dispatch the event.
|
2018-09-12 11:38:08 +00:00
|
|
|
if (!aborted)
|
|
|
|
{
|
2019-01-16 12:13:30 +00:00
|
|
|
if (pointer.downElement === this.manager.game.canvas)
|
|
|
|
{
|
|
|
|
this.emit(Events.POINTER_DOWN, pointer, currentlyOver);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.emit(Events.POINTER_DOWN_OUTSIDE, pointer);
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-01-20 04:44:54 +00:00
|
|
|
|
|
|
|
return total;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2019-01-04 16:34:59 +00:00
|
|
|
/**
|
|
|
|
* Returns the drag state of the given Pointer for this Input Plugin.
|
|
|
|
*
|
|
|
|
* The state will be one of the following:
|
|
|
|
*
|
|
|
|
* 0 = Not dragging anything
|
|
|
|
* 1 = Primary button down and objects below, so collect a draglist
|
|
|
|
* 2 = Pointer being checked if meets drag criteria
|
|
|
|
* 3 = Pointer meets criteria, notify the draglist
|
|
|
|
* 4 = Pointer actively dragging the draglist and has moved
|
|
|
|
* 5 = Pointer actively dragging but has been released, notify draglist
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#getDragState
|
|
|
|
* @since 3.16.0
|
|
|
|
*
|
|
|
|
* @param {Phaser.Input.Pointer} pointer - The Pointer to get the drag state for.
|
|
|
|
*
|
|
|
|
* @return {integer} The drag state of the given Pointer.
|
|
|
|
*/
|
|
|
|
getDragState: function (pointer)
|
|
|
|
{
|
|
|
|
return this._dragState[pointer.id];
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the drag state of the given Pointer for this Input Plugin.
|
|
|
|
*
|
|
|
|
* The state must be one of the following values:
|
|
|
|
*
|
|
|
|
* 0 = Not dragging anything
|
|
|
|
* 1 = Primary button down and objects below, so collect a draglist
|
|
|
|
* 2 = Pointer being checked if meets drag criteria
|
|
|
|
* 3 = Pointer meets criteria, notify the draglist
|
|
|
|
* 4 = Pointer actively dragging the draglist and has moved
|
|
|
|
* 5 = Pointer actively dragging but has been released, notify draglist
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setDragState
|
|
|
|
* @since 3.16.0
|
|
|
|
*
|
|
|
|
* @param {Phaser.Input.Pointer} pointer - The Pointer to set the drag state for.
|
|
|
|
* @param {integer} state - The drag state value. An integer between 0 and 5.
|
|
|
|
*/
|
|
|
|
setDragState: function (pointer, state)
|
|
|
|
{
|
|
|
|
this._dragState[pointer.id] = state;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* An internal method that handles the Pointer drag events.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#processDragEvents
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2019-01-16 13:12:07 +00:00
|
|
|
* @fires Phaser.Input.Events#DRAG_END
|
|
|
|
* @fires Phaser.Input.Events#DRAG_ENTER
|
|
|
|
* @fires Phaser.Input.Events#DRAG
|
|
|
|
* @fires Phaser.Input.Events#DRAG_LEAVE
|
|
|
|
* @fires Phaser.Input.Events#DRAG_OVER
|
|
|
|
* @fires Phaser.Input.Events#DRAG_START
|
|
|
|
* @fires Phaser.Input.Events#DROP
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DOWN
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_END
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_OVER
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_START
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_DROP
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects.
|
|
|
|
* @param {number} time - The time stamp of the most recent Game step.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @return {integer} The total number of objects interacted with.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
processDragEvents: function (pointer, time)
|
|
|
|
{
|
|
|
|
if (this._draggable.length === 0)
|
|
|
|
{
|
|
|
|
// There are no draggable items, so let's not even bother going further
|
2018-01-20 04:44:54 +00:00
|
|
|
return 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var i;
|
|
|
|
var gameObject;
|
|
|
|
var list;
|
|
|
|
var input;
|
|
|
|
var currentlyOver = this._temp;
|
|
|
|
|
|
|
|
// 0 = Not dragging anything
|
|
|
|
// 1 = Primary button down and objects below, so collect a draglist
|
|
|
|
// 2 = Pointer being checked if meets drag criteria
|
|
|
|
// 3 = Pointer meets criteria, notify the draglist
|
|
|
|
// 4 = Pointer actively dragging the draglist and has moved
|
|
|
|
// 5 = Pointer actively dragging but has been released, notify draglist
|
|
|
|
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 0 && pointer.primaryDown && pointer.justDown && currentlyOver.length > 0)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 1);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2019-01-04 16:34:59 +00:00
|
|
|
else if (this.getDragState(pointer) > 0 && !pointer.primaryDown && pointer.justUp)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 5);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Process the various drag states
|
|
|
|
|
|
|
|
// 1 = Primary button down and objects below, so collect a draglist
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 1)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
// Get draggable objects, sort them, pick the top (or all) and store them somewhere
|
|
|
|
var draglist = [];
|
|
|
|
|
|
|
|
for (i = 0; i < currentlyOver.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = currentlyOver[i];
|
|
|
|
|
2018-06-19 02:33:22 +00:00
|
|
|
if (gameObject.input.draggable && (gameObject.input.dragState === 0))
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
draglist.push(gameObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (draglist.length === 0)
|
|
|
|
{
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 0);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-03-05 21:49:00 +00:00
|
|
|
return 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
else if (draglist.length > 1)
|
|
|
|
{
|
|
|
|
this.sortGameObjects(draglist);
|
|
|
|
|
|
|
|
if (this.topOnly)
|
|
|
|
{
|
|
|
|
draglist.splice(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// draglist now contains all potential candidates for dragging
|
|
|
|
this._drag[pointer.id] = draglist;
|
|
|
|
|
|
|
|
if (this.dragDistanceThreshold === 0 && this.dragTimeThreshold === 0)
|
|
|
|
{
|
|
|
|
// No drag criteria, so snap immediately to mode 3
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 3);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Check the distance / time
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 2);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2 = Pointer being checked if meets drag criteria
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 2)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
// Has it moved far enough to be considered a drag?
|
|
|
|
if (this.dragDistanceThreshold > 0 && DistanceBetween(pointer.x, pointer.y, pointer.downX, pointer.downY) >= this.dragDistanceThreshold)
|
|
|
|
{
|
|
|
|
// Alrighty, we've got a drag going on ...
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 3);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Held down long enough to be considered a drag?
|
|
|
|
if (this.dragTimeThreshold > 0 && (time >= pointer.downTime + this.dragTimeThreshold))
|
|
|
|
{
|
|
|
|
// Alrighty, we've got a drag going on ...
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 3);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3 = Pointer meets criteria and is freshly down, notify the draglist
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 3)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
list = this._drag[pointer.id];
|
|
|
|
|
|
|
|
for (i = 0; i < list.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = list[i];
|
|
|
|
|
|
|
|
input = gameObject.input;
|
|
|
|
|
|
|
|
input.dragState = 2;
|
|
|
|
|
|
|
|
input.dragX = pointer.x - gameObject.x;
|
|
|
|
input.dragY = pointer.y - gameObject.y;
|
|
|
|
|
|
|
|
input.dragStartX = gameObject.x;
|
|
|
|
input.dragStartY = gameObject.y;
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_START, pointer, input.dragX, input.dragY);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_START, pointer, gameObject);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 4);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
return list.length;
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 4 = Pointer actively dragging the draglist and has moved
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 4 && pointer.justMoved && !pointer.justUp)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-03-01 02:46:17 +00:00
|
|
|
var dropZones = this._tempZones;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
list = this._drag[pointer.id];
|
|
|
|
|
|
|
|
for (i = 0; i < list.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = list[i];
|
|
|
|
|
|
|
|
input = gameObject.input;
|
|
|
|
|
|
|
|
// If this GO has a target then let's check it
|
|
|
|
if (input.target)
|
|
|
|
{
|
|
|
|
var index = dropZones.indexOf(input.target);
|
|
|
|
|
|
|
|
// Got a target, are we still over it?
|
|
|
|
if (index === 0)
|
|
|
|
{
|
|
|
|
// We're still over it, and it's still the top of the display list, phew ...
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_OVER, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_OVER, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
else if (index > 0)
|
|
|
|
{
|
|
|
|
// Still over it but it's no longer top of the display list (targets must always be at the top)
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_LEAVE, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
input.target = dropZones[0];
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_ENTER, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Nope, we've moved on (or the target has!), leave the old target
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_LEAVE, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
// Anything new to replace it?
|
|
|
|
// Yup!
|
|
|
|
if (dropZones[0])
|
|
|
|
{
|
|
|
|
input.target = dropZones[0];
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_ENTER, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Nope
|
|
|
|
input.target = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!input.target && dropZones[0])
|
|
|
|
{
|
|
|
|
input.target = dropZones[0];
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_ENTER, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var dragX = pointer.x - gameObject.input.dragX;
|
|
|
|
var dragY = pointer.y - gameObject.input.dragY;
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG, pointer, dragX, dragY);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG, pointer, gameObject, dragX, dragY);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-03-16 14:57:19 +00:00
|
|
|
|
|
|
|
return list.length;
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
// 5 = Pointer was actively dragging but has been released, notify draglist
|
2019-01-04 16:34:59 +00:00
|
|
|
if (this.getDragState(pointer) === 5)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
list = this._drag[pointer.id];
|
|
|
|
|
|
|
|
for (i = 0; i < list.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = list[i];
|
|
|
|
|
|
|
|
input = gameObject.input;
|
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
if (input.dragState === 2)
|
|
|
|
{
|
|
|
|
input.dragState = 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
input.dragX = input.localX - gameObject.displayOriginX;
|
|
|
|
input.dragY = input.localY - gameObject.displayOriginY;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
var dropped = false;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
if (input.target)
|
|
|
|
{
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DROP, pointer, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DROP, pointer, gameObject, input.target);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
input.target = null;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
dropped = true;
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-22 20:24:50 +00:00
|
|
|
// And finally the dragend event
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_DRAG_END, pointer, input.dragX, input.dragY, dropped);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.DRAG_END, pointer, gameObject, dropped);
|
2018-05-22 20:24:50 +00:00
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
2019-01-04 16:34:59 +00:00
|
|
|
this.setDragState(pointer, 0);
|
2018-05-22 20:24:50 +00:00
|
|
|
|
2018-04-04 21:09:18 +00:00
|
|
|
list.splice(0);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-03-16 14:57:19 +00:00
|
|
|
|
|
|
|
return 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* An internal method that handles the Pointer movement event.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#processMoveEvents
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_MOVE
|
|
|
|
* @fires Phaser.Input.Events#POINTER_MOVE
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {integer} The total number of objects interacted with.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
processMoveEvents: function (pointer)
|
|
|
|
{
|
2018-09-12 11:38:08 +00:00
|
|
|
var total = 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
var currentlyOver = this._temp;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
var _eventData = this._eventData;
|
|
|
|
var _eventContainer = this._eventContainer;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
_eventData.cancelled = false;
|
|
|
|
|
|
|
|
var aborted = false;
|
2018-01-20 04:44:54 +00:00
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
// Go through all objects the pointer was over and fire their events / callbacks
|
|
|
|
for (var i = 0; i < currentlyOver.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = currentlyOver[i];
|
|
|
|
|
|
|
|
if (!gameObject.input)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-01-20 04:44:54 +00:00
|
|
|
total++;
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_MOVE, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
this.emit(Events.GAMEOBJECT_MOVE, pointer, gameObject, _eventContainer);
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
if (this.topOnly)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-01-20 04:44:54 +00:00
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
if (!aborted)
|
|
|
|
{
|
2019-01-16 12:13:30 +00:00
|
|
|
this.emit(Events.POINTER_MOVE, pointer, currentlyOver);
|
2018-09-12 11:38:08 +00:00
|
|
|
}
|
|
|
|
|
2018-01-20 04:44:54 +00:00
|
|
|
return total;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* An internal method that handles the Pointer over and out events.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#processOverOutEvents
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2019-01-16 13:12:07 +00:00
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_OVER
|
|
|
|
* @fires Phaser.Input.Events#POINTER_OVER
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_OUT
|
|
|
|
* @fires Phaser.Input.Events#POINTER_OUT
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @return {integer} The total number of objects interacted with.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
processOverOutEvents: function (pointer)
|
|
|
|
{
|
|
|
|
var currentlyOver = this._temp;
|
|
|
|
|
|
|
|
var i;
|
|
|
|
var gameObject;
|
|
|
|
var justOut = [];
|
|
|
|
var justOver = [];
|
|
|
|
var stillOver = [];
|
|
|
|
var previouslyOver = this._over[pointer.id];
|
2018-03-01 02:46:17 +00:00
|
|
|
var currentlyDragging = this._drag[pointer.id];
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
var manager = this.manager;
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
// Go through all objects the pointer was previously over, and see if it still is.
|
|
|
|
// Splits the previouslyOver array into two parts: justOut and stillOver
|
|
|
|
|
|
|
|
for (i = 0; i < previouslyOver.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = previouslyOver[i];
|
|
|
|
|
2018-03-01 02:46:17 +00:00
|
|
|
if (currentlyOver.indexOf(gameObject) === -1 && currentlyDragging.indexOf(gameObject) === -1)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
// Not in the currentlyOver array, so must be outside of this object now
|
|
|
|
justOut.push(gameObject);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// In the currentlyOver array
|
|
|
|
stillOver.push(gameObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Go through all objects the pointer is currently over (the hit test results)
|
|
|
|
// and if not in the previouslyOver array we know it's a new entry, so add to justOver
|
|
|
|
for (i = 0; i < currentlyOver.length; i++)
|
|
|
|
{
|
|
|
|
gameObject = currentlyOver[i];
|
|
|
|
|
|
|
|
// Is this newly over?
|
|
|
|
|
|
|
|
if (previouslyOver.indexOf(gameObject) === -1)
|
|
|
|
{
|
|
|
|
justOver.push(gameObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// By this point the arrays are filled, so now we can process what happened...
|
|
|
|
|
|
|
|
// Process the Just Out objects
|
|
|
|
var total = justOut.length;
|
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
var totalInteracted = 0;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
var _eventData = this._eventData;
|
|
|
|
var _eventContainer = this._eventContainer;
|
|
|
|
|
|
|
|
_eventData.cancelled = false;
|
|
|
|
|
|
|
|
var aborted = false;
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
if (total > 0)
|
|
|
|
{
|
|
|
|
this.sortGameObjects(justOut);
|
|
|
|
|
|
|
|
// Call onOut for everything in the justOut array
|
|
|
|
for (i = 0; i < total; i++)
|
|
|
|
{
|
|
|
|
gameObject = justOut[i];
|
|
|
|
|
|
|
|
if (!gameObject.input)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer);
|
2018-03-16 14:57:19 +00:00
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
manager.resetCursor(gameObject.input);
|
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
totalInteracted++;
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer);
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aborted)
|
|
|
|
{
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.POINTER_OUT, pointer, justOut);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the Just Over objects
|
|
|
|
total = justOver.length;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
_eventData.cancelled = false;
|
|
|
|
|
|
|
|
aborted = false;
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
if (total > 0)
|
|
|
|
{
|
|
|
|
this.sortGameObjects(justOver);
|
|
|
|
|
|
|
|
// Call onOver for everything in the justOver array
|
|
|
|
for (i = 0; i < total; i++)
|
|
|
|
{
|
|
|
|
gameObject = justOver[i];
|
|
|
|
|
|
|
|
if (!gameObject.input)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
|
2018-03-16 14:57:19 +00:00
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
manager.setCursor(gameObject.input);
|
2018-06-08 18:04:12 +00:00
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
totalInteracted++;
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer);
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aborted)
|
|
|
|
{
|
2019-01-16 13:12:07 +00:00
|
|
|
this.emit(Events.POINTER_OVER, pointer, justOver);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the contents of justOver to the previously over array
|
|
|
|
previouslyOver = stillOver.concat(justOver);
|
|
|
|
|
|
|
|
// Then sort it into display list order
|
|
|
|
this._over[pointer.id] = this.sortGameObjects(previouslyOver);
|
2018-01-20 04:44:54 +00:00
|
|
|
|
2018-03-16 14:57:19 +00:00
|
|
|
return totalInteracted;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* An internal method that handles the Pointer up events.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#processUpEvents
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_UP
|
|
|
|
* @fires Phaser.Input.Events#GAMEOBJECT_UP
|
|
|
|
* @fires Phaser.Input.Events#POINTER_UP
|
|
|
|
* @fires Phaser.Input.Events#POINTER_UP_OUTSIDE
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
|
|
|
|
*
|
|
|
|
* @return {integer} The total number of objects interacted with.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
processUpEvents: function (pointer)
|
|
|
|
{
|
|
|
|
var currentlyOver = this._temp;
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
var _eventData = this._eventData;
|
|
|
|
var _eventContainer = this._eventContainer;
|
|
|
|
|
|
|
|
_eventData.cancelled = false;
|
|
|
|
|
|
|
|
var aborted = false;
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
// Go through all objects the pointer was over and fire their events / callbacks
|
|
|
|
for (var i = 0; i < currentlyOver.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = currentlyOver[i];
|
|
|
|
|
|
|
|
if (!gameObject.input)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_UP, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2019-02-08 14:33:25 +00:00
|
|
|
// Clear over and emit 'pointerout' on touch.
|
|
|
|
if (pointer.wasTouch)
|
|
|
|
{
|
|
|
|
this._over[pointer.id] = [];
|
|
|
|
|
|
|
|
gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
|
|
|
|
}
|
|
|
|
|
2018-09-12 11:38:08 +00:00
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-16 12:13:30 +00:00
|
|
|
this.emit(Events.GAMEOBJECT_UP, pointer, gameObject, _eventContainer);
|
2018-09-12 11:38:08 +00:00
|
|
|
|
|
|
|
if (_eventData.cancelled)
|
|
|
|
{
|
|
|
|
aborted = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-29 13:44:42 +00:00
|
|
|
// If they released outside the canvas, but pressed down inside it, we'll still dispatch the event.
|
2018-09-12 11:38:08 +00:00
|
|
|
if (!aborted)
|
|
|
|
{
|
2019-01-16 12:13:30 +00:00
|
|
|
if (pointer.upElement === this.manager.game.canvas)
|
|
|
|
{
|
|
|
|
this.emit(Events.POINTER_UP, pointer, currentlyOver);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.emit(Events.POINTER_UP_OUTSIDE, pointer);
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-03-05 21:49:00 +00:00
|
|
|
|
|
|
|
return currentlyOver.length;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Queues a Game Object for insertion into this Input Plugin on the next update.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#queueForInsertion
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to add.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
queueForInsertion: function (child)
|
|
|
|
{
|
|
|
|
if (this._pendingInsertion.indexOf(child) === -1 && this._list.indexOf(child) === -1)
|
|
|
|
{
|
|
|
|
this._pendingInsertion.push(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Queues a Game Object for removal from this Input Plugin on the next update.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#queueForRemoval
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to remove.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
queueForRemoval: function (child)
|
|
|
|
{
|
|
|
|
this._pendingRemoval.push(child);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the draggable state of the given array of Game Objects.
|
|
|
|
*
|
|
|
|
* They can either be set to be draggable, or can have their draggable state removed by passing `false`.
|
|
|
|
*
|
|
|
|
* A Game Object will not fire drag events unless it has been specifically enabled for drag.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setDraggable
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to change the draggable state on.
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {boolean} [value=true] - Set to `true` if the Game Objects should be made draggable, `false` if they should be unset.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setDraggable: function (gameObjects, value)
|
|
|
|
{
|
|
|
|
if (value === undefined) { value = true; }
|
|
|
|
|
|
|
|
if (!Array.isArray(gameObjects))
|
|
|
|
{
|
|
|
|
gameObjects = [ gameObjects ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < gameObjects.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = gameObjects[i];
|
|
|
|
|
|
|
|
gameObject.input.draggable = value;
|
|
|
|
|
|
|
|
var index = this._draggable.indexOf(gameObject);
|
|
|
|
|
|
|
|
if (value && index === -1)
|
|
|
|
{
|
|
|
|
this._draggable.push(gameObject);
|
|
|
|
}
|
|
|
|
else if (!value && index > -1)
|
|
|
|
{
|
|
|
|
this._draggable.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-06-08 16:50:47 +00:00
|
|
|
/**
|
|
|
|
* Creates a function that can be passed to `setInteractive`, `enable` or `setHitArea` that will handle
|
|
|
|
* pixel-perfect input detection on an Image or Sprite based Game Object, or any custom class that extends them.
|
|
|
|
*
|
|
|
|
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 1.
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 150.
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect(150));
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* Once you have made an Interactive Object pixel perfect it impacts all input related events for it: down, up,
|
|
|
|
* dragstart, drag, etc.
|
|
|
|
*
|
|
|
|
* As a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from
|
|
|
|
* the given coordinates and checking its color values. This is an expensive process, so should only be enabled on
|
|
|
|
* Game Objects that really need it.
|
|
|
|
*
|
|
|
|
* You cannot make non-texture based Game Objects pixel perfect. So this will not work on Graphics, BitmapText,
|
|
|
|
* Render Textures, Text, Tilemaps, Containers or Particles.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#makePixelPerfect
|
|
|
|
* @since 3.10.0
|
|
|
|
*
|
|
|
|
* @param {integer} [alphaTolerance=1] - The alpha level that the pixel should be above to be included as a successful interaction.
|
|
|
|
*
|
|
|
|
* @return {function} A Pixel Perfect Handler for use as a hitArea shape callback.
|
|
|
|
*/
|
|
|
|
makePixelPerfect: function (alphaTolerance)
|
|
|
|
{
|
|
|
|
if (alphaTolerance === undefined) { alphaTolerance = 1; }
|
|
|
|
|
|
|
|
var textureManager = this.systems.textures;
|
|
|
|
|
|
|
|
return CreatePixelPerfectHandler(textureManager, alphaTolerance);
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for the given array of Game Objects.
|
|
|
|
*
|
|
|
|
* A hit area is typically one of the geometric shapes Phaser provides, such as a `Phaser.Geom.Rectangle`
|
|
|
|
* or `Phaser.Geom.Circle`. However, it can be any object as long as it works with the provided callback.
|
|
|
|
*
|
|
|
|
* If no hit area is provided a Rectangle is created based on the size of the Game Object, if possible
|
|
|
|
* to calculate.
|
|
|
|
*
|
|
|
|
* The hit area callback is the function that takes an `x` and `y` coordinate and returns a boolean if
|
|
|
|
* those values fall within the area of the shape or not. All of the Phaser geometry objects provide this,
|
|
|
|
* such as `Phaser.Geom.Rectangle.Contains`.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitArea
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set the hit area on.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {(Phaser.Input.Types.InputConfiguration|any)} [shape] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used.
|
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The 'contains' function to invoke to check if the pointer is within the hit area.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitArea: function (gameObjects, shape, callback)
|
|
|
|
{
|
|
|
|
if (shape === undefined)
|
|
|
|
{
|
|
|
|
return this.setHitAreaFromTexture(gameObjects);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Array.isArray(gameObjects))
|
|
|
|
{
|
|
|
|
gameObjects = [ gameObjects ];
|
|
|
|
}
|
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
var draggable = false;
|
|
|
|
var dropZone = false;
|
|
|
|
var cursor = false;
|
2018-06-11 13:42:50 +00:00
|
|
|
var useHandCursor = false;
|
2018-06-11 10:35:31 +00:00
|
|
|
|
|
|
|
// Config object?
|
|
|
|
if (IsPlainObject(shape))
|
|
|
|
{
|
|
|
|
var config = shape;
|
|
|
|
|
|
|
|
shape = GetFastValue(config, 'hitArea', null);
|
|
|
|
callback = GetFastValue(config, 'hitAreaCallback', null);
|
|
|
|
draggable = GetFastValue(config, 'draggable', false);
|
|
|
|
dropZone = GetFastValue(config, 'dropZone', false);
|
|
|
|
cursor = GetFastValue(config, 'cursor', false);
|
2018-06-11 10:50:37 +00:00
|
|
|
useHandCursor = GetFastValue(config, 'useHandCursor', false);
|
2018-06-11 13:42:50 +00:00
|
|
|
|
|
|
|
var pixelPerfect = GetFastValue(config, 'pixelPerfect', false);
|
|
|
|
var alphaTolerance = GetFastValue(config, 'alphaTolerance', 1);
|
2018-06-11 10:35:31 +00:00
|
|
|
|
|
|
|
if (pixelPerfect)
|
|
|
|
{
|
|
|
|
shape = {};
|
|
|
|
callback = this.makePixelPerfect(alphaTolerance);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Still no hitArea or callback?
|
|
|
|
if (!shape || !callback)
|
|
|
|
{
|
|
|
|
this.setHitAreaFromTexture(gameObjects);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (typeof shape === 'function' && !callback)
|
2018-06-08 16:50:47 +00:00
|
|
|
{
|
|
|
|
callback = shape;
|
|
|
|
shape = {};
|
|
|
|
}
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
for (var i = 0; i < gameObjects.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = gameObjects[i];
|
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
var io = (!gameObject.input) ? CreateInteractiveObject(gameObject, shape, callback) : gameObject.input;
|
|
|
|
|
|
|
|
io.dropZone = dropZone;
|
2018-06-11 10:50:37 +00:00
|
|
|
io.cursor = (useHandCursor) ? 'pointer' : cursor;
|
2018-06-11 10:35:31 +00:00
|
|
|
|
|
|
|
gameObject.input = io;
|
|
|
|
|
|
|
|
if (draggable)
|
|
|
|
{
|
|
|
|
this.setDraggable(gameObject);
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
this.queueForInsertion(gameObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Circle` shape, using
|
|
|
|
* the given coordinates and radius to control its position and size.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitAreaCircle
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a circle hit area.
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {number} x - The center of the circle.
|
|
|
|
* @param {number} y - The center of the circle.
|
|
|
|
* @param {number} radius - The radius of the circle.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Circle.Contains.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitAreaCircle: function (gameObjects, x, y, radius, callback)
|
|
|
|
{
|
|
|
|
if (callback === undefined) { callback = CircleContains; }
|
|
|
|
|
|
|
|
var shape = new Circle(x, y, radius);
|
|
|
|
|
|
|
|
return this.setHitArea(gameObjects, shape, callback);
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Ellipse` shape, using
|
|
|
|
* the given coordinates and dimensions to control its position and size.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitAreaEllipse
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area.
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {number} x - The center of the ellipse.
|
|
|
|
* @param {number} y - The center of the ellipse.
|
|
|
|
* @param {number} width - The width of the ellipse.
|
|
|
|
* @param {number} height - The height of the ellipse.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Ellipse.Contains.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitAreaEllipse: function (gameObjects, x, y, width, height, callback)
|
|
|
|
{
|
|
|
|
if (callback === undefined) { callback = EllipseContains; }
|
|
|
|
|
|
|
|
var shape = new Ellipse(x, y, width, height);
|
|
|
|
|
|
|
|
return this.setHitArea(gameObjects, shape, callback);
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using
|
|
|
|
* the Game Objects texture frame to define the position and size of the hit area.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitAreaFromTexture
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitAreaFromTexture: function (gameObjects, callback)
|
|
|
|
{
|
|
|
|
if (callback === undefined) { callback = RectangleContains; }
|
|
|
|
|
|
|
|
if (!Array.isArray(gameObjects))
|
|
|
|
{
|
|
|
|
gameObjects = [ gameObjects ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < gameObjects.length; i++)
|
|
|
|
{
|
|
|
|
var gameObject = gameObjects[i];
|
2018-04-11 10:25:31 +00:00
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
var frame = gameObject.frame;
|
|
|
|
|
|
|
|
var width = 0;
|
|
|
|
var height = 0;
|
|
|
|
|
2018-11-12 23:19:49 +00:00
|
|
|
if (gameObject.width)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
|
|
|
width = gameObject.width;
|
|
|
|
height = gameObject.height;
|
|
|
|
}
|
2018-11-12 23:19:49 +00:00
|
|
|
else if (frame)
|
|
|
|
{
|
|
|
|
width = frame.realWidth;
|
|
|
|
height = frame.realHeight;
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-05-18 11:48:12 +00:00
|
|
|
if (gameObject.type === 'Container' && (width === 0 || height === 0))
|
|
|
|
{
|
2018-11-12 23:19:49 +00:00
|
|
|
console.warn('Container.setInteractive must specify a Shape or call setSize() first');
|
2018-05-18 11:48:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-01-16 16:00:37 +00:00
|
|
|
if (width !== 0 && height !== 0)
|
|
|
|
{
|
2018-03-28 14:03:54 +00:00
|
|
|
gameObject.input = CreateInteractiveObject(gameObject, new Rectangle(0, 0, width, height), callback);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
|
|
|
this.queueForInsertion(gameObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using
|
|
|
|
* the given coordinates and dimensions to control its position and size.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitAreaRectangle
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a rectangular hit area.
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {number} x - The top-left of the rectangle.
|
|
|
|
* @param {number} y - The top-left of the rectangle.
|
|
|
|
* @param {number} width - The width of the rectangle.
|
|
|
|
* @param {number} height - The height of the rectangle.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitAreaRectangle: function (gameObjects, x, y, width, height, callback)
|
|
|
|
{
|
|
|
|
if (callback === undefined) { callback = RectangleContains; }
|
|
|
|
|
|
|
|
var shape = new Rectangle(x, y, width, height);
|
|
|
|
|
|
|
|
return this.setHitArea(gameObjects, shape, callback);
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Triangle` shape, using
|
|
|
|
* the given coordinates to control the position of its points.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setHitAreaTriangle
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a triangular hit area.
|
2018-03-19 13:22:30 +00:00
|
|
|
* @param {number} x1 - The x coordinate of the first point of the triangle.
|
|
|
|
* @param {number} y1 - The y coordinate of the first point of the triangle.
|
|
|
|
* @param {number} x2 - The x coordinate of the second point of the triangle.
|
|
|
|
* @param {number} y2 - The y coordinate of the second point of the triangle.
|
|
|
|
* @param {number} x3 - The x coordinate of the third point of the triangle.
|
|
|
|
* @param {number} y3 - The y coordinate of the third point of the triangle.
|
2019-02-13 14:17:36 +00:00
|
|
|
* @param {Phaser.Input.Types.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Triangle.Contains.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setHitAreaTriangle: function (gameObjects, x1, y1, x2, y2, x3, y3, callback)
|
|
|
|
{
|
|
|
|
if (callback === undefined) { callback = TriangleContains; }
|
|
|
|
|
|
|
|
var shape = new Triangle(x1, y1, x2, y2, x3, y3);
|
|
|
|
|
|
|
|
return this.setHitArea(gameObjects, shape, callback);
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the Pointers to always poll.
|
|
|
|
*
|
|
|
|
* When a pointer is polled it runs a hit test to see which Game Objects are currently below it,
|
|
|
|
* or being interacted with it, regardless if the Pointer has actually moved or not.
|
|
|
|
*
|
|
|
|
* You should enable this if you want objects in your game to fire over / out events, and the objects
|
|
|
|
* are constantly moving, but the pointer may not have. Polling every frame has additional computation
|
|
|
|
* costs, especially if there are a large number of interactive objects in your game.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setPollAlways
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setPollAlways: function ()
|
|
|
|
{
|
|
|
|
this.pollRate = 0;
|
|
|
|
this._pollTimer = 0;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the Pointers to only poll when they are moved or updated.
|
|
|
|
*
|
|
|
|
* When a pointer is polled it runs a hit test to see which Game Objects are currently below it,
|
|
|
|
* or being interacted with it.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setPollOnMove
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setPollOnMove: function ()
|
|
|
|
{
|
|
|
|
this.pollRate = -1;
|
|
|
|
this._pollTimer = 0;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Sets the poll rate value. This is the amount of time that should have elapsed before a pointer
|
|
|
|
* will be polled again. See the `setPollAlways` and `setPollOnMove` methods.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setPollRate
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {number} value - The amount of time, in ms, that should elapsed before re-polling the pointers.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setPollRate: function (value)
|
|
|
|
{
|
|
|
|
this.pollRate = value;
|
|
|
|
this._pollTimer = 0;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* When set to `true` the global Input Manager will emulate DOM behavior by only emitting events from
|
2019-04-16 16:08:12 +00:00
|
|
|
* the top-most Scene in the Scene List. By default, if a Scene receives an input event it will then stop the event
|
|
|
|
* from flowing down to any Scenes below it in the Scene list. To disable this behavior call this method with `false`.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setGlobalTopOnly
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2019-04-16 16:08:12 +00:00
|
|
|
* @param {boolean} value - Set to `true` to stop processing input events on the Scene that receives it, or `false` to let the event continue down the Scene list.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-20 04:44:54 +00:00
|
|
|
setGlobalTopOnly: function (value)
|
|
|
|
{
|
|
|
|
this.manager.globalTopOnly = value;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* When set to `true` this Input Plugin will emulate DOM behavior by only emitting events from
|
|
|
|
* the top-most Game Objects in the Display List.
|
|
|
|
*
|
|
|
|
* If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#setTopOnly
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {boolean} value - `true` to only include the top-most Game Object, or `false` to include all Game Objects in a hit test.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
setTopOnly: function (value)
|
|
|
|
{
|
|
|
|
this.topOnly = value;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Given an array of Game Objects, sort the array and return it, so that the objects are in depth index order
|
|
|
|
* with the lowest at the bottom.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#sortGameObjects
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
sortGameObjects: function (gameObjects)
|
|
|
|
{
|
|
|
|
if (gameObjects.length < 2)
|
|
|
|
{
|
|
|
|
return gameObjects;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.scene.sys.depthSort();
|
|
|
|
|
|
|
|
return gameObjects.sort(this.sortHandlerGO.bind(this));
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* Return the child lowest down the display list (with the smallest index)
|
2018-04-12 01:11:40 +00:00
|
|
|
* Will iterate through all parent containers, if present.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#sortHandlerGO
|
2018-06-04 14:19:25 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-04-12 01:11:40 +00:00
|
|
|
* @param {Phaser.GameObjects.GameObject} childA - The first Game Object to compare.
|
|
|
|
* @param {Phaser.GameObjects.GameObject} childB - The second Game Object to compare.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
2018-04-12 01:11:40 +00:00
|
|
|
* @return {integer} Returns either a negative or positive integer, or zero if they match.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-16 16:00:37 +00:00
|
|
|
sortHandlerGO: function (childA, childB)
|
|
|
|
{
|
2018-04-12 01:11:40 +00:00
|
|
|
if (!childA.parentContainer && !childB.parentContainer)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-04-12 01:11:40 +00:00
|
|
|
// Quick bail out when neither child has a container
|
|
|
|
return this.displayList.getIndex(childB) - this.displayList.getIndex(childA);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-04-12 01:11:40 +00:00
|
|
|
else if (childA.parentContainer === childB.parentContainer)
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-04-12 01:11:40 +00:00
|
|
|
// Quick bail out when both children have the same container
|
|
|
|
return childB.parentContainer.getIndex(childB) - childA.parentContainer.getIndex(childA);
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
2018-05-18 11:48:12 +00:00
|
|
|
else if (childA.parentContainer === childB)
|
|
|
|
{
|
|
|
|
// Quick bail out when childA is a child of childB
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (childB.parentContainer === childA)
|
|
|
|
{
|
|
|
|
// Quick bail out when childA is a child of childB
|
|
|
|
return 1;
|
|
|
|
}
|
2018-04-12 01:11:40 +00:00
|
|
|
else
|
2018-01-16 16:00:37 +00:00
|
|
|
{
|
2018-04-12 01:11:40 +00:00
|
|
|
// Container index check
|
|
|
|
var listA = childA.getIndexList();
|
|
|
|
var listB = childB.getIndexList();
|
|
|
|
var len = Math.min(listA.length, listB.length);
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-04-12 01:11:40 +00:00
|
|
|
for (var i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
var indexA = listA[i];
|
|
|
|
var indexB = listB[i];
|
2018-01-16 16:00:37 +00:00
|
|
|
|
2018-04-12 01:11:40 +00:00
|
|
|
if (indexA === indexB)
|
|
|
|
{
|
|
|
|
// Go to the next level down
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Non-matching parents, so return
|
|
|
|
return indexB - indexA;
|
|
|
|
}
|
|
|
|
}
|
2018-01-16 16:00:37 +00:00
|
|
|
}
|
|
|
|
|
2018-04-12 01:11:40 +00:00
|
|
|
// Technically this shouldn't happen, but ...
|
|
|
|
return 0;
|
2018-01-16 16:00:37 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-06-04 14:19:25 +00:00
|
|
|
* Causes the Input Manager to stop emitting any events for the remainder of this game step.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#stopPropagation
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 13:22:30 +00:00
|
|
|
* @return {Phaser.Input.InputPlugin} This InputPlugin object.
|
2018-01-26 06:55:15 +00:00
|
|
|
*/
|
2018-01-20 04:44:54 +00:00
|
|
|
stopPropagation: function ()
|
|
|
|
{
|
|
|
|
if (this.manager.globalTopOnly)
|
|
|
|
{
|
|
|
|
this.manager.ignoreEvents = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-06-04 12:23:51 +00:00
|
|
|
/**
|
2019-01-23 15:51:42 +00:00
|
|
|
* **Note:** As of Phaser 3.16 this method is no longer required _unless_ you have set `input.queue = true`
|
|
|
|
* in your game config, to force it to use the legacy event queue system. This method is deprecated and
|
|
|
|
* will be removed in a future version.
|
|
|
|
*
|
2018-06-04 12:23:51 +00:00
|
|
|
* Adds a callback to be invoked whenever the native DOM `mouseup` or `touchend` events are received.
|
|
|
|
* By setting the `isOnce` argument you can control if the callback is called once,
|
|
|
|
* or every time the DOM event occurs.
|
|
|
|
*
|
|
|
|
* Callbacks passed to this method are invoked _immediately_ when the DOM event happens,
|
|
|
|
* within the scope of the DOM event handler. Therefore, they are considered as 'native'
|
|
|
|
* from the perspective of the browser. This means they can be used for tasks such as
|
|
|
|
* opening new browser windows, or anything which explicitly requires user input to activate.
|
|
|
|
* However, as a result of this, they come with their own risks, and as such should not be used
|
|
|
|
* for general game input, but instead be reserved for special circumstances.
|
|
|
|
*
|
|
|
|
* If all you're trying to do is execute a callback when a pointer is released, then
|
|
|
|
* please use the internal Input event system instead.
|
|
|
|
*
|
|
|
|
* Please understand that these callbacks are invoked when the browser feels like doing so,
|
|
|
|
* which may be entirely out of the normal flow of the Phaser Game Loop. Therefore, you should absolutely keep
|
|
|
|
* Phaser related operations to a minimum in these callbacks. For example, don't destroy Game Objects,
|
|
|
|
* change Scenes or manipulate internal systems, otherwise you run a very real risk of creating
|
|
|
|
* heisenbugs (https://en.wikipedia.org/wiki/Heisenbug) that prove a challenge to reproduce, never mind
|
|
|
|
* solve.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#addUpCallback
|
2019-01-23 15:51:42 +00:00
|
|
|
* @deprecated
|
2018-06-04 12:23:51 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*
|
2018-06-04 14:19:25 +00:00
|
|
|
* @param {function} callback - The callback to be invoked on this DOM event.
|
2018-06-04 12:23:51 +00:00
|
|
|
* @param {boolean} [isOnce=true] - `true` if the callback will only be invoked once, `false` to call every time this event happens.
|
|
|
|
*
|
|
|
|
* @return {this} The Input Plugin.
|
|
|
|
*/
|
2018-05-29 23:33:28 +00:00
|
|
|
addUpCallback: function (callback, isOnce)
|
|
|
|
{
|
|
|
|
this.manager.addUpCallback(callback, isOnce);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-06-04 12:23:51 +00:00
|
|
|
/**
|
2019-01-23 15:51:42 +00:00
|
|
|
* **Note:** As of Phaser 3.16 this method is no longer required _unless_ you have set `input.queue = true`
|
|
|
|
* in your game config, to force it to use the legacy event queue system. This method is deprecated and
|
|
|
|
* will be removed in a future version.
|
|
|
|
*
|
2018-06-04 12:23:51 +00:00
|
|
|
* Adds a callback to be invoked whenever the native DOM `mousedown` or `touchstart` events are received.
|
|
|
|
* By setting the `isOnce` argument you can control if the callback is called once,
|
|
|
|
* or every time the DOM event occurs.
|
|
|
|
*
|
|
|
|
* Callbacks passed to this method are invoked _immediately_ when the DOM event happens,
|
|
|
|
* within the scope of the DOM event handler. Therefore, they are considered as 'native'
|
|
|
|
* from the perspective of the browser. This means they can be used for tasks such as
|
|
|
|
* opening new browser windows, or anything which explicitly requires user input to activate.
|
|
|
|
* However, as a result of this, they come with their own risks, and as such should not be used
|
|
|
|
* for general game input, but instead be reserved for special circumstances.
|
|
|
|
*
|
|
|
|
* If all you're trying to do is execute a callback when a pointer is down, then
|
|
|
|
* please use the internal Input event system instead.
|
|
|
|
*
|
|
|
|
* Please understand that these callbacks are invoked when the browser feels like doing so,
|
|
|
|
* which may be entirely out of the normal flow of the Phaser Game Loop. Therefore, you should absolutely keep
|
|
|
|
* Phaser related operations to a minimum in these callbacks. For example, don't destroy Game Objects,
|
|
|
|
* change Scenes or manipulate internal systems, otherwise you run a very real risk of creating
|
|
|
|
* heisenbugs (https://en.wikipedia.org/wiki/Heisenbug) that prove a challenge to reproduce, never mind
|
|
|
|
* solve.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#addDownCallback
|
2019-01-23 15:51:42 +00:00
|
|
|
* @deprecated
|
2018-06-04 12:23:51 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*
|
|
|
|
* @param {function} callback - The callback to be invoked on this dom event.
|
|
|
|
* @param {boolean} [isOnce=true] - `true` if the callback will only be invoked once, `false` to call every time this event happens.
|
|
|
|
*
|
|
|
|
* @return {this} The Input Plugin.
|
|
|
|
*/
|
2018-05-29 23:33:28 +00:00
|
|
|
addDownCallback: function (callback, isOnce)
|
|
|
|
{
|
|
|
|
this.manager.addDownCallback(callback, isOnce);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-06-04 12:23:51 +00:00
|
|
|
/**
|
2019-01-23 15:51:42 +00:00
|
|
|
* **Note:** As of Phaser 3.16 this method is no longer required _unless_ you have set `input.queue = true`
|
|
|
|
* in your game config, to force it to use the legacy event queue system. This method is deprecated and
|
|
|
|
* will be removed in a future version.
|
|
|
|
*
|
2018-06-04 12:23:51 +00:00
|
|
|
* Adds a callback to be invoked whenever the native DOM `mousemove` or `touchmove` events are received.
|
|
|
|
* By setting the `isOnce` argument you can control if the callback is called once,
|
|
|
|
* or every time the DOM event occurs.
|
|
|
|
*
|
|
|
|
* Callbacks passed to this method are invoked _immediately_ when the DOM event happens,
|
|
|
|
* within the scope of the DOM event handler. Therefore, they are considered as 'native'
|
|
|
|
* from the perspective of the browser. This means they can be used for tasks such as
|
|
|
|
* opening new browser windows, or anything which explicitly requires user input to activate.
|
|
|
|
* However, as a result of this, they come with their own risks, and as such should not be used
|
|
|
|
* for general game input, but instead be reserved for special circumstances.
|
|
|
|
*
|
|
|
|
* If all you're trying to do is execute a callback when a pointer is moved, then
|
|
|
|
* please use the internal Input event system instead.
|
|
|
|
*
|
|
|
|
* Please understand that these callbacks are invoked when the browser feels like doing so,
|
|
|
|
* which may be entirely out of the normal flow of the Phaser Game Loop. Therefore, you should absolutely keep
|
|
|
|
* Phaser related operations to a minimum in these callbacks. For example, don't destroy Game Objects,
|
|
|
|
* change Scenes or manipulate internal systems, otherwise you run a very real risk of creating
|
|
|
|
* heisenbugs (https://en.wikipedia.org/wiki/Heisenbug) that prove a challenge to reproduce, never mind
|
|
|
|
* solve.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#addMoveCallback
|
2019-01-23 15:51:42 +00:00
|
|
|
* @deprecated
|
2018-06-04 12:23:51 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*
|
|
|
|
* @param {function} callback - The callback to be invoked on this dom event.
|
|
|
|
* @param {boolean} [isOnce=false] - `true` if the callback will only be invoked once, `false` to call every time this event happens.
|
|
|
|
*
|
|
|
|
* @return {this} The Input Plugin.
|
|
|
|
*/
|
2018-05-29 23:33:28 +00:00
|
|
|
addMoveCallback: function (callback, isOnce)
|
|
|
|
{
|
|
|
|
this.manager.addMoveCallback(callback, isOnce);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
/**
|
|
|
|
* Adds new Pointer objects to the Input Manager.
|
|
|
|
*
|
|
|
|
* By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`.
|
|
|
|
*
|
|
|
|
* You can create more either by calling this method, or by setting the `input.activePointers` property
|
2018-06-11 12:39:28 +00:00
|
|
|
* in the Game Config, up to a maximum of 10 pointers.
|
2018-06-08 14:16:35 +00:00
|
|
|
*
|
|
|
|
* The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added
|
|
|
|
* via this method.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#addPointer
|
|
|
|
* @since 3.10.0
|
|
|
|
*
|
2018-06-11 12:39:28 +00:00
|
|
|
* @param {integer} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total.
|
2018-06-08 14:16:35 +00:00
|
|
|
*
|
|
|
|
* @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created.
|
|
|
|
*/
|
|
|
|
addPointer: function (quantity)
|
|
|
|
{
|
|
|
|
return this.manager.addPointer(quantity);
|
|
|
|
},
|
|
|
|
|
2018-06-11 10:35:31 +00:00
|
|
|
/**
|
|
|
|
* Tells the Input system to set a custom cursor.
|
|
|
|
*
|
|
|
|
* This cursor will be the default cursor used when interacting with the game canvas.
|
|
|
|
*
|
|
|
|
* If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use.
|
|
|
|
*
|
2018-06-11 10:50:37 +00:00
|
|
|
* Any valid CSS cursor value is allowed, including paths to image files, i.e.:
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer');
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* Please read about the differences between browsers when it comes to the file formats and sizes they support:
|
2018-06-11 10:35:31 +00:00
|
|
|
*
|
|
|
|
* https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
|
|
|
|
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property
|
|
|
|
*
|
|
|
|
* It's up to you to pick a suitable cursor format that works across the range of browsers you need to support.
|
|
|
|
*
|
2018-06-11 10:50:37 +00:00
|
|
|
* @method Phaser.Input.InputPlugin#setDefaultCursor
|
2018-06-11 10:35:31 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*
|
|
|
|
* @param {string} cursor - The CSS to be used when setting the default cursor.
|
|
|
|
*
|
|
|
|
* @return {Phaser.Input.InputPlugin} This Input instance.
|
|
|
|
*/
|
|
|
|
setDefaultCursor: function (cursor)
|
|
|
|
{
|
|
|
|
this.manager.setDefaultCursor(cursor);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-04-14 03:23:11 +00:00
|
|
|
/**
|
|
|
|
* The Scene that owns this plugin is transitioning in.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#transitionIn
|
|
|
|
* @private
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-04-14 03:23:11 +00:00
|
|
|
*/
|
|
|
|
transitionIn: function ()
|
|
|
|
{
|
|
|
|
this.enabled = this.settings.transitionAllowInput;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Scene that owns this plugin has finished transitioning in.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#transitionComplete
|
|
|
|
* @private
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-04-14 03:23:11 +00:00
|
|
|
*/
|
|
|
|
transitionComplete: function ()
|
|
|
|
{
|
|
|
|
if (!this.settings.transitionAllowInput)
|
|
|
|
{
|
|
|
|
this.enabled = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Scene that owns this plugin is transitioning out.
|
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#transitionOut
|
|
|
|
* @private
|
2018-04-15 11:44:47 +00:00
|
|
|
* @since 3.5.0
|
2018-04-14 03:23:11 +00:00
|
|
|
*/
|
|
|
|
transitionOut: function ()
|
|
|
|
{
|
|
|
|
this.enabled = this.settings.transitionAllowInput;
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
|
|
|
* The Scene that owns this plugin is shutting down.
|
2018-04-13 16:12:17 +00:00
|
|
|
* We need to kill and reset all internal properties as well as stop listening to Scene events.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#shutdown
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#SHUTDOWN
|
2018-04-13 16:12:17 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
shutdown: function ()
|
|
|
|
{
|
2018-06-08 14:16:35 +00:00
|
|
|
// Registered input plugins listen for this
|
2019-01-16 12:13:30 +00:00
|
|
|
this.pluginEvents.emit(Events.SHUTDOWN);
|
2018-06-08 14:16:35 +00:00
|
|
|
|
2017-07-25 03:10:50 +00:00
|
|
|
this._temp.length = 0;
|
|
|
|
this._list.length = 0;
|
2017-07-27 02:40:58 +00:00
|
|
|
this._draggable.length = 0;
|
2017-07-25 03:10:50 +00:00
|
|
|
this._pendingRemoval.length = 0;
|
|
|
|
this._pendingInsertion.length = 0;
|
2019-01-04 16:34:59 +00:00
|
|
|
this._dragState.length = 0;
|
2017-07-24 16:10:30 +00:00
|
|
|
|
|
|
|
for (var i = 0; i < 10; i++)
|
|
|
|
{
|
2017-07-27 02:40:58 +00:00
|
|
|
this._drag[i] = [];
|
2017-07-25 03:10:50 +00:00
|
|
|
this._over[i] = [];
|
2017-07-24 16:10:30 +00:00
|
|
|
}
|
2018-01-12 17:09:09 +00:00
|
|
|
|
|
|
|
this.removeAllListeners();
|
2018-04-13 16:12:17 +00:00
|
|
|
|
|
|
|
var eventEmitter = this.systems.events;
|
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
eventEmitter.off(SceneEvents.TRANSITION_START, this.transitionIn, this);
|
|
|
|
eventEmitter.off(SceneEvents.TRANSITION_OUT, this.transitionOut, this);
|
|
|
|
eventEmitter.off(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this);
|
2018-04-14 03:23:11 +00:00
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this);
|
2019-01-23 15:51:42 +00:00
|
|
|
|
|
|
|
if (this.manager.useQueue)
|
|
|
|
{
|
|
|
|
eventEmitter.off(SceneEvents.UPDATE, this.update, this);
|
|
|
|
}
|
|
|
|
|
2019-02-10 17:10:13 +00:00
|
|
|
this.manager.events.off(Events.GAME_OUT, this.onGameOut, this);
|
|
|
|
this.manager.events.off(Events.GAME_OVER, this.onGameOver, this);
|
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
|
2017-07-20 16:10:12 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-05-18 17:08:37 +00:00
|
|
|
* The Scene that owns this plugin is being destroyed.
|
2018-04-13 16:12:17 +00:00
|
|
|
* We need to shutdown and then kill off all external references.
|
2018-01-26 06:55:15 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Input.InputPlugin#destroy
|
2019-01-16 12:13:30 +00:00
|
|
|
* @fires Phaser.Input.Events#DESTROY
|
2018-04-13 16:12:17 +00:00
|
|
|
* @private
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-07-20 16:10:12 +00:00
|
|
|
destroy: function ()
|
|
|
|
{
|
|
|
|
this.shutdown();
|
|
|
|
|
2018-06-08 14:16:35 +00:00
|
|
|
// Registered input plugins listen for this
|
2019-01-16 12:13:30 +00:00
|
|
|
this.pluginEvents.emit(Events.DESTROY);
|
2018-06-08 14:16:35 +00:00
|
|
|
|
|
|
|
this.pluginEvents.removeAllListeners();
|
|
|
|
|
2019-01-18 13:41:43 +00:00
|
|
|
this.scene.sys.events.off(SceneEvents.START, this.start, this);
|
2018-04-13 16:12:17 +00:00
|
|
|
|
|
|
|
this.scene = null;
|
|
|
|
this.cameras = null;
|
|
|
|
this.manager = null;
|
|
|
|
this.events = null;
|
|
|
|
this.mouse = null;
|
2018-01-16 22:28:29 +00:00
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-05-29 15:55:52 +00:00
|
|
|
* The x coordinates of the ActivePointer based on the first camera in the camera list.
|
|
|
|
* This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch.
|
2018-03-19 12:43:19 +00:00
|
|
|
*
|
2018-05-29 15:55:52 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#x
|
|
|
|
* @type {number}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-05-29 15:55:52 +00:00
|
|
|
x: {
|
2018-01-16 22:28:29 +00:00
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
2018-05-29 15:55:52 +00:00
|
|
|
return this.manager.activePointer.x;
|
2018-01-16 22:28:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-05-29 15:55:52 +00:00
|
|
|
* The y coordinates of the ActivePointer based on the first camera in the camera list.
|
2018-01-26 06:55:15 +00:00
|
|
|
* This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch.
|
2018-03-19 12:43:19 +00:00
|
|
|
*
|
2018-05-29 15:55:52 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#y
|
2018-02-13 01:13:12 +00:00
|
|
|
* @type {number}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-05-29 15:55:52 +00:00
|
|
|
y: {
|
2018-01-16 22:28:29 +00:00
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
2018-05-29 15:55:52 +00:00
|
|
|
return this.manager.activePointer.y;
|
2018-01-16 22:28:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2018-11-28 13:10:54 +00:00
|
|
|
/**
|
|
|
|
* Are any mouse or touch pointers currently over the game canvas?
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#isOver
|
|
|
|
* @type {boolean}
|
|
|
|
* @readonly
|
|
|
|
* @since 3.16.0
|
|
|
|
*/
|
|
|
|
isOver: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.isOver;
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
/**
|
2018-05-29 15:55:52 +00:00
|
|
|
* The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_.
|
|
|
|
* If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer`
|
|
|
|
* which will always map to the most recently interacted pointer.
|
2018-03-19 12:43:19 +00:00
|
|
|
*
|
2018-05-29 15:55:52 +00:00
|
|
|
* @name Phaser.Input.InputPlugin#mousePointer
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-29 15:55:52 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
mousePointer: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.mousePointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The current active input Pointer.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#activePointer
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-01-26 06:55:15 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2018-05-29 15:55:52 +00:00
|
|
|
activePointer: {
|
2018-01-16 22:28:29 +00:00
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
2018-05-29 15:55:52 +00:00
|
|
|
return this.manager.activePointer;
|
2018-01-16 22:28:29 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 18:28:18 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer1
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer1: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer2
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer2: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer3
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer3: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[3];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer4
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer4: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[4];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer5
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer5: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[5];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer6
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer6: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[6];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer7
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer7: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[7];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer8
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer8: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[8];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer9
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer9: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[9];
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A touch-based Pointer object.
|
|
|
|
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Input.InputPlugin#pointer10
|
|
|
|
* @type {Phaser.Input.Pointer}
|
2018-10-09 12:40:00 +00:00
|
|
|
* @readonly
|
2018-05-25 18:28:18 +00:00
|
|
|
* @since 3.10.0
|
|
|
|
*/
|
|
|
|
pointer10: {
|
|
|
|
|
|
|
|
get: function ()
|
|
|
|
{
|
|
|
|
return this.manager.pointers[10];
|
|
|
|
}
|
|
|
|
|
2018-01-26 06:55:15 +00:00
|
|
|
}
|
2017-07-20 16:10:12 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2018-05-15 11:51:50 +00:00
|
|
|
PluginCache.register('InputPlugin', InputPlugin, 'input');
|
2018-01-16 22:28:29 +00:00
|
|
|
|
2018-01-16 16:14:21 +00:00
|
|
|
module.exports = InputPlugin;
|