UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.

1,587 lines (1,405 loc) 671 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("SpineWebGLPlugin", [], factory); else if(typeof exports === 'object') exports["SpineWebGLPlugin"] = factory(); else root["SpineWebGLPlugin"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./SpineWebGLPlugin.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "../../../node_modules/eventemitter3/index.js": /*!*******************************************************************************!*\ !*** /Users/rich/Documents/GitHub/phaser/node_modules/eventemitter3/index.js ***! \*******************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var has = Object.prototype.hasOwnProperty , prefix = '~'; /** * Constructor to create a storage for our `EE` objects. * An `Events` instance is a plain object whose properties are event names. * * @constructor * @private */ function Events() {} // // We try to not inherit from `Object.prototype`. In some engines creating an // instance in this way is faster than calling `Object.create(null)` directly. // If `Object.create(null)` is not supported we prefix the event names with a // character to make sure that the built-in object properties are not // overridden or used as an attack vector. // if (Object.create) { Events.prototype = Object.create(null); // // This hack is needed because the `__proto__` property is still inherited in // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. // if (!new Events().__proto__) prefix = false; } /** * Representation of a single event listener. * * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} [once=false] Specify if the listener is a one-time listener. * @constructor * @private */ function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } /** * Add a listener for a given event. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} context The context to invoke the listener with. * @param {Boolean} once Specify if the listener is a one-time listener. * @returns {EventEmitter} * @private */ function addListener(emitter, event, fn, context, once) { if (typeof fn !== 'function') { throw new TypeError('The listener must be a function'); } var listener = new EE(fn, context || emitter, once) , evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } /** * Clear event by name. * * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. * @param {(String|Symbol)} evt The Event name. * @private */ function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events(); else delete emitter._events[evt]; } /** * Minimal `EventEmitter` interface that is molded against the Node.js * `EventEmitter` interface. * * @constructor * @public */ function EventEmitter() { this._events = new Events(); this._eventsCount = 0; } /** * Return an array listing the events for which the emitter has registered * listeners. * * @returns {Array} * @public */ EventEmitter.prototype.eventNames = function eventNames() { var names = [] , events , name; if (this._eventsCount === 0) return names; for (name in (events = this._events)) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; /** * Return the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Array} The registered listeners. * @public */ EventEmitter.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event , handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [handlers.fn]; for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { ee[i] = handlers[i].fn; } return ee; }; /** * Return the number of listeners listening to a given event. * * @param {(String|Symbol)} event The event name. * @returns {Number} The number of listeners. * @public */ EventEmitter.prototype.listenerCount = function listenerCount(event) { var evt = prefix ? prefix + event : event , listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; /** * Calls each of the listeners registered for a given event. * * @param {(String|Symbol)} event The event name. * @returns {Boolean} `true` if the event had listeners, else `false`. * @public */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt] , len = arguments.length , args , i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len -1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length , j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; /** * Add a listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.on = function on(event, fn, context) { return addListener(this, event, fn, context, false); }; /** * Add a one-time listener for a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn The listener function. * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.once = function once(event, fn, context) { return addListener(this, event, fn, context, true); }; /** * Remove the listeners of a given event. * * @param {(String|Symbol)} event The event name. * @param {Function} fn Only remove the listeners that match this function. * @param {*} context Only remove the listeners that have this context. * @param {Boolean} once Only remove one-time listeners. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return this; if (!fn) { clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if ( listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context) ) { clearEvent(this, evt); } } else { for (var i = 0, events = [], length = listeners.length; i < length; i++) { if ( listeners[i].fn !== fn || (once && !listeners[i].once) || (context && listeners[i].context !== context) ) { events.push(listeners[i]); } } // // Reset the array, or remove it completely if we have no more listeners. // if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; else clearEvent(this, evt); } return this; }; /** * Remove all listeners, or those of the specified event. * * @param {(String|Symbol)} [event] The event name. * @returns {EventEmitter} `this`. * @public */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = prefix ? prefix + event : event; if (this._events[evt]) clearEvent(this, evt); } else { this._events = new Events(); this._eventsCount = 0; } return this; }; // // Alias methods names because people roll like that. // EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.addListener = EventEmitter.prototype.on; // // Expose the prefix. // EventEmitter.prefixed = prefix; // // Allow `EventEmitter` to be imported as module namespace. // EventEmitter.EventEmitter = EventEmitter; // // Expose the module. // if (true) { module.exports = EventEmitter; } /***/ }), /***/ "../../../src/data/DataManager.js": /*!*******************************************************************!*\ !*** /Users/rich/Documents/GitHub/phaser/src/data/DataManager.js ***! \*******************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2018 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ var Class = __webpack_require__(/*! ../utils/Class */ "../../../src/utils/Class.js"); /** * @callback DataEachCallback * * @param {*} parent - The parent object of the DataManager. * @param {string} key - The key of the value. * @param {*} value - The value. * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. */ /** * @classdesc * The Data Component features a means to store pieces of data specific to a Game Object, System or Plugin. * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter, * or have a property called `events` that is an instance of it. * * @class DataManager * @memberof Phaser.Data * @constructor * @since 3.0.0 * * @param {object} parent - The object that this DataManager belongs to. * @param {Phaser.Events.EventEmitter} eventEmitter - The DataManager's event emitter. */ var DataManager = new Class({ initialize: function DataManager (parent, eventEmitter) { /** * The object that this DataManager belongs to. * * @name Phaser.Data.DataManager#parent * @type {*} * @since 3.0.0 */ this.parent = parent; /** * The DataManager's event emitter. * * @name Phaser.Data.DataManager#events * @type {Phaser.Events.EventEmitter} * @since 3.0.0 */ this.events = eventEmitter; if (!eventEmitter) { this.events = (parent.events) ? parent.events : parent; } /** * The data list. * * @name Phaser.Data.DataManager#list * @type {Object.<string, *>} * @default {} * @since 3.0.0 */ this.list = {}; /** * The public values list. You can use this to access anything you have stored * in this Data Manager. For example, if you set a value called `gold` you can * access it via: * * ```javascript * this.data.values.gold; * ``` * * You can also modify it directly: * * ```javascript * this.data.values.gold += 1000; * ``` * * Doing so will emit a `setdata` event from the parent of this Data Manager. * * Do not modify this object directly. Adding properties directly to this object will not * emit any events. Always use `DataManager.set` to create new items the first time around. * * @name Phaser.Data.DataManager#values * @type {Object.<string, *>} * @default {} * @since 3.10.0 */ this.values = {}; /** * Whether setting data is frozen for this DataManager. * * @name Phaser.Data.DataManager#_frozen * @type {boolean} * @private * @default false * @since 3.0.0 */ this._frozen = false; if (!parent.hasOwnProperty('sys') && this.events) { this.events.once('destroy', this.destroy, this); } }, /** * Retrieves the value for the given key, or undefined if it doesn't exist. * * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: * * ```javascript * this.data.get('gold'); * ``` * * Or access the value directly: * * ```javascript * this.data.values.gold; * ``` * * You can also pass in an array of keys, in which case an array of values will be returned: * * ```javascript * this.data.get([ 'gold', 'armor', 'health' ]); * ``` * * This approach is useful for destructuring arrays in ES6. * * @method Phaser.Data.DataManager#get * @since 3.0.0 * * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. * * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. */ get: function (key) { var list = this.list; if (Array.isArray(key)) { var output = []; for (var i = 0; i < key.length; i++) { output.push(list[key[i]]); } return output; } else { return list[key]; } }, /** * Retrieves all data values in a new object. * * @method Phaser.Data.DataManager#getAll * @since 3.0.0 * * @return {Object.<string, *>} All data values. */ getAll: function () { var results = {}; for (var key in this.list) { if (this.list.hasOwnProperty(key)) { results[key] = this.list[key]; } } return results; }, /** * Queries the DataManager for the values of keys matching the given regular expression. * * @method Phaser.Data.DataManager#query * @since 3.0.0 * * @param {RegExp} search - A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj). * * @return {Object.<string, *>} The values of the keys matching the search string. */ query: function (search) { var results = {}; for (var key in this.list) { if (this.list.hasOwnProperty(key) && key.match(search)) { results[key] = this.list[key]; } } return results; }, /** * Sets a value for the given key. If the key doesn't already exist in the Data Manager then it is created. * * ```javascript * data.set('name', 'Red Gem Stone'); * ``` * * You can also pass in an object of key value pairs as the first argument: * * ```javascript * data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); * ``` * * To get a value back again you can call `get`: * * ```javascript * data.get('gold'); * ``` * * Or you can access the value directly via the `values` property, where it works like any other variable: * * ```javascript * data.values.gold += 50; * ``` * * When the value is first set, a `setdata` event is emitted. * * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata_PlayerLives`. * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. * * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. * * @method Phaser.Data.DataManager#set * @since 3.0.0 * * @param {(string|object)} key - The key to set the value for. Or an object or key value pairs. If an object the `data` argument is ignored. * @param {*} data - The value to set for the given key. If an object is provided as the key this argument is ignored. * * @return {Phaser.Data.DataManager} This DataManager object. */ set: function (key, data) { if (this._frozen) { return this; } if (typeof key === 'string') { return this.setValue(key, data); } else { for (var entry in key) { this.setValue(entry, key[entry]); } } return this; }, /** * Internal value setter, called automatically by the `set` method. * * @method Phaser.Data.DataManager#setValue * @private * @since 3.10.0 * * @param {string} key - The key to set the value for. * @param {*} data - The value to set. * * @return {Phaser.Data.DataManager} This DataManager object. */ setValue: function (key, data) { if (this._frozen) { return this; } if (this.has(key)) { // Hit the key getter, which will in turn emit the events. this.values[key] = data; } else { var _this = this; var list = this.list; var events = this.events; var parent = this.parent; Object.defineProperty(this.values, key, { enumerable: true, configurable: true, get: function () { return list[key]; }, set: function (value) { if (!_this._frozen) { var previousValue = list[key]; list[key] = value; events.emit('changedata', parent, key, value, previousValue); events.emit('changedata_' + key, parent, value, previousValue); } } }); list[key] = data; events.emit('setdata', parent, key, data); } return this; }, /** * Passes all data entries to the given callback. * * @method Phaser.Data.DataManager#each * @since 3.0.0 * * @param {DataEachCallback} callback - The function to call. * @param {*} [context] - Value to use as `this` when executing callback. * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. * * @return {Phaser.Data.DataManager} This DataManager object. */ each: function (callback, context) { var args = [ this.parent, null, undefined ]; for (var i = 1; i < arguments.length; i++) { args.push(arguments[i]); } for (var key in this.list) { args[1] = key; args[2] = this.list[key]; callback.apply(context, args); } return this; }, /** * Merge the given object of key value pairs into this DataManager. * * Any newly created values will emit a `setdata` event. Any updated values (see the `overwrite` argument) * will emit a `changedata` event. * * @method Phaser.Data.DataManager#merge * @since 3.0.0 * * @param {Object.<string, *>} data - The data to merge. * @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true. * * @return {Phaser.Data.DataManager} This DataManager object. */ merge: function (data, overwrite) { if (overwrite === undefined) { overwrite = true; } // Merge data from another component into this one for (var key in data) { if (data.hasOwnProperty(key) && (overwrite || (!overwrite && !this.has(key)))) { this.setValue(key, data[key]); } } return this; }, /** * Remove the value for the given key. * * If the key is found in this Data Manager it is removed from the internal lists and a * `removedata` event is emitted. * * You can also pass in an array of keys, in which case all keys in the array will be removed: * * ```javascript * this.data.remove([ 'gold', 'armor', 'health' ]); * ``` * * @method Phaser.Data.DataManager#remove * @since 3.0.0 * * @param {(string|string[])} key - The key to remove, or an array of keys to remove. * * @return {Phaser.Data.DataManager} This DataManager object. */ remove: function (key) { if (this._frozen) { return this; } if (Array.isArray(key)) { for (var i = 0; i < key.length; i++) { this.removeValue(key[i]); } } else { return this.removeValue(key); } return this; }, /** * Internal value remover, called automatically by the `remove` method. * * @method Phaser.Data.DataManager#removeValue * @private * @since 3.10.0 * * @param {string} key - The key to set the value for. * * @return {Phaser.Data.DataManager} This DataManager object. */ removeValue: function (key) { if (this.has(key)) { var data = this.list[key]; delete this.list[key]; delete this.values[key]; this.events.emit('removedata', this.parent, key, data); } return this; }, /** * Retrieves the data associated with the given 'key', deletes it from this Data Manager, then returns it. * * @method Phaser.Data.DataManager#pop * @since 3.0.0 * * @param {string} key - The key of the value to retrieve and delete. * * @return {*} The value of the given key. */ pop: function (key) { var data = undefined; if (!this._frozen && this.has(key)) { data = this.list[key]; delete this.list[key]; delete this.values[key]; this.events.emit('removedata', this, key, data); } return data; }, /** * Determines whether the given key is set in this Data Manager. * * Please note that the keys are case-sensitive and must be valid JavaScript Object property strings. * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. * * @method Phaser.Data.DataManager#has * @since 3.0.0 * * @param {string} key - The key to check. * * @return {boolean} Returns `true` if the key exists, otherwise `false`. */ has: function (key) { return this.list.hasOwnProperty(key); }, /** * Freeze or unfreeze this Data Manager. A frozen Data Manager will block all attempts * to create new values or update existing ones. * * @method Phaser.Data.DataManager#setFreeze * @since 3.0.0 * * @param {boolean} value - Whether to freeze or unfreeze the Data Manager. * * @return {Phaser.Data.DataManager} This DataManager object. */ setFreeze: function (value) { this._frozen = value; return this; }, /** * Delete all data in this Data Manager and unfreeze it. * * @method Phaser.Data.DataManager#reset * @since 3.0.0 * * @return {Phaser.Data.DataManager} This DataManager object. */ reset: function () { for (var key in this.list) { delete this.list[key]; delete this.values[key]; } this._frozen = false; return this; }, /** * Destroy this data manager. * * @method Phaser.Data.DataManager#destroy * @since 3.0.0 */ destroy: function () { this.reset(); this.events.off('changedata'); this.events.off('setdata'); this.events.off('removedata'); this.parent = null; }, /** * Gets or sets the frozen state of this Data Manager. * A frozen Data Manager will block all attempts to create new values or update existing ones. * * @name Phaser.Data.DataManager#freeze * @type {boolean} * @since 3.0.0 */ freeze: { get: function () { return this._frozen; }, set: function (value) { this._frozen = (value) ? true : false; } }, /** * Return the total number of entries in this Data Manager. * * @name Phaser.Data.DataManager#count * @type {integer} * @since 3.0.0 */ count: { get: function () { var i = 0; for (var key in this.list) { if (this.list[key] !== undefined) { i++; } } return i; } } }); module.exports = DataManager; /***/ }), /***/ "../../../src/gameobjects/GameObject.js": /*!*************************************************************************!*\ !*** /Users/rich/Documents/GitHub/phaser/src/gameobjects/GameObject.js ***! \*************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2018 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ var Class = __webpack_require__(/*! ../utils/Class */ "../../../src/utils/Class.js"); var ComponentsToJSON = __webpack_require__(/*! ./components/ToJSON */ "../../../src/gameobjects/components/ToJSON.js"); var DataManager = __webpack_require__(/*! ../data/DataManager */ "../../../src/data/DataManager.js"); var EventEmitter = __webpack_require__(/*! eventemitter3 */ "../../../node_modules/eventemitter3/index.js"); /** * @classdesc * The base class that all Game Objects extend. * You don't create GameObjects directly and they cannot be added to the display list. * Instead, use them as the base for your own custom classes. * * @class GameObject * @memberof Phaser.GameObjects * @extends Phaser.Events.EventEmitter * @constructor * @since 3.0.0 * * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. * @param {string} type - A textual representation of the type of Game Object, i.e. `sprite`. */ var GameObject = new Class({ Extends: EventEmitter, initialize: function GameObject (scene, type) { EventEmitter.call(this); /** * The Scene to which this Game Object belongs. * Game Objects can only belong to one Scene. * * @name Phaser.GameObjects.GameObject#scene * @type {Phaser.Scene} * @protected * @since 3.0.0 */ this.scene = scene; /** * A textual representation of this Game Object, i.e. `sprite`. * Used internally by Phaser but is available for your own custom classes to populate. * * @name Phaser.GameObjects.GameObject#type * @type {string} * @since 3.0.0 */ this.type = type; /** * The parent Container of this Game Object, if it has one. * * @name Phaser.GameObjects.GameObject#parentContainer * @type {Phaser.GameObjects.Container} * @since 3.4.0 */ this.parentContainer = null; /** * The name of this Game Object. * Empty by default and never populated by Phaser, this is left for developers to use. * * @name Phaser.GameObjects.GameObject#name * @type {string} * @default '' * @since 3.0.0 */ this.name = ''; /** * The active state of this Game Object. * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. * An active object is one which is having its logic and internal systems updated. * * @name Phaser.GameObjects.GameObject#active * @type {boolean} * @default true * @since 3.0.0 */ this.active = true; /** * The Tab Index of the Game Object. * Reserved for future use by plugins and the Input Manager. * * @name Phaser.GameObjects.GameObject#tabIndex * @type {integer} * @default -1 * @since 3.0.0 */ this.tabIndex = -1; /** * A Data Manager. * It allows you to store, query and get key/value paired information specific to this Game Object. * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. * * @name Phaser.GameObjects.GameObject#data * @type {Phaser.Data.DataManager} * @default null * @since 3.0.0 */ this.data = null; /** * The flags that are compared against `RENDER_MASK` to determine if this Game Object will render or not. * The bits are 0001 | 0010 | 0100 | 1000 set by the components Visible, Alpha, Transform and Texture respectively. * If those components are not used by your custom class then you can use this bitmask as you wish. * * @name Phaser.GameObjects.GameObject#renderFlags * @type {integer} * @default 15 * @since 3.0.0 */ this.renderFlags = 15; /** * A bitmask that controls if this Game Object is drawn by a Camera or not. * Not usually set directly, instead call `Camera.ignore`, however you can * set this property directly using the Camera.id property: * * @example * this.cameraFilter |= camera.id * * @name Phaser.GameObjects.GameObject#cameraFilter * @type {number} * @default 0 * @since 3.0.0 */ this.cameraFilter = 0; /** * If this Game Object is enabled for input then this property will contain an InteractiveObject instance. * Not usually set directly. Instead call `GameObject.setInteractive()`. * * @name Phaser.GameObjects.GameObject#input * @type {?Phaser.Input.InteractiveObject} * @default null * @since 3.0.0 */ this.input = null; /** * If this Game Object is enabled for physics then this property will contain a reference to a Physics Body. * * @name Phaser.GameObjects.GameObject#body * @type {?(object|Phaser.Physics.Arcade.Body|Phaser.Physics.Impact.Body)} * @default null * @since 3.0.0 */ this.body = null; /** * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. * This includes calls that may come from a Group, Container or the Scene itself. * While it allows you to persist a Game Object across Scenes, please understand you are entirely * responsible for managing references to and from this Game Object. * * @name Phaser.GameObjects.GameObject#ignoreDestroy * @type {boolean} * @default false * @since 3.5.0 */ this.ignoreDestroy = false; // Tell the Scene to re-sort the children scene.sys.queueDepthSort(); }, /** * Sets the `active` property of this Game Object and returns this Game Object for further chaining. * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. * * @method Phaser.GameObjects.GameObject#setActive * @since 3.0.0 * * @param {boolean} value - True if this Game Object should be set as active, false if not. * * @return {this} This GameObject. */ setActive: function (value) { this.active = value; return this; }, /** * Sets the `name` property of this Game Object and returns this Game Object for further chaining. * The `name` property is not populated by Phaser and is presented for your own use. * * @method Phaser.GameObjects.GameObject#setName * @since 3.0.0 * * @param {string} value - The name to be given to this Game Object. * * @return {this} This GameObject. */ setName: function (value) { this.name = value; return this; }, /** * Adds a Data Manager component to this Game Object. * * @method Phaser.GameObjects.GameObject#setDataEnabled * @since 3.0.0 * @see Phaser.Data.DataManager * * @return {this} This GameObject. */ setDataEnabled: function () { if (!this.data) { this.data = new DataManager(this); } return this; }, /** * Allows you to store a key value pair within this Game Objects Data Manager. * * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled * before setting the value. * * If the key doesn't already exist in the Data Manager then it is created. * * ```javascript * sprite.setData('name', 'Red Gem Stone'); * ``` * * You can also pass in an object of key value pairs as the first argument: * * ```javascript * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); * ``` * * To get a value back again you can call `getData`: * * ```javascript * sprite.getData('gold'); * ``` * * Or you can access the value directly via the `values` property, where it works like any other variable: * * ```javascript * sprite.data.values.gold += 50; * ``` * * When the value is first set, a `setdata` event is emitted from this Game Object. * * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata_PlayerLives`. * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. * * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. * * @method Phaser.GameObjects.GameObject#setData * @since 3.0.0 * * @param {(string|object)} key - The key to set the value for. Or an object or key value pairs. If an object the `data` argument is ignored. * @param {*} data - The value to set for the given key. If an object is provided as the key this argument is ignored. * * @return {this} This GameObject. */ setData: function (key, value) { if (!this.data) { this.data = new DataManager(this); } this.data.set(key, value); return this; }, /** * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. * * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: * * ```javascript * sprite.getData('gold'); * ``` * * Or access the value directly: * * ```javascript * sprite.data.values.gold; * ``` * * You can also pass in an array of keys, in which case an array of values will be returned: * * ```javascript * sprite.getData([ 'gold', 'armor', 'health' ]); * ``` * * This approach is useful for destructuring arrays in ES6. * * @method Phaser.GameObjects.GameObject#getData * @since 3.0.0 * * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. * * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. */ getData: function (key) { if (!this.data) { this.data = new DataManager(this); } return this.data.get(key); }, /** * Pass this Game Object to the Input Manager to enable it for Input. * * 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. * * 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. * * @method Phaser.GameObjects.GameObject#setInteractive * @since 3.0.0 * * @param {(Phaser.Input.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 {HitAreaCallback} [callback] - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. * @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target? * * @return {this} This GameObject. */ setInteractive: function (shape, callback, dropZone) { this.scene.sys.input.enable(this, shape, callback, dropZone); return this; }, /** * If this Game Object has previously been enabled for input, this will disable it. * * An object that is disabled for input stops processing or being considered for * input events, but can be turned back on again at any time by simply calling * `setInteractive()` with no arguments provided. * * If want to completely remove interaction from this Game Object then use `removeInteractive` instead. * * @method Phaser.GameObjects.GameObject#disableInteractive * @since 3.7.0 * * @return {this} This GameObject. */ disableInteractive: function () { if (this.input) { this.input.enabled = false; } return this; }, /** * If this Game Object has previously been enabled for input, this will queue it * for removal, causing it to no longer be interactive. The removal happens on * the next game step, it is not immediate. * * The Interactive Object that was assigned to this Game Object will be destroyed, * removed from the Input Manager and cleared from this Game Object. * * If you wish to re-enable this Game Object at a later date you will need to * re-create its InteractiveObject by calling `setInteractive` again. * * If you wish to only temporarily stop an object from receiving input then use * `disableInteractive` instead, as that toggles the interactive state, where-as * this erases it completely. * * If you wish to resize a hit area, don't remove and then set it as being * interactive. Instead, access the hitarea object directly and resize the shape * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the * shape is a Rectangle, which it is by default.) * * @method Phaser.GameObjects.GameObject#removeInteractive * @since 3.7.0 * * @return {this} This GameObject. */ removeInteractive: function () { this.scene.sys.input.clear(this); this.input = undefined; return this; }, /** * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. * * @method Phaser.GameObjects.GameObject#update * @since 3.0.0 * * @param {...*} [args] - args */ update: function () { }, /** * Returns a JSON representation of the Game Object. * * @method Phaser.GameObjects.GameObject#toJSON * @since 3.0.0 * * @return {JSONGameObject} A JSON representation of the Game Object. */ toJSON: function () { return ComponentsToJSON(this); }, /** * Compares the renderMask with the renderFlags to see if this Game Object will render or not. * Also checks the Game Object against the given Cameras exclusion list. * * @method Phaser.GameObjects.GameObject#willRender * @since 3.0.0 * * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. * * @return {boolean} True if the Game Object should be rendered, otherwise false. */ willRender: function (camera) { return !(GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter > 0 && (this.cameraFilter & camera.id))); }, /** * Returns an array containing the display list index of either this Game Object, or if it has one, * its parent Container. It then iterates up through all of the parent containers until it hits the * root of the display list (which is index 0 in the returned array). * * Used internally by the InputPlugin but also useful if you wish to find out the display depth of * this Game Object and all of its ancestors. * * @method Phaser.GameObjects.GameObject#getIndexList * @since 3.4.0 * * @return {integer[]} An array of display list position indexes. */ getIndexList: function () { // eslint-disable-next-line consistent-this var child = this; var parent = this.parentContainer; var indexes = []; while (parent) { // indexes.unshift([parent.getIndex(child), parent.name]); indexes.unshift(parent.getIndex(child)); child = parent; if (!parent.parentContainer) { break; } else { parent = parent.parentContainer; } } // indexes.unshift([this.scene.sys.displayList.getIndex(child), 'root']); indexes.unshift(this.scene.sys.displayList.getIndex(child));