2018-04-05 08:23:29 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
|
|
* @author Felipe Alfonso <@bitnenfer>
|
|
|
|
* @copyright 2018 Photon Storm Ltd.
|
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
2018-03-23 17:15:52 +00:00
|
|
|
var Class = require('../../utils/Class');
|
|
|
|
var Components = require('../components');
|
|
|
|
var GameObject = require('../GameObject');
|
2018-04-05 12:52:42 +00:00
|
|
|
var List = require('../../structs/List');
|
2018-03-23 17:15:52 +00:00
|
|
|
var Render = require('./ContainerRender');
|
2018-04-05 08:23:29 +00:00
|
|
|
var Vector2 = require('../../math/Vector2');
|
2018-03-23 17:15:52 +00:00
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
/**
|
|
|
|
* @classdesc
|
|
|
|
* A Container Game Object.
|
|
|
|
*
|
|
|
|
* @class Container
|
|
|
|
* @extends Phaser.GameObjects.GameObject
|
|
|
|
* @memberOf Phaser.GameObjects
|
|
|
|
* @constructor
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @extends Phaser.GameObjects.Components.BlendMode
|
|
|
|
* @extends Phaser.GameObjects.Components.Transform
|
2018-04-05 12:52:42 +00:00
|
|
|
* @extends Phaser.Structs.List
|
2018-04-05 08:23:29 +00:00
|
|
|
*
|
|
|
|
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
|
2018-04-05 12:52:42 +00:00
|
|
|
* @param {number} [x=0] - The horizontal position of this Game Object in the world.
|
|
|
|
* @param {number} [y=0] - The vertical position of this Game Object in the world.
|
|
|
|
* @param {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container.
|
2018-04-05 08:23:29 +00:00
|
|
|
*/
|
2018-03-23 17:15:52 +00:00
|
|
|
var Container = new Class({
|
|
|
|
|
|
|
|
Extends: GameObject,
|
|
|
|
|
|
|
|
Mixins: [
|
2018-04-09 15:32:08 +00:00
|
|
|
Components.Alpha,
|
2018-03-23 17:15:52 +00:00
|
|
|
Components.BlendMode,
|
2018-04-05 15:53:40 +00:00
|
|
|
Components.Depth,
|
2018-03-23 17:15:52 +00:00
|
|
|
Components.Transform,
|
2018-04-05 15:53:40 +00:00
|
|
|
Components.Visible,
|
2018-04-05 12:52:42 +00:00
|
|
|
Render,
|
|
|
|
List
|
2018-03-23 17:15:52 +00:00
|
|
|
],
|
|
|
|
|
|
|
|
initialize:
|
|
|
|
|
2018-04-05 12:52:42 +00:00
|
|
|
function Container (scene, x, y, children)
|
2018-03-23 17:15:52 +00:00
|
|
|
{
|
|
|
|
GameObject.call(this, scene, 'Container');
|
2018-04-05 08:23:29 +00:00
|
|
|
|
|
|
|
/**
|
2018-04-05 12:52:42 +00:00
|
|
|
* The parent property as used by the List methods.
|
2018-04-05 08:23:29 +00:00
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @name Phaser.GameObjects.Container#parent
|
2018-04-05 08:23:29 +00:00
|
|
|
* @type {Phaser.GameObjects.Container}
|
2018-04-05 12:52:42 +00:00
|
|
|
* @private
|
2018-04-05 08:23:29 +00:00
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-04-05 12:52:42 +00:00
|
|
|
this.parent = this;
|
2018-04-05 08:23:29 +00:00
|
|
|
|
|
|
|
/**
|
2018-04-05 12:52:42 +00:00
|
|
|
* An array holding the children of this Container.
|
2018-04-05 08:23:29 +00:00
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @name Phaser.GameObjects.Container#list
|
2018-04-05 08:23:29 +00:00
|
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-04-05 12:52:42 +00:00
|
|
|
this.list = [];
|
|
|
|
|
2018-04-09 16:33:55 +00:00
|
|
|
/**
|
|
|
|
* Does this Container exclusively manage its children?
|
|
|
|
*
|
|
|
|
* The default is `true` which means a child added to this Container cannot
|
|
|
|
* belong in another Container, which includes the Scene display list.
|
|
|
|
*
|
|
|
|
* If you disable this then this Container will no longer exclusively manage its children.
|
|
|
|
* This allows you to create all kinds of interesting graphical effects, such as replicating
|
|
|
|
* Game Objects without reparenting them all over the Scene.
|
|
|
|
* However, doing so will prevent children from receiving any kind of input event or have
|
|
|
|
* their physics bodies work by default, as they're no longer a single entity on the
|
|
|
|
* display list, but are being replicated where-ever this Container is.
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#exclusive
|
|
|
|
* @type {boolean}
|
|
|
|
* @default true
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
this.exclusive = true;
|
|
|
|
|
2018-04-05 12:52:42 +00:00
|
|
|
/**
|
|
|
|
* The cursor position.
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#position
|
|
|
|
* @type {integer}
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
this.position = 0;
|
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#localTransform
|
|
|
|
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-03-23 17:15:52 +00:00
|
|
|
this.localTransform = new Components.TransformMatrix();
|
2018-04-05 08:23:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#tempTransformMatrix
|
|
|
|
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
2018-04-05 12:52:42 +00:00
|
|
|
* @private
|
2018-04-05 08:23:29 +00:00
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-03-28 23:47:57 +00:00
|
|
|
this.tempTransformMatrix = new Components.TransformMatrix();
|
2018-04-05 10:25:22 +00:00
|
|
|
|
2018-04-05 12:52:42 +00:00
|
|
|
/**
|
|
|
|
* A callback that is invoked every time a child is added to this list.
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#addCallback
|
|
|
|
* @type {function}
|
|
|
|
* @private
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-04-10 03:13:38 +00:00
|
|
|
this.addCallback = this.addHandler.bind(this);
|
2018-04-05 12:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A callback that is invoked every time a child is removed from this list.
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#removeCallback
|
|
|
|
* @type {function}
|
|
|
|
* @private
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
2018-04-10 03:13:38 +00:00
|
|
|
this.removeCallback = this.removeHandler.bind(this);
|
2018-04-05 12:52:42 +00:00
|
|
|
|
2018-04-05 14:28:34 +00:00
|
|
|
/**
|
|
|
|
* A reference to the Scene Display List.
|
|
|
|
*
|
|
|
|
* @name Phaser.GameObjects.Container#_displayList
|
|
|
|
* @type {Phaser.GameObjects.DisplayList}
|
|
|
|
* @private
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
this._displayList = scene.sys.displayList;
|
|
|
|
|
2018-04-05 10:25:22 +00:00
|
|
|
this.setPosition(x, y);
|
2018-04-09 15:32:08 +00:00
|
|
|
this.clearAlpha();
|
2018-04-05 12:52:42 +00:00
|
|
|
|
2018-04-10 03:13:38 +00:00
|
|
|
if (children)
|
2018-04-05 12:52:42 +00:00
|
|
|
{
|
2018-04-10 03:13:38 +00:00
|
|
|
this.add(children);
|
2018-04-05 12:52:42 +00:00
|
|
|
}
|
2018-03-23 17:15:52 +00:00
|
|
|
},
|
|
|
|
|
2018-04-09 16:33:55 +00:00
|
|
|
/**
|
|
|
|
* Does this Container exclusively manage its children?
|
|
|
|
*
|
|
|
|
* The default is `true` which means a child added to this Container cannot
|
|
|
|
* belong in another Container, which includes the Scene display list.
|
|
|
|
*
|
|
|
|
* If you disable this then this Container will no longer exclusively manage its children.
|
|
|
|
* This allows you to create all kinds of interesting graphical effects, such as replicating
|
|
|
|
* Game Objects without reparenting them all over the Scene.
|
|
|
|
* However, doing so will prevent children from receiving any kind of input event or have
|
|
|
|
* their physics bodies work by default, as they're no longer a single entity on the
|
|
|
|
* display list, but are being replicated where-ever this Container is.
|
|
|
|
*
|
|
|
|
* @method Phaser.GameObjects.Container#setExclusive
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @param {boolean} [value=true] - The exclusive state of this Container.
|
|
|
|
*
|
|
|
|
* @return {Phaser.GameObjects.Container} This Container.
|
|
|
|
*/
|
|
|
|
setExclusive: function (value)
|
|
|
|
{
|
|
|
|
if (value === undefined) { value = true; }
|
|
|
|
|
|
|
|
this.exclusive = value;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
/**
|
2018-04-05 12:52:42 +00:00
|
|
|
* Internal add handler.
|
2018-04-05 08:23:29 +00:00
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @method Phaser.GameObjects.Container#addHandler
|
|
|
|
* @private
|
2018-04-05 08:23:29 +00:00
|
|
|
* @since 3.4.0
|
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @param {Phaser.GameObjects.Container} list - The List the Game Object was added to (also this Container)
|
|
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container.
|
2018-04-05 08:23:29 +00:00
|
|
|
*/
|
2018-04-10 03:13:38 +00:00
|
|
|
addHandler: function (gameObject)
|
2018-03-23 17:15:52 +00:00
|
|
|
{
|
2018-04-05 12:52:42 +00:00
|
|
|
gameObject.on('destroy', this.remove, this);
|
2018-04-05 08:23:29 +00:00
|
|
|
|
2018-04-09 16:33:55 +00:00
|
|
|
if (this.exclusive)
|
2018-03-23 17:15:52 +00:00
|
|
|
{
|
2018-04-09 16:33:55 +00:00
|
|
|
this._displayList.remove(gameObject);
|
|
|
|
|
|
|
|
if (gameObject.parentContainer)
|
|
|
|
{
|
|
|
|
gameObject.parentContainer.remove(gameObject);
|
|
|
|
}
|
2018-04-05 13:59:57 +00:00
|
|
|
|
2018-04-10 03:13:38 +00:00
|
|
|
gameObject.parentContainer = this;
|
2018-04-09 16:33:55 +00:00
|
|
|
}
|
2018-03-26 20:23:18 +00:00
|
|
|
},
|
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
/**
|
2018-04-05 12:52:42 +00:00
|
|
|
* Internal remove handler.
|
2018-04-05 08:23:29 +00:00
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @method Phaser.GameObjects.Container#removeHandler
|
|
|
|
* @private
|
2018-04-05 08:23:29 +00:00
|
|
|
* @since 3.4.0
|
|
|
|
*
|
2018-04-05 12:52:42 +00:00
|
|
|
* @param {Phaser.GameObjects.Container} list - The List the Game Object was removed from (also this Container)
|
|
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container.
|
2018-04-05 08:23:29 +00:00
|
|
|
*/
|
2018-04-10 03:13:38 +00:00
|
|
|
removeHandler: function (gameObject)
|
2018-03-26 20:23:18 +00:00
|
|
|
{
|
2018-04-10 03:13:38 +00:00
|
|
|
gameObject.off('destroy', this.remove, this);
|
2018-04-05 08:23:29 +00:00
|
|
|
|
2018-04-09 16:33:55 +00:00
|
|
|
if (this.exclusive)
|
|
|
|
{
|
|
|
|
gameObject.parentContainer = null;
|
|
|
|
}
|
2018-03-28 23:47:57 +00:00
|
|
|
},
|
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
/**
|
|
|
|
* Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties,
|
|
|
|
* and transforms it into the space of this Container, then returns it in the output object.
|
|
|
|
*
|
|
|
|
* @method Phaser.GameObjects.Container#pointToContainer
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @param {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} source - The Source Point to be transformed.
|
|
|
|
* @param {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} [output] - A destination object to store the transformed point in. If none given a Vector2 will be created and returned.
|
|
|
|
*
|
|
|
|
* @return {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} The transformed point.
|
|
|
|
*/
|
|
|
|
pointToContainer: function (source, output)
|
2018-03-28 23:47:57 +00:00
|
|
|
{
|
2018-04-05 08:23:29 +00:00
|
|
|
if (output === undefined) { output = new Vector2(); }
|
2018-03-28 23:47:57 +00:00
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
if (this.parentContainer)
|
2018-03-28 23:47:57 +00:00
|
|
|
{
|
2018-04-05 10:25:22 +00:00
|
|
|
return this.parentContainer.pointToContainer(source, output);
|
2018-03-28 23:47:57 +00:00
|
|
|
}
|
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
var tempMatrix = this.tempTransformMatrix;
|
|
|
|
|
2018-04-05 10:25:22 +00:00
|
|
|
// No need to loadIdentity because applyITRS overwrites every value anyway
|
2018-03-28 23:47:57 +00:00
|
|
|
tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY);
|
2018-04-05 10:25:22 +00:00
|
|
|
|
2018-03-28 23:47:57 +00:00
|
|
|
tempMatrix.invert();
|
2018-04-05 10:25:22 +00:00
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
tempMatrix.transformPoint(source.x, source.y, output);
|
2018-03-28 23:47:57 +00:00
|
|
|
|
2018-04-05 08:23:29 +00:00
|
|
|
return output;
|
2018-04-05 12:52:42 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroys this Container removing it and all children from the Display List and
|
|
|
|
* severing all ties to parent resources.
|
|
|
|
*
|
|
|
|
* Use this to remove a Container from your game if you don't ever plan to use it again.
|
|
|
|
* As long as no reference to it exists within your own code it should become free for
|
|
|
|
* garbage collection by the browser.
|
|
|
|
*
|
|
|
|
* If you just want to temporarily disable an object then look at using the
|
|
|
|
* Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected.
|
|
|
|
*
|
|
|
|
* @method Phaser.GameObjects.Container#destroy
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
destroy: function ()
|
|
|
|
{
|
|
|
|
// This Game Object had already been destroyed
|
|
|
|
if (!this.scene)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.preDestroy)
|
|
|
|
{
|
|
|
|
this.preDestroy.call(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.emit('destroy', this);
|
|
|
|
|
|
|
|
var sys = this.scene.sys;
|
|
|
|
|
|
|
|
sys.displayList.remove(this);
|
|
|
|
|
|
|
|
if (this.data)
|
|
|
|
{
|
|
|
|
this.data.destroy();
|
|
|
|
|
|
|
|
this.data = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tell the Scene to re-sort the children
|
|
|
|
sys.queueDepthSort();
|
|
|
|
|
|
|
|
this.active = false;
|
|
|
|
this.visible = false;
|
|
|
|
|
|
|
|
this.scene = undefined;
|
|
|
|
|
|
|
|
this.removeAllListeners();
|
|
|
|
|
|
|
|
this.removeAll();
|
|
|
|
|
|
|
|
this.list = [];
|
|
|
|
|
|
|
|
this.parent = null;
|
|
|
|
this.parentContainer = null;
|
2018-03-23 17:15:52 +00:00
|
|
|
}
|
2018-04-05 08:23:29 +00:00
|
|
|
|
2018-03-23 17:15:52 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = Container;
|