mirror of
https://github.com/photonstorm/phaser
synced 2024-11-15 01:17:43 +00:00
45024 lines
No EOL
1.4 MiB
45024 lines
No EOL
1.4 MiB
window["SpinePlugin"] =
|
|
/******/ (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 = 61);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Taken from klasse by mattdesl https://github.com/mattdesl/klasse
|
|
|
|
function hasGetterOrSetter (def)
|
|
{
|
|
return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function');
|
|
}
|
|
|
|
function getProperty (definition, k, isClassDescriptor)
|
|
{
|
|
// This may be a lightweight object, OR it might be a property that was defined previously.
|
|
|
|
// For simple class descriptors we can just assume its NOT previously defined.
|
|
var def = (isClassDescriptor) ? definition[k] : Object.getOwnPropertyDescriptor(definition, k);
|
|
|
|
if (!isClassDescriptor && def.value && typeof def.value === 'object')
|
|
{
|
|
def = def.value;
|
|
}
|
|
|
|
// This might be a regular property, or it may be a getter/setter the user defined in a class.
|
|
if (def && hasGetterOrSetter(def))
|
|
{
|
|
if (typeof def.enumerable === 'undefined')
|
|
{
|
|
def.enumerable = true;
|
|
}
|
|
|
|
if (typeof def.configurable === 'undefined')
|
|
{
|
|
def.configurable = true;
|
|
}
|
|
|
|
return def;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function hasNonConfigurable (obj, k)
|
|
{
|
|
var prop = Object.getOwnPropertyDescriptor(obj, k);
|
|
|
|
if (!prop)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (prop.value && typeof prop.value === 'object')
|
|
{
|
|
prop = prop.value;
|
|
}
|
|
|
|
if (prop.configurable === false)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Extends the given `myClass` object's prototype with the properties of `definition`.
|
|
*
|
|
* @function extend
|
|
* @param {Object} ctor The constructor object to mix into.
|
|
* @param {Object} definition A dictionary of functions for the class.
|
|
* @param {boolean} isClassDescriptor Is the definition a class descriptor?
|
|
* @param {Object} [extend] The parent constructor object.
|
|
*/
|
|
function extend (ctor, definition, isClassDescriptor, extend)
|
|
{
|
|
for (var k in definition)
|
|
{
|
|
if (!definition.hasOwnProperty(k))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var def = getProperty(definition, k, isClassDescriptor);
|
|
|
|
if (def !== false)
|
|
{
|
|
// If Extends is used, we will check its prototype to see if the final variable exists.
|
|
|
|
var parent = extend || ctor;
|
|
|
|
if (hasNonConfigurable(parent.prototype, k))
|
|
{
|
|
// Just skip the final property
|
|
if (Class.ignoreFinals)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// We cannot re-define a property that is configurable=false.
|
|
// So we will consider them final and throw an error. This is by
|
|
// default so it is clear to the developer what is happening.
|
|
// You can set ignoreFinals to true if you need to extend a class
|
|
// which has configurable=false; it will simply not re-define final properties.
|
|
throw new Error('cannot override final property \'' + k + '\', set Class.ignoreFinals = true to skip');
|
|
}
|
|
|
|
Object.defineProperty(ctor.prototype, k, def);
|
|
}
|
|
else
|
|
{
|
|
ctor.prototype[k] = definition[k];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Applies the given `mixins` to the prototype of `myClass`.
|
|
*
|
|
* @function mixin
|
|
* @param {Object} myClass The constructor object to mix into.
|
|
* @param {Object|Array<Object>} mixins The mixins to apply to the constructor.
|
|
*/
|
|
function mixin (myClass, mixins)
|
|
{
|
|
if (!mixins)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Array.isArray(mixins))
|
|
{
|
|
mixins = [ mixins ];
|
|
}
|
|
|
|
for (var i = 0; i < mixins.length; i++)
|
|
{
|
|
extend(myClass, mixins[i].prototype || mixins[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a new class with the given descriptor.
|
|
* The constructor, defined by the name `initialize`,
|
|
* is an optional function. If unspecified, an anonymous
|
|
* function will be used which calls the parent class (if
|
|
* one exists).
|
|
*
|
|
* You can also use `Extends` and `Mixins` to provide subclassing
|
|
* and inheritance.
|
|
*
|
|
* @class Phaser.Class
|
|
* @constructor
|
|
* @param {Object} definition a dictionary of functions for the class
|
|
* @example
|
|
*
|
|
* var MyClass = new Phaser.Class({
|
|
*
|
|
* initialize: function() {
|
|
* this.foo = 2.0;
|
|
* },
|
|
*
|
|
* bar: function() {
|
|
* return this.foo + 5;
|
|
* }
|
|
* });
|
|
*/
|
|
function Class (definition)
|
|
{
|
|
if (!definition)
|
|
{
|
|
definition = {};
|
|
}
|
|
|
|
// The variable name here dictates what we see in Chrome debugger
|
|
var initialize;
|
|
var Extends;
|
|
|
|
if (definition.initialize)
|
|
{
|
|
if (typeof definition.initialize !== 'function')
|
|
{
|
|
throw new Error('initialize must be a function');
|
|
}
|
|
|
|
initialize = definition.initialize;
|
|
|
|
// Usually we should avoid 'delete' in V8 at all costs.
|
|
// However, its unlikely to make any performance difference
|
|
// here since we only call this on class creation (i.e. not object creation).
|
|
delete definition.initialize;
|
|
}
|
|
else if (definition.Extends)
|
|
{
|
|
var base = definition.Extends;
|
|
|
|
initialize = function ()
|
|
{
|
|
base.apply(this, arguments);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
initialize = function () {};
|
|
}
|
|
|
|
if (definition.Extends)
|
|
{
|
|
initialize.prototype = Object.create(definition.Extends.prototype);
|
|
initialize.prototype.constructor = initialize;
|
|
|
|
// For getOwnPropertyDescriptor to work, we need to act directly on the Extends (or Mixin)
|
|
|
|
Extends = definition.Extends;
|
|
|
|
delete definition.Extends;
|
|
}
|
|
else
|
|
{
|
|
initialize.prototype.constructor = initialize;
|
|
}
|
|
|
|
// Grab the mixins, if they are specified...
|
|
var mixins = null;
|
|
|
|
if (definition.Mixins)
|
|
{
|
|
mixins = definition.Mixins;
|
|
delete definition.Mixins;
|
|
}
|
|
|
|
// First, mixin if we can.
|
|
mixin(initialize, mixins);
|
|
|
|
// Now we grab the actual definition which defines the overrides.
|
|
extend(initialize, definition, true, Extends);
|
|
|
|
return initialize;
|
|
}
|
|
|
|
Class.extend = extend;
|
|
Class.mixin = mixin;
|
|
Class.ignoreFinals = false;
|
|
|
|
module.exports = Class;
|
|
|
|
|
|
/***/ }),
|
|
/* 1 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* A NOOP (No Operation) callback function.
|
|
*
|
|
* Used internally by Phaser when it's more expensive to determine if a callback exists
|
|
* than it is to just invoke an empty function.
|
|
*
|
|
* @function Phaser.Utils.NOOP
|
|
* @since 3.0.0
|
|
*/
|
|
var NOOP = function ()
|
|
{
|
|
// NOOP
|
|
};
|
|
|
|
module.exports = NOOP;
|
|
|
|
|
|
/***/ }),
|
|
/* 2 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
var FuzzyEqual = __webpack_require__(32);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A representation of a vector in 2D space.
|
|
*
|
|
* A two-component vector.
|
|
*
|
|
* @class Vector2
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number|Phaser.Types.Math.Vector2Like} [x] - The x component, or an object with `x` and `y` properties.
|
|
* @param {number} [y] - The y component.
|
|
*/
|
|
var Vector2 = new Class({
|
|
|
|
initialize:
|
|
|
|
function Vector2 (x, y)
|
|
{
|
|
/**
|
|
* The x component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector2#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.x = 0;
|
|
|
|
/**
|
|
* The y component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector2#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.y = 0;
|
|
|
|
if (typeof x === 'object')
|
|
{
|
|
this.x = x.x || 0;
|
|
this.y = x.y || 0;
|
|
}
|
|
else
|
|
{
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Make a clone of this Vector2.
|
|
*
|
|
* @method Phaser.Math.Vector2#clone
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} A clone of this Vector2.
|
|
*/
|
|
clone: function ()
|
|
{
|
|
return new Vector2(this.x, this.y);
|
|
},
|
|
|
|
/**
|
|
* Copy the components of a given Vector into this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to copy the components from.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
this.x = src.x || 0;
|
|
this.y = src.y || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the component values of this Vector from a given Vector2Like object.
|
|
*
|
|
* @method Phaser.Math.Vector2#setFromObject
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
setFromObject: function (obj)
|
|
{
|
|
this.x = obj.x || 0;
|
|
this.y = obj.y || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
|
|
*
|
|
* @method Phaser.Math.Vector2#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The x value to set for this Vector.
|
|
* @param {number} [y=x] - The y value to set for this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
set: function (x, y)
|
|
{
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* This method is an alias for `Vector2.set`.
|
|
*
|
|
* @method Phaser.Math.Vector2#setTo
|
|
* @since 3.4.0
|
|
*
|
|
* @param {number} x - The x value to set for this Vector.
|
|
* @param {number} [y=x] - The y value to set for this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
setTo: function (x, y)
|
|
{
|
|
return this.set(x, y);
|
|
},
|
|
|
|
/**
|
|
* Sets the `x` and `y` values of this object from a given polar coordinate.
|
|
*
|
|
* @method Phaser.Math.Vector2#setToPolar
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} azimuth - The angular coordinate, in radians.
|
|
* @param {number} [radius=1] - The radial coordinate (length).
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
setToPolar: function (azimuth, radius)
|
|
{
|
|
if (radius == null) { radius = 1; }
|
|
|
|
this.x = Math.cos(azimuth) * radius;
|
|
this.y = Math.sin(azimuth) * radius;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Check whether this Vector is equal to a given Vector.
|
|
*
|
|
* Performs a strict equality check against each Vector's components.
|
|
*
|
|
* @method Phaser.Math.Vector2#equals
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} v - The vector to compare with this Vector.
|
|
*
|
|
* @return {boolean} Whether the given Vector is equal to this Vector.
|
|
*/
|
|
equals: function (v)
|
|
{
|
|
return ((this.x === v.x) && (this.y === v.y));
|
|
},
|
|
|
|
/**
|
|
* Check whether this Vector is approximately equal to a given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#fuzzyEquals
|
|
* @since 3.23.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} v - The vector to compare with this Vector.
|
|
* @param {number} [epsilon=0.0001] - The tolerance value.
|
|
*
|
|
* @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`.
|
|
*/
|
|
fuzzyEquals: function (v, epsilon)
|
|
{
|
|
return (FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon));
|
|
},
|
|
|
|
/**
|
|
* Calculate the angle between this Vector and the positive x-axis, in radians.
|
|
*
|
|
* @method Phaser.Math.Vector2#angle
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The angle between this Vector, and the positive x-axis, given in radians.
|
|
*/
|
|
angle: function ()
|
|
{
|
|
// computes the angle in radians with respect to the positive x-axis
|
|
|
|
var angle = Math.atan2(this.y, this.x);
|
|
|
|
if (angle < 0)
|
|
{
|
|
angle += 2 * Math.PI;
|
|
}
|
|
|
|
return angle;
|
|
},
|
|
|
|
/**
|
|
* Set the angle of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#setAngle
|
|
* @since 3.23.0
|
|
*
|
|
* @param {number} angle - The angle, in radians.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
setAngle: function (angle)
|
|
{
|
|
return this.setToPolar(angle, this.length());
|
|
},
|
|
|
|
/**
|
|
* Add a given Vector to this Vector. Addition is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector2#add
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to add to this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
add: function (src)
|
|
{
|
|
this.x += src.x;
|
|
this.y += src.y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Subtract the given Vector from this Vector. Subtraction is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector2#subtract
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to subtract from this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
subtract: function (src)
|
|
{
|
|
this.x -= src.x;
|
|
this.y -= src.y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise multiplication between this Vector and the given Vector.
|
|
*
|
|
* Multiplies this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to multiply this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
multiply: function (src)
|
|
{
|
|
this.x *= src.x;
|
|
this.y *= src.y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Scale this Vector by the given value.
|
|
*
|
|
* @method Phaser.Math.Vector2#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to scale this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
scale: function (value)
|
|
{
|
|
if (isFinite(value))
|
|
{
|
|
this.x *= value;
|
|
this.y *= value;
|
|
}
|
|
else
|
|
{
|
|
this.x = 0;
|
|
this.y = 0;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise division between this Vector and the given Vector.
|
|
*
|
|
* Divides this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#divide
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to divide this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
divide: function (src)
|
|
{
|
|
this.x /= src.x;
|
|
this.y /= src.y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Negate the `x` and `y` components of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#negate
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
negate: function ()
|
|
{
|
|
this.x = -this.x;
|
|
this.y = -this.y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#distance
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector.
|
|
*/
|
|
distance: function (src)
|
|
{
|
|
var dx = src.x - this.x;
|
|
var dy = src.y - this.y;
|
|
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector, squared.
|
|
*
|
|
* @method Phaser.Math.Vector2#distanceSq
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector, squared.
|
|
*/
|
|
distanceSq: function (src)
|
|
{
|
|
var dx = src.x - this.x;
|
|
var dy = src.y - this.y;
|
|
|
|
return dx * dx + dy * dy;
|
|
},
|
|
|
|
/**
|
|
* Calculate the length (or magnitude) of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#length
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector.
|
|
*/
|
|
length: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
|
|
return Math.sqrt(x * x + y * y);
|
|
},
|
|
|
|
/**
|
|
* Set the length (or magnitude) of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#setLength
|
|
* @since 3.23.0
|
|
*
|
|
* @param {number} length
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
setLength: function (length)
|
|
{
|
|
return this.normalize().scale(length);
|
|
},
|
|
|
|
/**
|
|
* Calculate the length of this Vector squared.
|
|
*
|
|
* @method Phaser.Math.Vector2#lengthSq
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector, squared.
|
|
*/
|
|
lengthSq: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
|
|
return x * x + y * y;
|
|
},
|
|
|
|
/**
|
|
* Normalize this Vector.
|
|
*
|
|
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
|
|
*
|
|
* @method Phaser.Math.Vector2#normalize
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
normalize: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var len = x * x + y * y;
|
|
|
|
if (len > 0)
|
|
{
|
|
len = 1 / Math.sqrt(len);
|
|
|
|
this.x = x * len;
|
|
this.y = y * len;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this Vector to its perpendicular, in the positive direction.
|
|
*
|
|
* @method Phaser.Math.Vector2#normalizeRightHand
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
normalizeRightHand: function ()
|
|
{
|
|
var x = this.x;
|
|
|
|
this.x = this.y * -1;
|
|
this.y = x;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this Vector to its perpendicular, in the negative direction.
|
|
*
|
|
* @method Phaser.Math.Vector2#normalizeLeftHand
|
|
* @since 3.23.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
normalizeLeftHand: function ()
|
|
{
|
|
var x = this.x;
|
|
|
|
this.x = this.y;
|
|
this.y = x * -1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the dot product of this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#dot
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector2 to dot product with this Vector2.
|
|
*
|
|
* @return {number} The dot product of this Vector and the given Vector.
|
|
*/
|
|
dot: function (src)
|
|
{
|
|
return this.x * src.x + this.y * src.y;
|
|
},
|
|
|
|
/**
|
|
* Calculate the cross product of this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#cross
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector2 to cross with this Vector2.
|
|
*
|
|
* @return {number} The cross product of this Vector and the given Vector.
|
|
*/
|
|
cross: function (src)
|
|
{
|
|
return this.x * src.y - this.y * src.x;
|
|
},
|
|
|
|
/**
|
|
* Linearly interpolate between this Vector and the given Vector.
|
|
*
|
|
* Interpolates this Vector towards the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#lerp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} src - The Vector2 to interpolate towards.
|
|
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
lerp: function (src, t)
|
|
{
|
|
if (t === undefined) { t = 0; }
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
|
|
this.x = ax + t * (src.x - ax);
|
|
this.y = ay + t * (src.y - ay);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Vector2#transformMat3
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
transformMat3: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var m = mat.val;
|
|
|
|
this.x = m[0] * x + m[3] * y + m[6];
|
|
this.y = m[1] * x + m[4] * y + m[7];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Vector2#transformMat4
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
transformMat4: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var m = mat.val;
|
|
|
|
this.x = m[0] * x + m[4] * y + m[12];
|
|
this.y = m[1] * x + m[5] * y + m[13];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Make this Vector the zero vector (0, 0).
|
|
*
|
|
* @method Phaser.Math.Vector2#reset
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
reset: function ()
|
|
{
|
|
this.x = 0;
|
|
this.y = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Limit the length (or magnitude) of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector2#limit
|
|
* @since 3.23.0
|
|
*
|
|
* @param {number} max - The maximum length.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
limit: function (max)
|
|
{
|
|
var len = this.length();
|
|
|
|
if (len && len > max)
|
|
{
|
|
this.scale(max / len);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Reflect this Vector off a line defined by a normal.
|
|
*
|
|
* @method Phaser.Math.Vector2#reflect
|
|
* @since 3.23.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
reflect: function (normal)
|
|
{
|
|
normal = normal.clone().normalize();
|
|
|
|
return this.subtract(normal.scale(2 * this.dot(normal)));
|
|
},
|
|
|
|
/**
|
|
* Reflect this Vector across another.
|
|
*
|
|
* @method Phaser.Math.Vector2#mirror
|
|
* @since 3.23.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} axis - A vector to reflect across.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
mirror: function (axis)
|
|
{
|
|
return this.reflect(axis).negate();
|
|
},
|
|
|
|
/**
|
|
* Rotate this Vector by an angle amount.
|
|
*
|
|
* @method Phaser.Math.Vector2#rotate
|
|
* @since 3.23.0
|
|
*
|
|
* @param {number} delta - The angle to rotate by, in radians.
|
|
*
|
|
* @return {Phaser.Math.Vector2} This Vector2.
|
|
*/
|
|
rotate: function (delta)
|
|
{
|
|
var cos = Math.cos(delta);
|
|
var sin = Math.sin(delta);
|
|
|
|
return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y);
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* A static zero Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.ZERO
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.1.0
|
|
*/
|
|
Vector2.ZERO = new Vector2();
|
|
|
|
/**
|
|
* A static right Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.RIGHT
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector2.RIGHT = new Vector2(1, 0);
|
|
|
|
/**
|
|
* A static left Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.LEFT
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector2.LEFT = new Vector2(-1, 0);
|
|
|
|
/**
|
|
* A static up Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.UP
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector2.UP = new Vector2(0, -1);
|
|
|
|
/**
|
|
* A static down Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.DOWN
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector2.DOWN = new Vector2(0, 1);
|
|
|
|
/**
|
|
* A static one Vector2 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector2.ONE
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector2.ONE = new Vector2(1, 1);
|
|
|
|
module.exports = Vector2;
|
|
|
|
|
|
/***/ }),
|
|
/* 3 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MATH_CONST = {
|
|
|
|
/**
|
|
* The value of PI * 2.
|
|
*
|
|
* @name Phaser.Math.PI2
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
PI2: Math.PI * 2,
|
|
|
|
/**
|
|
* The value of PI * 0.5.
|
|
*
|
|
* @name Phaser.Math.TAU
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
TAU: Math.PI * 0.5,
|
|
|
|
/**
|
|
* An epsilon value (1.0e-6)
|
|
*
|
|
* @name Phaser.Math.EPSILON
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
EPSILON: 1.0e-6,
|
|
|
|
/**
|
|
* For converting degrees to radians (PI / 180)
|
|
*
|
|
* @name Phaser.Math.DEG_TO_RAD
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
DEG_TO_RAD: Math.PI / 180,
|
|
|
|
/**
|
|
* For converting radians to degrees (180 / PI)
|
|
*
|
|
* @name Phaser.Math.RAD_TO_DEG
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
RAD_TO_DEG: 180 / Math.PI,
|
|
|
|
/**
|
|
* An instance of the Random Number Generator.
|
|
* This is not set until the Game boots.
|
|
*
|
|
* @name Phaser.Math.RND
|
|
* @type {Phaser.Math.RandomDataGenerator}
|
|
* @since 3.0.0
|
|
*/
|
|
RND: null,
|
|
|
|
/**
|
|
* The minimum safe integer this browser supports.
|
|
* We use a const for backward compatibility with Internet Explorer.
|
|
*
|
|
* @name Phaser.Math.MIN_SAFE_INTEGER
|
|
* @type {number}
|
|
* @since 3.21.0
|
|
*/
|
|
MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER || -9007199254740991,
|
|
|
|
/**
|
|
* The maximum safe integer this browser supports.
|
|
* We use a const for backward compatibility with Internet Explorer.
|
|
*
|
|
* @name Phaser.Math.MAX_SAFE_INTEGER
|
|
* @type {number}
|
|
* @since 3.21.0
|
|
*/
|
|
MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER || 9007199254740991
|
|
|
|
};
|
|
|
|
module.exports = MATH_CONST;
|
|
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Force a value within the boundaries by clamping it to the range `min`, `max`.
|
|
*
|
|
* @function Phaser.Math.Clamp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to be clamped.
|
|
* @param {number} min - The minimum bounds.
|
|
* @param {number} max - The maximum bounds.
|
|
*
|
|
* @return {number} The clamped value.
|
|
*/
|
|
var Clamp = function (value, min, max)
|
|
{
|
|
return Math.max(min, Math.min(max, value));
|
|
};
|
|
|
|
module.exports = Clamp;
|
|
|
|
|
|
/***/ }),
|
|
/* 5 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Tests if the start and end indexes are a safe range for the given array.
|
|
*
|
|
* @function Phaser.Utils.Array.SafeRange
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to check.
|
|
* @param {integer} startIndex - The start index.
|
|
* @param {integer} endIndex - The end index.
|
|
* @param {boolean} [throwError=true] - Throw an error if the range is out of bounds.
|
|
*
|
|
* @return {boolean} True if the range is safe, otherwise false.
|
|
*/
|
|
var SafeRange = function (array, startIndex, endIndex, throwError)
|
|
{
|
|
var len = array.length;
|
|
|
|
if (startIndex < 0 ||
|
|
startIndex > len ||
|
|
startIndex >= endIndex ||
|
|
endIndex > len ||
|
|
startIndex + endIndex > len)
|
|
{
|
|
if (throwError)
|
|
{
|
|
throw new Error('Range Error: Values outside acceptable range');
|
|
}
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
};
|
|
|
|
module.exports = SafeRange;
|
|
|
|
|
|
/***/ }),
|
|
/* 6 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Wrap the given `value` between `min` and `max.
|
|
*
|
|
* @function Phaser.Math.Wrap
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to wrap.
|
|
* @param {number} min - The minimum value.
|
|
* @param {number} max - The maximum value.
|
|
*
|
|
* @return {number} The wrapped value.
|
|
*/
|
|
var Wrap = function (value, min, max)
|
|
{
|
|
var range = max - min;
|
|
|
|
return (min + ((((value - min) % range) + range) % range));
|
|
};
|
|
|
|
module.exports = Wrap;
|
|
|
|
|
|
/***/ }),
|
|
/* 7 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* This is a slightly modified version of jQuery.isPlainObject.
|
|
* A plain object is an object whose internal class property is [object Object].
|
|
*
|
|
* @function Phaser.Utils.Objects.IsPlainObject
|
|
* @since 3.0.0
|
|
*
|
|
* @param {object} obj - The object to inspect.
|
|
*
|
|
* @return {boolean} `true` if the object is plain, otherwise `false`.
|
|
*/
|
|
var IsPlainObject = function (obj)
|
|
{
|
|
// Not plain objects:
|
|
// - Any object or value whose internal [[Class]] property is not "[object Object]"
|
|
// - DOM nodes
|
|
// - window
|
|
if (typeof(obj) !== 'object' || obj.nodeType || obj === obj.window)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Support: Firefox <20
|
|
// The try/catch suppresses exceptions thrown when attempting to access
|
|
// the "constructor" property of certain host objects, ie. |window.location|
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=814622
|
|
try
|
|
{
|
|
if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf'))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
catch (e)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// If the function hasn't returned already, we're confident that
|
|
// |obj| is a plain object, created by {} or constructed with new Object
|
|
return true;
|
|
};
|
|
|
|
module.exports = IsPlainObject;
|
|
|
|
|
|
/***/ }),
|
|
/* 8 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CONST = __webpack_require__(3);
|
|
|
|
/**
|
|
* Takes an angle in Phasers default clockwise format and converts it so that
|
|
* 0 is North, 90 is West, 180 is South and 270 is East,
|
|
* therefore running counter-clockwise instead of clockwise.
|
|
*
|
|
* You can pass in the angle from a Game Object using:
|
|
*
|
|
* ```javascript
|
|
* var converted = CounterClockwise(gameobject.rotation);
|
|
* ```
|
|
*
|
|
* All values for this function are in radians.
|
|
*
|
|
* @function Phaser.Math.Angle.CounterClockwise
|
|
* @since 3.16.0
|
|
*
|
|
* @param {number} angle - The angle to convert, in radians.
|
|
*
|
|
* @return {number} The converted angle, in radians.
|
|
*/
|
|
var CounterClockwise = function (angle)
|
|
{
|
|
if (angle > Math.PI)
|
|
{
|
|
angle -= CONST.PI2;
|
|
}
|
|
|
|
return Math.abs((((angle + CONST.TAU) % CONST.PI2) - CONST.PI2) % CONST.PI2);
|
|
};
|
|
|
|
module.exports = CounterClockwise;
|
|
|
|
|
|
/***/ }),
|
|
/* 9 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CONST = __webpack_require__(3);
|
|
|
|
/**
|
|
* Convert the given angle in radians, to the equivalent angle in degrees.
|
|
*
|
|
* @function Phaser.Math.RadToDeg
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} radians - The angle in radians to convert ot degrees.
|
|
*
|
|
* @return {integer} The given angle converted to degrees.
|
|
*/
|
|
var RadToDeg = function (radians)
|
|
{
|
|
return radians * CONST.RAD_TO_DEG;
|
|
};
|
|
|
|
module.exports = RadToDeg;
|
|
|
|
|
|
/***/ }),
|
|
/* 10 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Source object
|
|
// The key as a string, or an array of keys, i.e. 'banner', or 'banner.hideBanner'
|
|
// The default value to use if the key doesn't exist
|
|
|
|
/**
|
|
* Retrieves a value from an object.
|
|
*
|
|
* @function Phaser.Utils.Objects.GetValue
|
|
* @since 3.0.0
|
|
*
|
|
* @param {object} source - The object to retrieve the value from.
|
|
* @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
|
|
* @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
|
|
*
|
|
* @return {*} The value of the requested key.
|
|
*/
|
|
var GetValue = function (source, key, defaultValue)
|
|
{
|
|
if (!source || typeof source === 'number')
|
|
{
|
|
return defaultValue;
|
|
}
|
|
else if (source.hasOwnProperty(key))
|
|
{
|
|
return source[key];
|
|
}
|
|
else if (key.indexOf('.') !== -1)
|
|
{
|
|
var keys = key.split('.');
|
|
var parent = source;
|
|
var value = defaultValue;
|
|
|
|
// Use for loop here so we can break early
|
|
for (var i = 0; i < keys.length; i++)
|
|
{
|
|
if (parent.hasOwnProperty(keys[i]))
|
|
{
|
|
// Yes it has a key property, let's carry on down
|
|
value = parent[keys[i]];
|
|
|
|
parent = parent[keys[i]];
|
|
}
|
|
else
|
|
{
|
|
// Can't go any further, so reset to default
|
|
value = defaultValue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
};
|
|
|
|
module.exports = GetValue;
|
|
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Finds the key within the top level of the {@link source} object, or returns {@link defaultValue}
|
|
*
|
|
* @function Phaser.Utils.Objects.GetFastValue
|
|
* @since 3.0.0
|
|
*
|
|
* @param {object} source - The object to search
|
|
* @param {string} key - The key for the property on source. Must exist at the top level of the source object (no periods)
|
|
* @param {*} [defaultValue] - The default value to use if the key does not exist.
|
|
*
|
|
* @return {*} The value if found; otherwise, defaultValue (null if none provided)
|
|
*/
|
|
var GetFastValue = function (source, key, defaultValue)
|
|
{
|
|
var t = typeof(source);
|
|
|
|
if (!source || t === 'number' || t === 'string')
|
|
{
|
|
return defaultValue;
|
|
}
|
|
else if (source.hasOwnProperty(key) && source[key] !== undefined)
|
|
{
|
|
return source[key];
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
};
|
|
|
|
module.exports = GetFastValue;
|
|
|
|
|
|
/***/ }),
|
|
/* 12 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var GEOM_CONST = __webpack_require__(26);
|
|
|
|
/**
|
|
* @classdesc
|
|
* Defines a Point in 2D space, with an x and y component.
|
|
*
|
|
* @class Point
|
|
* @memberof Phaser.Geom
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The x coordinate of this Point.
|
|
* @param {number} [y=x] - The y coordinate of this Point.
|
|
*/
|
|
var Point = new Class({
|
|
|
|
initialize:
|
|
|
|
function Point (x, y)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = x; }
|
|
|
|
/**
|
|
* The geometry constant type of this object: `GEOM_CONST.POINT`.
|
|
* Used for fast type comparisons.
|
|
*
|
|
* @name Phaser.Geom.Point#type
|
|
* @type {integer}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
this.type = GEOM_CONST.POINT;
|
|
|
|
/**
|
|
* The x coordinate of this Point.
|
|
*
|
|
* @name Phaser.Geom.Point#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.x = x;
|
|
|
|
/**
|
|
* The y coordinate of this Point.
|
|
*
|
|
* @name Phaser.Geom.Point#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.y = y;
|
|
},
|
|
|
|
/**
|
|
* Set the x and y coordinates of the point to the given values.
|
|
*
|
|
* @method Phaser.Geom.Point#setTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The x coordinate of this Point.
|
|
* @param {number} [y=x] - The y coordinate of this Point.
|
|
*
|
|
* @return {this} This Point object.
|
|
*/
|
|
setTo: function (x, y)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Point;
|
|
|
|
|
|
/***/ }),
|
|
/* 13 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A representation of a vector in 3D space.
|
|
*
|
|
* A three-component vector.
|
|
*
|
|
* @class Vector3
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x] - The x component.
|
|
* @param {number} [y] - The y component.
|
|
* @param {number} [z] - The z component.
|
|
*/
|
|
var Vector3 = new Class({
|
|
|
|
initialize:
|
|
|
|
function Vector3 (x, y, z)
|
|
{
|
|
/**
|
|
* The x component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector3#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.x = 0;
|
|
|
|
/**
|
|
* The y component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector3#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.y = 0;
|
|
|
|
/**
|
|
* The z component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector3#z
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.z = 0;
|
|
|
|
if (typeof x === 'object')
|
|
{
|
|
this.x = x.x || 0;
|
|
this.y = x.y || 0;
|
|
this.z = x.z || 0;
|
|
}
|
|
else
|
|
{
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set this Vector to point up.
|
|
*
|
|
* Sets the y component of the vector to 1, and the others to 0.
|
|
*
|
|
* @method Phaser.Math.Vector3#up
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
up: function ()
|
|
{
|
|
this.x = 0;
|
|
this.y = 1;
|
|
this.z = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the components of this Vector to be the `Math.min` result from the given vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#min
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector3 to check the minimum values against.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
min: function (v)
|
|
{
|
|
this.x = Math.min(this.x, v.x);
|
|
this.y = Math.min(this.y, v.y);
|
|
this.z = Math.min(this.z, v.z);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the components of this Vector to be the `Math.max` result from the given vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#max
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector3 to check the maximum values against.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
max: function (v)
|
|
{
|
|
this.x = Math.max(this.x, v.x);
|
|
this.y = Math.max(this.y, v.y);
|
|
this.z = Math.max(this.z, v.z);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Make a clone of this Vector3.
|
|
*
|
|
* @method Phaser.Math.Vector3#clone
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector3} A new Vector3 object containing this Vectors values.
|
|
*/
|
|
clone: function ()
|
|
{
|
|
return new Vector3(this.x, this.y, this.z);
|
|
},
|
|
|
|
/**
|
|
* Adds the two given Vector3s and sets the results into this Vector3.
|
|
*
|
|
* @method Phaser.Math.Vector3#addVectors
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} a - The first Vector to add.
|
|
* @param {Phaser.Math.Vector3} b - The second Vector to add.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
addVectors: function (a, b)
|
|
{
|
|
this.x = a.x + b.x;
|
|
this.y = a.y + b.y;
|
|
this.z = a.z + b.z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the cross (vector) product of two given Vectors.
|
|
*
|
|
* @method Phaser.Math.Vector3#crossVectors
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} a - The first Vector to multiply.
|
|
* @param {Phaser.Math.Vector3} b - The second Vector to multiply.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
crossVectors: function (a, b)
|
|
{
|
|
var ax = a.x;
|
|
var ay = a.y;
|
|
var az = a.z;
|
|
var bx = b.x;
|
|
var by = b.y;
|
|
var bz = b.z;
|
|
|
|
this.x = ay * bz - az * by;
|
|
this.y = az * bx - ax * bz;
|
|
this.z = ax * by - ay * bx;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Check whether this Vector is equal to a given Vector.
|
|
*
|
|
* Performs a strict equality check against each Vector's components.
|
|
*
|
|
* @method Phaser.Math.Vector3#equals
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector3 to compare against.
|
|
*
|
|
* @return {boolean} True if the two vectors strictly match, otherwise false.
|
|
*/
|
|
equals: function (v)
|
|
{
|
|
return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z));
|
|
},
|
|
|
|
/**
|
|
* Copy the components of a given Vector into this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} src - The Vector to copy the components from.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
this.x = src.x;
|
|
this.y = src.y;
|
|
this.z = src.z || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the `x`, `y`, and `z` components of this Vector to the given `x`, `y`, and `z` values.
|
|
*
|
|
* @method Phaser.Math.Vector3#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y and z components.
|
|
* @param {number} [y] - The y value to set for this Vector.
|
|
* @param {number} [z] - The z value to set for this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
set: function (x, y, z)
|
|
{
|
|
if (typeof x === 'object')
|
|
{
|
|
this.x = x.x || 0;
|
|
this.y = x.y || 0;
|
|
this.z = x.z || 0;
|
|
}
|
|
else
|
|
{
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the components of this Vector3 from the position of the given Matrix4.
|
|
*
|
|
* @method Phaser.Math.Vector3#setFromMatrixPosition
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the position from.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
setFromMatrixPosition: function (m)
|
|
{
|
|
return this.fromArray(m.val, 12);
|
|
},
|
|
|
|
/**
|
|
* Sets the components of this Vector3 from the Matrix4 column specified.
|
|
*
|
|
* @method Phaser.Math.Vector3#setFromMatrixColumn
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the column from.
|
|
* @param {number} index - The column index.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
setFromMatrixColumn: function (mat4, index)
|
|
{
|
|
return this.fromArray(mat4.val, index * 4);
|
|
},
|
|
|
|
/**
|
|
* Sets the components of this Vector3 from the given array, based on the offset.
|
|
*
|
|
* Vector3.x = array[offset]
|
|
* Vector3.y = array[offset + 1]
|
|
* Vector3.z = array[offset + 2]
|
|
*
|
|
* @method Phaser.Math.Vector3#fromArray
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number[]} array - The array of values to get this Vector from.
|
|
* @param {number} [offset=0] - The offset index into the array.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
fromArray: function (array, offset)
|
|
{
|
|
if (offset === undefined) { offset = 0; }
|
|
|
|
this.x = array[offset];
|
|
this.y = array[offset + 1];
|
|
this.z = array[offset + 2];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Add a given Vector to this Vector. Addition is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector3#add
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
add: function (v)
|
|
{
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Add the given value to each component of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#addScalar
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number} s - The amount to add to this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
addScalar: function (s)
|
|
{
|
|
this.x += s;
|
|
this.y += s;
|
|
this.z += s;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Add and scale a given Vector to this Vector. Addition is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector3#addScale
|
|
* @since 3.50.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
|
|
* @param {number} scale - The amount to scale `v` by.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
addScale: function (v, scale)
|
|
{
|
|
this.x += v.x * scale;
|
|
this.y += v.y * scale;
|
|
this.z += v.z * scale || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Subtract the given Vector from this Vector. Subtraction is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector3#subtract
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to subtract from this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
subtract: function (v)
|
|
{
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
this.z -= v.z || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise multiplication between this Vector and the given Vector.
|
|
*
|
|
* Multiplies this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to multiply this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
multiply: function (v)
|
|
{
|
|
this.x *= v.x;
|
|
this.y *= v.y;
|
|
this.z *= v.z || 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Scale this Vector by the given value.
|
|
*
|
|
* @method Phaser.Math.Vector3#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} scale - The value to scale this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
scale: function (scale)
|
|
{
|
|
if (isFinite(scale))
|
|
{
|
|
this.x *= scale;
|
|
this.y *= scale;
|
|
this.z *= scale;
|
|
}
|
|
else
|
|
{
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise division between this Vector and the given Vector.
|
|
*
|
|
* Divides this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#divide
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to divide this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
divide: function (v)
|
|
{
|
|
this.x /= v.x;
|
|
this.y /= v.y;
|
|
this.z /= v.z || 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Negate the `x`, `y` and `z` components of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#negate
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
negate: function ()
|
|
{
|
|
this.x = -this.x;
|
|
this.y = -this.y;
|
|
this.z = -this.z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#distance
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector.
|
|
*/
|
|
distance: function (v)
|
|
{
|
|
var dx = v.x - this.x;
|
|
var dy = v.y - this.y;
|
|
var dz = v.z - this.z || 0;
|
|
|
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector, squared.
|
|
*
|
|
* @method Phaser.Math.Vector3#distanceSq
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector, squared.
|
|
*/
|
|
distanceSq: function (v)
|
|
{
|
|
var dx = v.x - this.x;
|
|
var dy = v.y - this.y;
|
|
var dz = v.z - this.z || 0;
|
|
|
|
return dx * dx + dy * dy + dz * dz;
|
|
},
|
|
|
|
/**
|
|
* Calculate the length (or magnitude) of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#length
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector.
|
|
*/
|
|
length: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
|
|
return Math.sqrt(x * x + y * y + z * z);
|
|
},
|
|
|
|
/**
|
|
* Calculate the length of this Vector squared.
|
|
*
|
|
* @method Phaser.Math.Vector3#lengthSq
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector, squared.
|
|
*/
|
|
lengthSq: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
|
|
return x * x + y * y + z * z;
|
|
},
|
|
|
|
/**
|
|
* Normalize this Vector.
|
|
*
|
|
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
|
|
*
|
|
* @method Phaser.Math.Vector3#normalize
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
normalize: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var len = x * x + y * y + z * z;
|
|
|
|
if (len > 0)
|
|
{
|
|
len = 1 / Math.sqrt(len);
|
|
|
|
this.x = x * len;
|
|
this.y = y * len;
|
|
this.z = z * len;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the dot product of this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#dot
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector3 to dot product with this Vector3.
|
|
*
|
|
* @return {number} The dot product of this Vector and `v`.
|
|
*/
|
|
dot: function (v)
|
|
{
|
|
return this.x * v.x + this.y * v.y + this.z * v.z;
|
|
},
|
|
|
|
/**
|
|
* Calculate the cross (vector) product of this Vector (which will be modified) and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#cross
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector to cross product with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
cross: function (v)
|
|
{
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var bx = v.x;
|
|
var by = v.y;
|
|
var bz = v.z;
|
|
|
|
this.x = ay * bz - az * by;
|
|
this.y = az * bx - ax * bz;
|
|
this.z = ax * by - ay * bx;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Linearly interpolate between this Vector and the given Vector.
|
|
*
|
|
* Interpolates this Vector towards the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector3#lerp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} v - The Vector3 to interpolate towards.
|
|
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
lerp: function (v, t)
|
|
{
|
|
if (t === undefined) { t = 0; }
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
|
|
this.x = ax + t * (v.x - ax);
|
|
this.y = ay + t * (v.y - ay);
|
|
this.z = az + t * (v.z - az);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Takes a Matrix3 and applies it to this Vector3.
|
|
*
|
|
* @method Phaser.Math.Vector3#applyMatrix3
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} mat3 - The Matrix3 to apply to this Vector3.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
applyMatrix3: function (mat3)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat3.val;
|
|
|
|
this.x = m[0] * x + m[3] * y + m[6] * z;
|
|
this.y = m[1] * x + m[4] * y + m[7] * z;
|
|
this.z = m[2] * x + m[5] * y + m[8] * z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Takes a Matrix4 and applies it to this Vector3.
|
|
*
|
|
* @method Phaser.Math.Vector3#applyMatrix4
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to apply to this Vector3.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
applyMatrix4: function (mat4)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat4.val;
|
|
|
|
var w = 1 / (m[3] * x + m[7] * y + m[11] * z + m[15]);
|
|
|
|
this.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) * w;
|
|
this.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) * w;
|
|
this.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) * w;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Vector3#transformMat3
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector3 with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
transformMat3: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat.val;
|
|
|
|
this.x = x * m[0] + y * m[3] + z * m[6];
|
|
this.y = x * m[1] + y * m[4] + z * m[7];
|
|
this.z = x * m[2] + y * m[5] + z * m[8];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Matrix4.
|
|
*
|
|
* @method Phaser.Math.Vector3#transformMat4
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
transformMat4: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat.val;
|
|
|
|
this.x = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
this.y = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
this.z = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transforms the coordinates of this Vector3 with the given Matrix4.
|
|
*
|
|
* @method Phaser.Math.Vector3#transformCoordinates
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
transformCoordinates: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat.val;
|
|
|
|
var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12];
|
|
var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13];
|
|
var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14];
|
|
var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15];
|
|
|
|
this.x = tx / tw;
|
|
this.y = ty / tw;
|
|
this.z = tz / tw;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Quaternion.
|
|
*
|
|
* @method Phaser.Math.Vector3#transformQuat
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
transformQuat: function (q)
|
|
{
|
|
// benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var qx = q.x;
|
|
var qy = q.y;
|
|
var qz = q.z;
|
|
var qw = q.w;
|
|
|
|
// calculate quat * vec
|
|
var ix = qw * x + qy * z - qz * y;
|
|
var iy = qw * y + qz * x - qx * z;
|
|
var iz = qw * z + qx * y - qy * x;
|
|
var iw = -qx * x - qy * y - qz * z;
|
|
|
|
// calculate result * inverse quat
|
|
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
|
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
|
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Multiplies this Vector3 by the specified matrix, applying a W divide. This is useful for projection,
|
|
* e.g. unprojecting a 2D point into 3D space.
|
|
*
|
|
* @method Phaser.Math.Vector3#project
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to multiply this Vector3 with.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
project: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var m = mat.val;
|
|
|
|
var a00 = m[0];
|
|
var a01 = m[1];
|
|
var a02 = m[2];
|
|
var a03 = m[3];
|
|
var a10 = m[4];
|
|
var a11 = m[5];
|
|
var a12 = m[6];
|
|
var a13 = m[7];
|
|
var a20 = m[8];
|
|
var a21 = m[9];
|
|
var a22 = m[10];
|
|
var a23 = m[11];
|
|
var a30 = m[12];
|
|
var a31 = m[13];
|
|
var a32 = m[14];
|
|
var a33 = m[15];
|
|
|
|
var lw = 1 / (x * a03 + y * a13 + z * a23 + a33);
|
|
|
|
this.x = (x * a00 + y * a10 + z * a20 + a30) * lw;
|
|
this.y = (x * a01 + y * a11 + z * a21 + a31) * lw;
|
|
this.z = (x * a02 + y * a12 + z * a22 + a32) * lw;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Multiplies this Vector3 by the given view and projection matrices.
|
|
*
|
|
* @method Phaser.Math.Vector3#projectViewMatrix
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} viewMatrix - A View Matrix.
|
|
* @param {Phaser.Math.Matrix4} projectionMatrix - A Projection Matrix.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
projectViewMatrix: function (viewMatrix, projectionMatrix)
|
|
{
|
|
return this.applyMatrix4(viewMatrix).applyMatrix4(projectionMatrix);
|
|
},
|
|
|
|
/**
|
|
* Multiplies this Vector3 by the given inversed projection matrix and world matrix.
|
|
*
|
|
* @method Phaser.Math.Vector3#unprojectViewMatrix
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} projectionMatrix - An inversed Projection Matrix.
|
|
* @param {Phaser.Math.Matrix4} worldMatrix - A World View Matrix.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
unprojectViewMatrix: function (projectionMatrix, worldMatrix)
|
|
{
|
|
return this.applyMatrix4(projectionMatrix).applyMatrix4(worldMatrix);
|
|
},
|
|
|
|
/**
|
|
* Unproject this point from 2D space to 3D space.
|
|
* The point should have its x and y properties set to
|
|
* 2D screen space, and the z either at 0 (near plane)
|
|
* or 1 (far plane). The provided matrix is assumed to already
|
|
* be combined, i.e. projection * view * model.
|
|
*
|
|
* After this operation, this vector's (x, y, z) components will
|
|
* represent the unprojected 3D coordinate.
|
|
*
|
|
* @method Phaser.Math.Vector3#unproject
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} viewport - Screen x, y, width and height in pixels.
|
|
* @param {Phaser.Math.Matrix4} invProjectionView - Combined projection and view matrix.
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
unproject: function (viewport, invProjectionView)
|
|
{
|
|
var viewX = viewport.x;
|
|
var viewY = viewport.y;
|
|
var viewWidth = viewport.z;
|
|
var viewHeight = viewport.w;
|
|
|
|
var x = this.x - viewX;
|
|
var y = (viewHeight - this.y - 1) - viewY;
|
|
var z = this.z;
|
|
|
|
this.x = (2 * x) / viewWidth - 1;
|
|
this.y = (2 * y) / viewHeight - 1;
|
|
this.z = 2 * z - 1;
|
|
|
|
return this.project(invProjectionView);
|
|
},
|
|
|
|
/**
|
|
* Make this Vector the zero vector (0, 0, 0).
|
|
*
|
|
* @method Phaser.Math.Vector3#reset
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector3} This Vector3.
|
|
*/
|
|
reset: function ()
|
|
{
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* A static zero Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.ZERO
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.ZERO = new Vector3();
|
|
|
|
/**
|
|
* A static right Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.RIGHT
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.RIGHT = new Vector3(1, 0, 0);
|
|
|
|
/**
|
|
* A static left Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.LEFT
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.LEFT = new Vector3(-1, 0, 0);
|
|
|
|
/**
|
|
* A static up Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.UP
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.UP = new Vector3(0, -1, 0);
|
|
|
|
/**
|
|
* A static down Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.DOWN
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.DOWN = new Vector3(0, 1, 0);
|
|
|
|
/**
|
|
* A static forward Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.FORWARD
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.FORWARD = new Vector3(0, 0, 1);
|
|
|
|
/**
|
|
* A static back Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.BACK
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.BACK = new Vector3(0, 0, -1);
|
|
|
|
/**
|
|
* A static one Vector3 for use by reference.
|
|
*
|
|
* This constant is meant for comparison operations and should not be modified directly.
|
|
*
|
|
* @constant
|
|
* @name Phaser.Math.Vector3.ONE
|
|
* @type {Phaser.Math.Vector3}
|
|
* @since 3.16.0
|
|
*/
|
|
Vector3.ONE = new Vector3(1, 1, 1);
|
|
|
|
module.exports = Vector3;
|
|
|
|
|
|
/***/ }),
|
|
/* 14 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var FILE_CONST = {
|
|
|
|
/**
|
|
* The Loader is idle.
|
|
*
|
|
* @name Phaser.Loader.LOADER_IDLE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_IDLE: 0,
|
|
|
|
/**
|
|
* The Loader is actively loading.
|
|
*
|
|
* @name Phaser.Loader.LOADER_LOADING
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_LOADING: 1,
|
|
|
|
/**
|
|
* The Loader is processing files is has loaded.
|
|
*
|
|
* @name Phaser.Loader.LOADER_PROCESSING
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_PROCESSING: 2,
|
|
|
|
/**
|
|
* The Loader has completed loading and processing.
|
|
*
|
|
* @name Phaser.Loader.LOADER_COMPLETE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_COMPLETE: 3,
|
|
|
|
/**
|
|
* The Loader is shutting down.
|
|
*
|
|
* @name Phaser.Loader.LOADER_SHUTDOWN
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_SHUTDOWN: 4,
|
|
|
|
/**
|
|
* The Loader has been destroyed.
|
|
*
|
|
* @name Phaser.Loader.LOADER_DESTROYED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOADER_DESTROYED: 5,
|
|
|
|
/**
|
|
* File is in the load queue but not yet started
|
|
*
|
|
* @name Phaser.Loader.FILE_PENDING
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_PENDING: 10,
|
|
|
|
/**
|
|
* File has been started to load by the loader (onLoad called)
|
|
*
|
|
* @name Phaser.Loader.FILE_LOADING
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_LOADING: 11,
|
|
|
|
/**
|
|
* File has loaded successfully, awaiting processing
|
|
*
|
|
* @name Phaser.Loader.FILE_LOADED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_LOADED: 12,
|
|
|
|
/**
|
|
* File failed to load
|
|
*
|
|
* @name Phaser.Loader.FILE_FAILED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_FAILED: 13,
|
|
|
|
/**
|
|
* File is being processed (onProcess callback)
|
|
*
|
|
* @name Phaser.Loader.FILE_PROCESSING
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_PROCESSING: 14,
|
|
|
|
/**
|
|
* The File has errored somehow during processing.
|
|
*
|
|
* @name Phaser.Loader.FILE_ERRORED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_ERRORED: 16,
|
|
|
|
/**
|
|
* File has finished processing.
|
|
*
|
|
* @name Phaser.Loader.FILE_COMPLETE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_COMPLETE: 17,
|
|
|
|
/**
|
|
* File has been destroyed
|
|
*
|
|
* @name Phaser.Loader.FILE_DESTROYED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_DESTROYED: 18,
|
|
|
|
/**
|
|
* File was populated from local data and doesn't need an HTTP request
|
|
*
|
|
* @name Phaser.Loader.FILE_POPULATED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
FILE_POPULATED: 19
|
|
|
|
};
|
|
|
|
module.exports = FILE_CONST;
|
|
|
|
|
|
/***/ }),
|
|
/* 15 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CheckMatrix = __webpack_require__(24);
|
|
var TransposeMatrix = __webpack_require__(55);
|
|
|
|
/**
|
|
* Rotates the array matrix based on the given rotation value.
|
|
*
|
|
* The value can be given in degrees: 90, -90, 270, -270 or 180,
|
|
* or a string command: `rotateLeft`, `rotateRight` or `rotate180`.
|
|
*
|
|
* Based on the routine from {@link http://jsfiddle.net/MrPolywhirl/NH42z/}.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.RotateMatrix
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array to rotate.
|
|
* @param {(number|string)} [direction=90] - The amount to rotate the matrix by.
|
|
*
|
|
* @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
|
|
*/
|
|
var RotateMatrix = function (matrix, direction)
|
|
{
|
|
if (direction === undefined) { direction = 90; }
|
|
|
|
if (!CheckMatrix(matrix))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (typeof direction !== 'string')
|
|
{
|
|
direction = ((direction % 360) + 360) % 360;
|
|
}
|
|
|
|
if (direction === 90 || direction === -270 || direction === 'rotateLeft')
|
|
{
|
|
matrix = TransposeMatrix(matrix);
|
|
matrix.reverse();
|
|
}
|
|
else if (direction === -90 || direction === 270 || direction === 'rotateRight')
|
|
{
|
|
matrix.reverse();
|
|
matrix = TransposeMatrix(matrix);
|
|
}
|
|
else if (Math.abs(direction) === 180 || direction === 'rotate180')
|
|
{
|
|
for (var i = 0; i < matrix.length; i++)
|
|
{
|
|
matrix[i].reverse();
|
|
}
|
|
|
|
matrix.reverse();
|
|
}
|
|
|
|
return matrix;
|
|
};
|
|
|
|
module.exports = RotateMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 16 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Removes a single item from an array and returns it without creating gc, like the native splice does.
|
|
* Based on code by Mike Reinstein.
|
|
*
|
|
* @function Phaser.Utils.Array.SpliceOne
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The array to splice from.
|
|
* @param {integer} index - The index of the item which should be spliced.
|
|
*
|
|
* @return {*} The item which was spliced (removed).
|
|
*/
|
|
var SpliceOne = function (array, index)
|
|
{
|
|
if (index >= array.length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var len = array.length - 1;
|
|
|
|
var item = array[index];
|
|
|
|
for (var i = index; i < len; i++)
|
|
{
|
|
array[i] = array[i + 1];
|
|
}
|
|
|
|
array.length = len;
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = SpliceOne;
|
|
|
|
|
|
/***/ }),
|
|
/* 17 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Phaser Blend Modes.
|
|
*
|
|
* @namespace Phaser.BlendModes
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
* Skips the Blend Mode check in the renderer.
|
|
*
|
|
* @name Phaser.BlendModes.SKIP_CHECK
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SKIP_CHECK: -1,
|
|
|
|
/**
|
|
* Normal blend mode. For Canvas and WebGL.
|
|
* This is the default setting and draws new shapes on top of the existing canvas content.
|
|
*
|
|
* @name Phaser.BlendModes.NORMAL
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
NORMAL: 0,
|
|
|
|
/**
|
|
* Add blend mode. For Canvas and WebGL.
|
|
* Where both shapes overlap the color is determined by adding color values.
|
|
*
|
|
* @name Phaser.BlendModes.ADD
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
ADD: 1,
|
|
|
|
/**
|
|
* Multiply blend mode. For Canvas and WebGL.
|
|
* The pixels are of the top layer are multiplied with the corresponding pixel of the bottom layer. A darker picture is the result.
|
|
*
|
|
* @name Phaser.BlendModes.MULTIPLY
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
MULTIPLY: 2,
|
|
|
|
/**
|
|
* Screen blend mode. For Canvas and WebGL.
|
|
* The pixels are inverted, multiplied, and inverted again. A lighter picture is the result (opposite of multiply)
|
|
*
|
|
* @name Phaser.BlendModes.SCREEN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SCREEN: 3,
|
|
|
|
/**
|
|
* Overlay blend mode. For Canvas only.
|
|
* A combination of multiply and screen. Dark parts on the base layer become darker, and light parts become lighter.
|
|
*
|
|
* @name Phaser.BlendModes.OVERLAY
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
OVERLAY: 4,
|
|
|
|
/**
|
|
* Darken blend mode. For Canvas only.
|
|
* Retains the darkest pixels of both layers.
|
|
*
|
|
* @name Phaser.BlendModes.DARKEN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DARKEN: 5,
|
|
|
|
/**
|
|
* Lighten blend mode. For Canvas only.
|
|
* Retains the lightest pixels of both layers.
|
|
*
|
|
* @name Phaser.BlendModes.LIGHTEN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
LIGHTEN: 6,
|
|
|
|
/**
|
|
* Color Dodge blend mode. For Canvas only.
|
|
* Divides the bottom layer by the inverted top layer.
|
|
*
|
|
* @name Phaser.BlendModes.COLOR_DODGE
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
COLOR_DODGE: 7,
|
|
|
|
/**
|
|
* Color Burn blend mode. For Canvas only.
|
|
* Divides the inverted bottom layer by the top layer, and then inverts the result.
|
|
*
|
|
* @name Phaser.BlendModes.COLOR_BURN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
COLOR_BURN: 8,
|
|
|
|
/**
|
|
* Hard Light blend mode. For Canvas only.
|
|
* A combination of multiply and screen like overlay, but with top and bottom layer swapped.
|
|
*
|
|
* @name Phaser.BlendModes.HARD_LIGHT
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
HARD_LIGHT: 9,
|
|
|
|
/**
|
|
* Soft Light blend mode. For Canvas only.
|
|
* A softer version of hard-light. Pure black or white does not result in pure black or white.
|
|
*
|
|
* @name Phaser.BlendModes.SOFT_LIGHT
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SOFT_LIGHT: 10,
|
|
|
|
/**
|
|
* Difference blend mode. For Canvas only.
|
|
* Subtracts the bottom layer from the top layer or the other way round to always get a positive value.
|
|
*
|
|
* @name Phaser.BlendModes.DIFFERENCE
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DIFFERENCE: 11,
|
|
|
|
/**
|
|
* Exclusion blend mode. For Canvas only.
|
|
* Like difference, but with lower contrast.
|
|
*
|
|
* @name Phaser.BlendModes.EXCLUSION
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
EXCLUSION: 12,
|
|
|
|
/**
|
|
* Hue blend mode. For Canvas only.
|
|
* Preserves the luma and chroma of the bottom layer, while adopting the hue of the top layer.
|
|
*
|
|
* @name Phaser.BlendModes.HUE
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
HUE: 13,
|
|
|
|
/**
|
|
* Saturation blend mode. For Canvas only.
|
|
* Preserves the luma and hue of the bottom layer, while adopting the chroma of the top layer.
|
|
*
|
|
* @name Phaser.BlendModes.SATURATION
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SATURATION: 14,
|
|
|
|
/**
|
|
* Color blend mode. For Canvas only.
|
|
* Preserves the luma of the bottom layer, while adopting the hue and chroma of the top layer.
|
|
*
|
|
* @name Phaser.BlendModes.COLOR
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
COLOR: 15,
|
|
|
|
/**
|
|
* Luminosity blend mode. For Canvas only.
|
|
* Preserves the hue and chroma of the bottom layer, while adopting the luma of the top layer.
|
|
*
|
|
* @name Phaser.BlendModes.LUMINOSITY
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
LUMINOSITY: 16,
|
|
|
|
/**
|
|
* Alpha erase blend mode. For Canvas and WebGL.
|
|
*
|
|
* @name Phaser.BlendModes.ERASE
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
ERASE: 17,
|
|
|
|
/**
|
|
* Source-in blend mode. For Canvas only.
|
|
* The new shape is drawn only where both the new shape and the destination canvas overlap. Everything else is made transparent.
|
|
*
|
|
* @name Phaser.BlendModes.SOURCE_IN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SOURCE_IN: 18,
|
|
|
|
/**
|
|
* Source-out blend mode. For Canvas only.
|
|
* The new shape is drawn where it doesn't overlap the existing canvas content.
|
|
*
|
|
* @name Phaser.BlendModes.SOURCE_OUT
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SOURCE_OUT: 19,
|
|
|
|
/**
|
|
* Source-out blend mode. For Canvas only.
|
|
* The new shape is only drawn where it overlaps the existing canvas content.
|
|
*
|
|
* @name Phaser.BlendModes.SOURCE_ATOP
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
SOURCE_ATOP: 20,
|
|
|
|
/**
|
|
* Destination-over blend mode. For Canvas only.
|
|
* New shapes are drawn behind the existing canvas content.
|
|
*
|
|
* @name Phaser.BlendModes.DESTINATION_OVER
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DESTINATION_OVER: 21,
|
|
|
|
/**
|
|
* Destination-in blend mode. For Canvas only.
|
|
* The existing canvas content is kept where both the new shape and existing canvas content overlap. Everything else is made transparent.
|
|
*
|
|
* @name Phaser.BlendModes.DESTINATION_IN
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DESTINATION_IN: 22,
|
|
|
|
/**
|
|
* Destination-out blend mode. For Canvas only.
|
|
* The existing content is kept where it doesn't overlap the new shape.
|
|
*
|
|
* @name Phaser.BlendModes.DESTINATION_OUT
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DESTINATION_OUT: 23,
|
|
|
|
/**
|
|
* Destination-out blend mode. For Canvas only.
|
|
* The existing canvas is only kept where it overlaps the new shape. The new shape is drawn behind the canvas content.
|
|
*
|
|
* @name Phaser.BlendModes.DESTINATION_ATOP
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
DESTINATION_ATOP: 24,
|
|
|
|
/**
|
|
* Lighten blend mode. For Canvas only.
|
|
* Where both shapes overlap the color is determined by adding color values.
|
|
*
|
|
* @name Phaser.BlendModes.LIGHTER
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
LIGHTER: 25,
|
|
|
|
/**
|
|
* Copy blend mode. For Canvas only.
|
|
* Only the new shape is shown.
|
|
*
|
|
* @name Phaser.BlendModes.COPY
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
COPY: 26,
|
|
|
|
/**
|
|
* Xor blend mode. For Canvas only.
|
|
* Shapes are made transparent where both overlap and drawn normal everywhere else.
|
|
*
|
|
* @name Phaser.BlendModes.XOR
|
|
* @type {integer}
|
|
* @const
|
|
* @since 3.0.0
|
|
*/
|
|
XOR: 27
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 18 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Generate a random floating point number between the two given bounds, minimum inclusive, maximum exclusive.
|
|
*
|
|
* @function Phaser.Math.FloatBetween
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} min - The lower bound for the float, inclusive.
|
|
* @param {number} max - The upper bound for the float exclusive.
|
|
*
|
|
* @return {number} A random float within the given range.
|
|
*/
|
|
var FloatBetween = function (min, max)
|
|
{
|
|
return Math.random() * (max - min) + min;
|
|
};
|
|
|
|
module.exports = FloatBetween;
|
|
|
|
|
|
/***/ }),
|
|
/* 19 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CONST = __webpack_require__(3);
|
|
|
|
/**
|
|
* Convert the given angle from degrees, to the equivalent angle in radians.
|
|
*
|
|
* @function Phaser.Math.DegToRad
|
|
* @since 3.0.0
|
|
*
|
|
* @param {integer} degrees - The angle (in degrees) to convert to radians.
|
|
*
|
|
* @return {number} The given angle converted to radians.
|
|
*/
|
|
var DegToRad = function (degrees)
|
|
{
|
|
return degrees * CONST.DEG_TO_RAD;
|
|
};
|
|
|
|
module.exports = DegToRad;
|
|
|
|
|
|
/***/ }),
|
|
/* 20 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
var Vector3 = __webpack_require__(13);
|
|
|
|
var EPSILON = 0.000001;
|
|
|
|
/**
|
|
* @classdesc
|
|
* A four-dimensional matrix.
|
|
*
|
|
* @class Matrix4
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} [m] - Optional Matrix4 to copy values from.
|
|
*/
|
|
var Matrix4 = new Class({
|
|
|
|
initialize:
|
|
|
|
function Matrix4 (m)
|
|
{
|
|
/**
|
|
* The matrix values.
|
|
*
|
|
* @name Phaser.Math.Matrix4#val
|
|
* @type {Float32Array}
|
|
* @since 3.0.0
|
|
*/
|
|
this.val = new Float32Array(16);
|
|
|
|
if (m)
|
|
{
|
|
// Assume Matrix4 with val:
|
|
this.copy(m);
|
|
}
|
|
else
|
|
{
|
|
// Default to identity
|
|
this.identity();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Make a clone of this Matrix4.
|
|
*
|
|
* @method Phaser.Math.Matrix4#clone
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} A clone of this Matrix4.
|
|
*/
|
|
clone: function ()
|
|
{
|
|
return new Matrix4(this);
|
|
},
|
|
|
|
/**
|
|
* This method is an alias for `Matrix4.copy`.
|
|
*
|
|
* @method Phaser.Math.Matrix4#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} src - The Matrix to set the values of this Matrix's from.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
set: function (src)
|
|
{
|
|
return this.copy(src);
|
|
},
|
|
|
|
/**
|
|
* Copy the values of a given Matrix into this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} src - The Matrix to copy the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
var out = this.val;
|
|
var a = src.val;
|
|
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix from the given array.
|
|
*
|
|
* @method Phaser.Math.Matrix4#fromArray
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} a - The array to copy the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
fromArray: function (a)
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
out[9] = a[9];
|
|
out[10] = a[10];
|
|
out[11] = a[11];
|
|
out[12] = a[12];
|
|
out[13] = a[13];
|
|
out[14] = a[14];
|
|
out[15] = a[15];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Reset this Matrix.
|
|
*
|
|
* Sets all values to `0`.
|
|
*
|
|
* @method Phaser.Math.Matrix4#zero
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
zero: function ()
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 0;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generates a transform matrix based on the given position, scale and rotation.
|
|
*
|
|
* @method Phaser.Math.Matrix4#transform
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} position - The position vector.
|
|
* @param {Phaser.Math.Vector3} scale - The scale vector.
|
|
* @param {Phaser.Math.Quaternion} rotation - The rotation quaternion.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
transform: function (position, scale, rotation)
|
|
{
|
|
// var rotMatrix = rotation.toMatrix4(_tempMat1);
|
|
var rotMatrix = _tempMat1.fromQuat(rotation);
|
|
|
|
var rm = rotMatrix.val;
|
|
var m = this.val;
|
|
|
|
var sx = scale.x;
|
|
var sy = scale.y;
|
|
var sz = scale.z;
|
|
|
|
m[0] = rm[0] * sx;
|
|
m[1] = rm[1] * sx;
|
|
m[2] = rm[2] * sx;
|
|
m[3] = 0;
|
|
|
|
m[4] = rm[4] * sy;
|
|
m[5] = rm[5] * sy;
|
|
m[6] = rm[6] * sy;
|
|
m[7] = 0;
|
|
|
|
m[8] = rm[8] * sz;
|
|
m[9] = rm[9] * sz;
|
|
m[10] = rm[10] * sz;
|
|
m[11] = 0;
|
|
|
|
m[12] = position.x;
|
|
m[13] = position.y;
|
|
m[14] = position.z;
|
|
m[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the `x`, `y` and `z` values of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#xyz
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The x value.
|
|
* @param {number} y - The y value.
|
|
* @param {number} z - The z value.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
xyz: function (x, y, z)
|
|
{
|
|
this.identity();
|
|
|
|
var out = this.val;
|
|
|
|
out[12] = x;
|
|
out[13] = y;
|
|
out[14] = z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the scaling values of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#scaling
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The x scaling value.
|
|
* @param {number} y - The y scaling value.
|
|
* @param {number} z - The z scaling value.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
scaling: function (x, y, z)
|
|
{
|
|
this.zero();
|
|
|
|
var out = this.val;
|
|
|
|
out[0] = x;
|
|
out[5] = y;
|
|
out[10] = z;
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Reset this Matrix to an identity (default) matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#identity
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
identity: function ()
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 0;
|
|
out[5] = 1;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 1;
|
|
out[11] = 0;
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transpose this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#transpose
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
transpose: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
var a23 = a[11];
|
|
|
|
a[1] = a[4];
|
|
a[2] = a[8];
|
|
a[3] = a[12];
|
|
a[4] = a01;
|
|
a[6] = a[9];
|
|
a[7] = a[13];
|
|
a[8] = a02;
|
|
a[9] = a12;
|
|
a[11] = a[14];
|
|
a[12] = a03;
|
|
a[13] = a13;
|
|
a[14] = a23;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Copies the given Matrix4 into this Matrix and then inverses it.
|
|
*
|
|
* @method Phaser.Math.Matrix4#getInverse
|
|
* @since 3.50.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
getInverse: function (m)
|
|
{
|
|
this.copy(m);
|
|
|
|
return this.invert();
|
|
},
|
|
|
|
/**
|
|
* Invert this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#invert
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
invert: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
var a30 = a[12];
|
|
var a31 = a[13];
|
|
var a32 = a[14];
|
|
var a33 = a[15];
|
|
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
|
|
// Calculate the determinant
|
|
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
|
|
if (!det)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
det = 1 / det;
|
|
|
|
a[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
a[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
a[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
a[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
|
|
a[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
a[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
a[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
a[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
|
|
a[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
a[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
a[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
a[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
|
|
a[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
|
|
a[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
|
|
a[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
|
|
a[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the adjoint, or adjugate, of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#adjoint
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
adjoint: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
var a30 = a[12];
|
|
var a31 = a[13];
|
|
var a32 = a[14];
|
|
var a33 = a[15];
|
|
|
|
a[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
|
|
a[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
|
|
a[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
|
|
a[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
|
|
a[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
|
|
a[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
|
|
a[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
|
|
a[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
|
|
a[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
|
|
a[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
|
|
a[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
|
|
a[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
|
|
a[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
|
|
a[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
|
|
a[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
|
|
a[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the determinant of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#determinant
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The determinant of this Matrix.
|
|
*/
|
|
determinant: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
var a30 = a[12];
|
|
var a31 = a[13];
|
|
var a32 = a[14];
|
|
var a33 = a[15];
|
|
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
|
|
// Calculate the determinant
|
|
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
},
|
|
|
|
/**
|
|
* Multiply this Matrix by the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} src - The Matrix to multiply this Matrix by.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
multiply: function (src)
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
var a30 = a[12];
|
|
var a31 = a[13];
|
|
var a32 = a[14];
|
|
var a33 = a[15];
|
|
|
|
var b = src.val;
|
|
|
|
// Cache only the current line of the second matrix
|
|
var b0 = b[0];
|
|
var b1 = b[1];
|
|
var b2 = b[2];
|
|
var b3 = b[3];
|
|
|
|
a[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
a[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
a[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
a[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
|
|
b0 = b[4];
|
|
b1 = b[5];
|
|
b2 = b[6];
|
|
b3 = b[7];
|
|
|
|
a[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
a[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
a[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
a[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
|
|
b0 = b[8];
|
|
b1 = b[9];
|
|
b2 = b[10];
|
|
b3 = b[11];
|
|
|
|
a[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
a[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
a[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
a[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
|
|
b0 = b[12];
|
|
b1 = b[13];
|
|
b2 = b[14];
|
|
b3 = b[15];
|
|
|
|
a[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
a[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
a[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
a[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Multiply the values of this Matrix4 by those given in the `src` argument.
|
|
*
|
|
* @method Phaser.Math.Matrix4#multiplyLocal
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} src - The source Matrix4 that this Matrix4 is multiplied by.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
multiplyLocal: function (src)
|
|
{
|
|
var a = [];
|
|
var m1 = this.val;
|
|
var m2 = src.val;
|
|
|
|
a[0] = m1[0] * m2[0] + m1[1] * m2[4] + m1[2] * m2[8] + m1[3] * m2[12];
|
|
a[1] = m1[0] * m2[1] + m1[1] * m2[5] + m1[2] * m2[9] + m1[3] * m2[13];
|
|
a[2] = m1[0] * m2[2] + m1[1] * m2[6] + m1[2] * m2[10] + m1[3] * m2[14];
|
|
a[3] = m1[0] * m2[3] + m1[1] * m2[7] + m1[2] * m2[11] + m1[3] * m2[15];
|
|
|
|
a[4] = m1[4] * m2[0] + m1[5] * m2[4] + m1[6] * m2[8] + m1[7] * m2[12];
|
|
a[5] = m1[4] * m2[1] + m1[5] * m2[5] + m1[6] * m2[9] + m1[7] * m2[13];
|
|
a[6] = m1[4] * m2[2] + m1[5] * m2[6] + m1[6] * m2[10] + m1[7] * m2[14];
|
|
a[7] = m1[4] * m2[3] + m1[5] * m2[7] + m1[6] * m2[11] + m1[7] * m2[15];
|
|
|
|
a[8] = m1[8] * m2[0] + m1[9] * m2[4] + m1[10] * m2[8] + m1[11] * m2[12];
|
|
a[9] = m1[8] * m2[1] + m1[9] * m2[5] + m1[10] * m2[9] + m1[11] * m2[13];
|
|
a[10] = m1[8] * m2[2] + m1[9] * m2[6] + m1[10] * m2[10] + m1[11] * m2[14];
|
|
a[11] = m1[8] * m2[3] + m1[9] * m2[7] + m1[10] * m2[11] + m1[11] * m2[15];
|
|
|
|
a[12] = m1[12] * m2[0] + m1[13] * m2[4] + m1[14] * m2[8] + m1[15] * m2[12];
|
|
a[13] = m1[12] * m2[1] + m1[13] * m2[5] + m1[14] * m2[9] + m1[15] * m2[13];
|
|
a[14] = m1[12] * m2[2] + m1[13] * m2[6] + m1[14] * m2[10] + m1[15] * m2[14];
|
|
a[15] = m1[12] * m2[3] + m1[13] * m2[7] + m1[14] * m2[11] + m1[15] * m2[15];
|
|
|
|
return this.fromArray(a);
|
|
},
|
|
|
|
/**
|
|
* Multiplies the given Matrix4 object with this Matrix.
|
|
*
|
|
* This is the same as calling `multiplyMatrices(m, this)`.
|
|
*
|
|
* @method Phaser.Math.Matrix4#premultiply
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} m - The Matrix4 to multiply with this one.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
premultiply: function (m)
|
|
{
|
|
return this.multiplyMatrices(m, this);
|
|
},
|
|
|
|
/**
|
|
* Multiplies the two given Matrix4 objects and stores the results in this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#multiplyMatrices
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} a - The first Matrix4 to multiply.
|
|
* @param {Phaser.Math.Matrix4} b - The second Matrix4 to multiply.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
multiplyMatrices: function (a, b)
|
|
{
|
|
var am = a.val;
|
|
var bm = b.val;
|
|
var m = this.val;
|
|
|
|
var a11 = am[0];
|
|
var a12 = am[4];
|
|
var a13 = am[8];
|
|
var a14 = am[12];
|
|
var a21 = am[1];
|
|
var a22 = am[5];
|
|
var a23 = am[9];
|
|
var a24 = am[13];
|
|
var a31 = am[2];
|
|
var a32 = am[6];
|
|
var a33 = am[10];
|
|
var a34 = am[14];
|
|
var a41 = am[3];
|
|
var a42 = am[7];
|
|
var a43 = am[11];
|
|
var a44 = am[15];
|
|
|
|
var b11 = bm[0];
|
|
var b12 = bm[4];
|
|
var b13 = bm[8];
|
|
var b14 = bm[12];
|
|
var b21 = bm[1];
|
|
var b22 = bm[5];
|
|
var b23 = bm[9];
|
|
var b24 = bm[13];
|
|
var b31 = bm[2];
|
|
var b32 = bm[6];
|
|
var b33 = bm[10];
|
|
var b34 = bm[14];
|
|
var b41 = bm[3];
|
|
var b42 = bm[7];
|
|
var b43 = bm[11];
|
|
var b44 = bm[15];
|
|
|
|
m[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
|
|
m[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
|
|
m[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
|
|
m[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
|
|
|
|
m[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
|
|
m[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
|
|
m[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
|
|
m[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
|
|
|
|
m[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
|
|
m[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
|
|
m[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
|
|
m[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
|
|
|
|
m[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
|
|
m[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
|
|
m[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
|
|
m[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Translate this Matrix using the given Vector.
|
|
*
|
|
* @method Phaser.Math.Matrix4#translate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
translate: function (v)
|
|
{
|
|
var x = v.x;
|
|
var y = v.y;
|
|
var z = v.z;
|
|
var a = this.val;
|
|
|
|
a[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
|
|
a[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
|
|
a[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
|
|
a[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Translate this Matrix using the given values.
|
|
*
|
|
* @method Phaser.Math.Matrix4#translateXYZ
|
|
* @since 3.16.0
|
|
*
|
|
* @param {number} x - The x component.
|
|
* @param {number} y - The y component.
|
|
* @param {number} z - The z component.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
translateXYZ: function (x, y, z)
|
|
{
|
|
var a = this.val;
|
|
|
|
a[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
|
|
a[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
|
|
a[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
|
|
a[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a scale transformation to this Matrix.
|
|
*
|
|
* Uses the `x`, `y` and `z` components of the given Vector to scale the Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
scale: function (v)
|
|
{
|
|
var x = v.x;
|
|
var y = v.y;
|
|
var z = v.z;
|
|
var a = this.val;
|
|
|
|
a[0] = a[0] * x;
|
|
a[1] = a[1] * x;
|
|
a[2] = a[2] * x;
|
|
a[3] = a[3] * x;
|
|
|
|
a[4] = a[4] * y;
|
|
a[5] = a[5] * y;
|
|
a[6] = a[6] * y;
|
|
a[7] = a[7] * y;
|
|
|
|
a[8] = a[8] * z;
|
|
a[9] = a[9] * z;
|
|
a[10] = a[10] * z;
|
|
a[11] = a[11] * z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a scale transformation to this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#scaleXYZ
|
|
* @since 3.16.0
|
|
*
|
|
* @param {number} x - The x component.
|
|
* @param {number} y - The y component.
|
|
* @param {number} z - The z component.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
scaleXYZ: function (x, y, z)
|
|
{
|
|
var a = this.val;
|
|
|
|
a[0] = a[0] * x;
|
|
a[1] = a[1] * x;
|
|
a[2] = a[2] * x;
|
|
a[3] = a[3] * x;
|
|
|
|
a[4] = a[4] * y;
|
|
a[5] = a[5] * y;
|
|
a[6] = a[6] * y;
|
|
a[7] = a[7] * y;
|
|
|
|
a[8] = a[8] * z;
|
|
a[9] = a[9] * z;
|
|
a[10] = a[10] * z;
|
|
a[11] = a[11] * z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Derive a rotation matrix around the given axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#makeRotationAxis
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} axis - The rotation axis.
|
|
* @param {number} angle - The rotation angle in radians.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
makeRotationAxis: function (axis, angle)
|
|
{
|
|
// Based on http://www.gamedev.net/reference/articles/article1199.asp
|
|
|
|
var c = Math.cos(angle);
|
|
var s = Math.sin(angle);
|
|
var t = 1 - c;
|
|
var x = axis.x;
|
|
var y = axis.y;
|
|
var z = axis.z;
|
|
var tx = t * x;
|
|
var ty = t * y;
|
|
|
|
this.fromArray([
|
|
tx * x + c, tx * y - s * z, tx * z + s * y, 0,
|
|
tx * y + s * z, ty * y + c, ty * z - s * x, 0,
|
|
tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
|
|
0, 0, 0, 1
|
|
]);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a rotation transformation to this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#rotate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The angle in radians to rotate by.
|
|
* @param {Phaser.Math.Vector3} axis - The axis to rotate upon.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
rotate: function (rad, axis)
|
|
{
|
|
var a = this.val;
|
|
var x = axis.x;
|
|
var y = axis.y;
|
|
var z = axis.z;
|
|
var len = Math.sqrt(x * x + y * y + z * z);
|
|
|
|
if (Math.abs(len) < EPSILON)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
len = 1 / len;
|
|
x *= len;
|
|
y *= len;
|
|
z *= len;
|
|
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
var t = 1 - c;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
// Construct the elements of the rotation matrix
|
|
var b00 = x * x * t + c;
|
|
var b01 = y * x * t + z * s;
|
|
var b02 = z * x * t - y * s;
|
|
|
|
var b10 = x * y * t - z * s;
|
|
var b11 = y * y * t + c;
|
|
var b12 = z * y * t + x * s;
|
|
|
|
var b20 = x * z * t + y * s;
|
|
var b21 = y * z * t - x * s;
|
|
var b22 = z * z * t + c;
|
|
|
|
// Perform rotation-specific matrix multiplication
|
|
a[0] = a00 * b00 + a10 * b01 + a20 * b02;
|
|
a[1] = a01 * b00 + a11 * b01 + a21 * b02;
|
|
a[2] = a02 * b00 + a12 * b01 + a22 * b02;
|
|
a[3] = a03 * b00 + a13 * b01 + a23 * b02;
|
|
a[4] = a00 * b10 + a10 * b11 + a20 * b12;
|
|
a[5] = a01 * b10 + a11 * b11 + a21 * b12;
|
|
a[6] = a02 * b10 + a12 * b11 + a22 * b12;
|
|
a[7] = a03 * b10 + a13 * b11 + a23 * b12;
|
|
a[8] = a00 * b20 + a10 * b21 + a20 * b22;
|
|
a[9] = a01 * b20 + a11 * b21 + a21 * b22;
|
|
a[10] = a02 * b20 + a12 * b21 + a22 * b22;
|
|
a[11] = a03 * b20 + a13 * b21 + a23 * b22;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this matrix on its X axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#rotateX
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The angle in radians to rotate by.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
rotateX: function (rad)
|
|
{
|
|
var a = this.val;
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
a[4] = a10 * c + a20 * s;
|
|
a[5] = a11 * c + a21 * s;
|
|
a[6] = a12 * c + a22 * s;
|
|
a[7] = a13 * c + a23 * s;
|
|
a[8] = a20 * c - a10 * s;
|
|
a[9] = a21 * c - a11 * s;
|
|
a[10] = a22 * c - a12 * s;
|
|
a[11] = a23 * c - a13 * s;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this matrix on its Y axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#rotateY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The angle to rotate by, in radians.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
rotateY: function (rad)
|
|
{
|
|
var a = this.val;
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
a[0] = a00 * c - a20 * s;
|
|
a[1] = a01 * c - a21 * s;
|
|
a[2] = a02 * c - a22 * s;
|
|
a[3] = a03 * c - a23 * s;
|
|
a[8] = a00 * s + a20 * c;
|
|
a[9] = a01 * s + a21 * c;
|
|
a[10] = a02 * s + a22 * c;
|
|
a[11] = a03 * s + a23 * c;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this matrix on its Z axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#rotateZ
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The angle to rotate by, in radians.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
rotateZ: function (rad)
|
|
{
|
|
var a = this.val;
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
// Perform axis-specific matrix multiplication
|
|
a[0] = a00 * c + a10 * s;
|
|
a[1] = a01 * c + a11 * s;
|
|
a[2] = a02 * c + a12 * s;
|
|
a[3] = a03 * c + a13 * s;
|
|
a[4] = a10 * c - a00 * s;
|
|
a[5] = a11 * c - a01 * s;
|
|
a[6] = a12 * c - a02 * s;
|
|
a[7] = a13 * c - a03 * s;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix from the given rotation Quaternion and translation Vector.
|
|
*
|
|
* @method Phaser.Math.Matrix4#fromRotationTranslation
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Quaternion} q - The Quaternion to set rotation from.
|
|
* @param {Phaser.Math.Vector3} v - The Vector to set translation from.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
fromRotationTranslation: function (q, v)
|
|
{
|
|
// Quaternion math
|
|
var out = this.val;
|
|
|
|
var x = q.x;
|
|
var y = q.y;
|
|
var z = q.z;
|
|
var w = q.w;
|
|
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
|
|
out[0] = 1 - (yy + zz);
|
|
out[1] = xy + wz;
|
|
out[2] = xz - wy;
|
|
out[3] = 0;
|
|
|
|
out[4] = xy - wz;
|
|
out[5] = 1 - (xx + zz);
|
|
out[6] = yz + wx;
|
|
out[7] = 0;
|
|
|
|
out[8] = xz + wy;
|
|
out[9] = yz - wx;
|
|
out[10] = 1 - (xx + yy);
|
|
out[11] = 0;
|
|
|
|
out[12] = v.x;
|
|
out[13] = v.y;
|
|
out[14] = v.z;
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix from the given Quaternion.
|
|
*
|
|
* @method Phaser.Math.Matrix4#fromQuat
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
fromQuat: function (q)
|
|
{
|
|
var out = this.val;
|
|
|
|
var x = q.x;
|
|
var y = q.y;
|
|
var z = q.z;
|
|
var w = q.w;
|
|
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
|
|
out[0] = 1 - (yy + zz);
|
|
out[1] = xy + wz;
|
|
out[2] = xz - wy;
|
|
out[3] = 0;
|
|
|
|
out[4] = xy - wz;
|
|
out[5] = 1 - (xx + zz);
|
|
out[6] = yz + wx;
|
|
out[7] = 0;
|
|
|
|
out[8] = xz + wy;
|
|
out[9] = yz - wx;
|
|
out[10] = 1 - (xx + yy);
|
|
out[11] = 0;
|
|
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = 0;
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a frustum matrix with the given bounds.
|
|
*
|
|
* @method Phaser.Math.Matrix4#frustum
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} left - The left bound of the frustum.
|
|
* @param {number} right - The right bound of the frustum.
|
|
* @param {number} bottom - The bottom bound of the frustum.
|
|
* @param {number} top - The top bound of the frustum.
|
|
* @param {number} near - The near bound of the frustum.
|
|
* @param {number} far - The far bound of the frustum.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
frustum: function (left, right, bottom, top, near, far)
|
|
{
|
|
var out = this.val;
|
|
|
|
var rl = 1 / (right - left);
|
|
var tb = 1 / (top - bottom);
|
|
var nf = 1 / (near - far);
|
|
|
|
out[0] = (near * 2) * rl;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
|
|
out[4] = 0;
|
|
out[5] = (near * 2) * tb;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
|
|
out[8] = (right + left) * rl;
|
|
out[9] = (top + bottom) * tb;
|
|
out[10] = (far + near) * nf;
|
|
out[11] = -1;
|
|
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = (far * near * 2) * nf;
|
|
out[15] = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a perspective projection matrix with the given bounds.
|
|
*
|
|
* @method Phaser.Math.Matrix4#perspective
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} fovy - Vertical field of view in radians
|
|
* @param {number} aspect - Aspect ratio. Typically viewport width /height.
|
|
* @param {number} near - Near bound of the frustum.
|
|
* @param {number} far - Far bound of the frustum.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
perspective: function (fovy, aspect, near, far)
|
|
{
|
|
var out = this.val;
|
|
var f = 1.0 / Math.tan(fovy / 2);
|
|
var nf = 1 / (near - far);
|
|
|
|
out[0] = f / aspect;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
|
|
out[4] = 0;
|
|
out[5] = f;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = (far + near) * nf;
|
|
out[11] = -1;
|
|
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = (2 * far * near) * nf;
|
|
out[15] = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a perspective projection matrix with the given bounds.
|
|
*
|
|
* @method Phaser.Math.Matrix4#perspectiveLH
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} width - The width of the frustum.
|
|
* @param {number} height - The height of the frustum.
|
|
* @param {number} near - Near bound of the frustum.
|
|
* @param {number} far - Far bound of the frustum.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
perspectiveLH: function (width, height, near, far)
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = (2 * near) / width;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
|
|
out[4] = 0;
|
|
out[5] = (2 * near) / height;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = -far / (near - far);
|
|
out[11] = 1;
|
|
|
|
out[12] = 0;
|
|
out[13] = 0;
|
|
out[14] = (near * far) / (near - far);
|
|
out[15] = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate an orthogonal projection matrix with the given bounds.
|
|
*
|
|
* @method Phaser.Math.Matrix4#ortho
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} left - The left bound of the frustum.
|
|
* @param {number} right - The right bound of the frustum.
|
|
* @param {number} bottom - The bottom bound of the frustum.
|
|
* @param {number} top - The top bound of the frustum.
|
|
* @param {number} near - The near bound of the frustum.
|
|
* @param {number} far - The far bound of the frustum.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
ortho: function (left, right, bottom, top, near, far)
|
|
{
|
|
var out = this.val;
|
|
var lr = left - right;
|
|
var bt = bottom - top;
|
|
var nf = near - far;
|
|
|
|
// Avoid division by zero
|
|
lr = (lr === 0) ? lr : 1 / lr;
|
|
bt = (bt === 0) ? bt : 1 / bt;
|
|
nf = (nf === 0) ? nf : 1 / nf;
|
|
|
|
out[0] = -2 * lr;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
|
|
out[4] = 0;
|
|
out[5] = -2 * bt;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
|
|
out[8] = 0;
|
|
out[9] = 0;
|
|
out[10] = 2 * nf;
|
|
out[11] = 0;
|
|
|
|
out[12] = (left + right) * lr;
|
|
out[13] = (top + bottom) * bt;
|
|
out[14] = (far + near) * nf;
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a right-handed look-at matrix with the given eye position, target and up axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#lookAtRH
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} eye - Position of the viewer.
|
|
* @param {Phaser.Math.Vector3} target - Point the viewer is looking at.
|
|
* @param {Phaser.Math.Vector3} up - vec3 pointing up.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
lookAtRH: function (eye, target, up)
|
|
{
|
|
var m = this.val;
|
|
|
|
_z.subVectors(eye, target);
|
|
|
|
if (_z.getLengthSquared() === 0)
|
|
{
|
|
// eye and target are in the same position
|
|
_z.z = 1;
|
|
}
|
|
|
|
_z.normalize();
|
|
_x.crossVectors(up, _z);
|
|
|
|
if (_x.getLengthSquared() === 0)
|
|
{
|
|
// up and z are parallel
|
|
|
|
if (Math.abs(up.z) === 1)
|
|
{
|
|
_z.x += 0.0001;
|
|
}
|
|
else
|
|
{
|
|
_z.z += 0.0001;
|
|
}
|
|
|
|
_z.normalize();
|
|
_x.crossVectors(up, _z);
|
|
}
|
|
|
|
_x.normalize();
|
|
_y.crossVectors(_z, _x);
|
|
|
|
m[0] = _x.x;
|
|
m[1] = _x.y;
|
|
m[2] = _x.z;
|
|
m[4] = _y.x;
|
|
m[5] = _y.y;
|
|
m[6] = _y.z;
|
|
m[8] = _z.x;
|
|
m[9] = _z.y;
|
|
m[10] = _z.z;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a look-at matrix with the given eye position, focal point, and up axis.
|
|
*
|
|
* @method Phaser.Math.Matrix4#lookAt
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} eye - Position of the viewer
|
|
* @param {Phaser.Math.Vector3} center - Point the viewer is looking at
|
|
* @param {Phaser.Math.Vector3} up - vec3 pointing up.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
lookAt: function (eye, center, up)
|
|
{
|
|
var out = this.val;
|
|
|
|
var eyex = eye.x;
|
|
var eyey = eye.y;
|
|
var eyez = eye.z;
|
|
|
|
var upx = up.x;
|
|
var upy = up.y;
|
|
var upz = up.z;
|
|
|
|
var centerx = center.x;
|
|
var centery = center.y;
|
|
var centerz = center.z;
|
|
|
|
if (Math.abs(eyex - centerx) < EPSILON &&
|
|
Math.abs(eyey - centery) < EPSILON &&
|
|
Math.abs(eyez - centerz) < EPSILON)
|
|
{
|
|
return this.identity();
|
|
}
|
|
|
|
var z0 = eyex - centerx;
|
|
var z1 = eyey - centery;
|
|
var z2 = eyez - centerz;
|
|
|
|
var len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
|
|
|
|
z0 *= len;
|
|
z1 *= len;
|
|
z2 *= len;
|
|
|
|
var x0 = upy * z2 - upz * z1;
|
|
var x1 = upz * z0 - upx * z2;
|
|
var x2 = upx * z1 - upy * z0;
|
|
|
|
len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
|
|
|
|
if (!len)
|
|
{
|
|
x0 = 0;
|
|
x1 = 0;
|
|
x2 = 0;
|
|
}
|
|
else
|
|
{
|
|
len = 1 / len;
|
|
x0 *= len;
|
|
x1 *= len;
|
|
x2 *= len;
|
|
}
|
|
|
|
var y0 = z1 * x2 - z2 * x1;
|
|
var y1 = z2 * x0 - z0 * x2;
|
|
var y2 = z0 * x1 - z1 * x0;
|
|
|
|
len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
|
|
|
|
if (!len)
|
|
{
|
|
y0 = 0;
|
|
y1 = 0;
|
|
y2 = 0;
|
|
}
|
|
else
|
|
{
|
|
len = 1 / len;
|
|
y0 *= len;
|
|
y1 *= len;
|
|
y2 *= len;
|
|
}
|
|
|
|
out[0] = x0;
|
|
out[1] = y0;
|
|
out[2] = z0;
|
|
out[3] = 0;
|
|
|
|
out[4] = x1;
|
|
out[5] = y1;
|
|
out[6] = z1;
|
|
out[7] = 0;
|
|
|
|
out[8] = x2;
|
|
out[9] = y2;
|
|
out[10] = z2;
|
|
out[11] = 0;
|
|
|
|
out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
|
|
out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
|
|
out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
|
|
out[15] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this matrix from the given `yaw`, `pitch` and `roll` values.
|
|
*
|
|
* @method Phaser.Math.Matrix4#yawPitchRoll
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} yaw - The yaw value.
|
|
* @param {number} pitch - The pitch value.
|
|
* @param {number} roll - The roll value.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
yawPitchRoll: function (yaw, pitch, roll)
|
|
{
|
|
this.zero();
|
|
_tempMat1.zero();
|
|
_tempMat2.zero();
|
|
|
|
var m0 = this.val;
|
|
var m1 = _tempMat1.val;
|
|
var m2 = _tempMat2.val;
|
|
|
|
// Rotate Z
|
|
var s = Math.sin(roll);
|
|
var c = Math.cos(roll);
|
|
|
|
m0[10] = 1;
|
|
m0[15] = 1;
|
|
m0[0] = c;
|
|
m0[1] = s;
|
|
m0[4] = -s;
|
|
m0[5] = c;
|
|
|
|
// Rotate X
|
|
s = Math.sin(pitch);
|
|
c = Math.cos(pitch);
|
|
|
|
m1[0] = 1;
|
|
m1[15] = 1;
|
|
m1[5] = c;
|
|
m1[10] = c;
|
|
m1[9] = -s;
|
|
m1[6] = s;
|
|
|
|
// Rotate Y
|
|
s = Math.sin(yaw);
|
|
c = Math.cos(yaw);
|
|
|
|
m2[5] = 1;
|
|
m2[15] = 1;
|
|
m2[0] = c;
|
|
m2[2] = -s;
|
|
m2[8] = s;
|
|
m2[10] = c;
|
|
|
|
this.multiplyLocal(_tempMat1);
|
|
this.multiplyLocal(_tempMat2);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Generate a world matrix from the given rotation, position, scale, view matrix and projection matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix4#setWorldMatrix
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} rotation - The rotation of the world matrix.
|
|
* @param {Phaser.Math.Vector3} position - The position of the world matrix.
|
|
* @param {Phaser.Math.Vector3} scale - The scale of the world matrix.
|
|
* @param {Phaser.Math.Matrix4} [viewMatrix] - The view matrix.
|
|
* @param {Phaser.Math.Matrix4} [projectionMatrix] - The projection matrix.
|
|
*
|
|
* @return {Phaser.Math.Matrix4} This Matrix4.
|
|
*/
|
|
setWorldMatrix: function (rotation, position, scale, viewMatrix, projectionMatrix)
|
|
{
|
|
this.yawPitchRoll(rotation.y, rotation.x, rotation.z);
|
|
|
|
_tempMat1.scaling(scale.x, scale.y, scale.z);
|
|
_tempMat2.xyz(position.x, position.y, position.z);
|
|
|
|
this.multiplyLocal(_tempMat1);
|
|
this.multiplyLocal(_tempMat2);
|
|
|
|
if (viewMatrix !== undefined)
|
|
{
|
|
this.multiplyLocal(viewMatrix);
|
|
}
|
|
|
|
if (projectionMatrix !== undefined)
|
|
{
|
|
this.multiplyLocal(projectionMatrix);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Returns the maximum axis scale from this Matrix4.
|
|
*
|
|
* @method Phaser.Math.Matrix4#getMaxScaleOnAxis
|
|
* @since 3.50.0
|
|
*
|
|
* @return {number} The maximum axis scale.
|
|
*/
|
|
getMaxScaleOnAxis: function ()
|
|
{
|
|
var m = this.val;
|
|
|
|
var scaleXSq = m[0] * m[0] + m[1] * m[1] + m[2] * m[2];
|
|
var scaleYSq = m[4] * m[4] + m[5] * m[5] + m[6] * m[6];
|
|
var scaleZSq = m[8] * m[8] + m[9] * m[9] + m[10] * m[10];
|
|
|
|
return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
|
|
}
|
|
|
|
});
|
|
|
|
var _tempMat1 = new Matrix4();
|
|
var _tempMat2 = new Matrix4();
|
|
|
|
var _x = new Vector3();
|
|
var _y = new Vector3();
|
|
var _z = new Vector3();
|
|
|
|
module.exports = Matrix4;
|
|
|
|
|
|
/***/ }),
|
|
/* 21 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var CONST = __webpack_require__(14);
|
|
var Events = __webpack_require__(202);
|
|
var GetFastValue = __webpack_require__(11);
|
|
var GetURL = __webpack_require__(213);
|
|
var MergeXHRSettings = __webpack_require__(44);
|
|
var XHRLoader = __webpack_require__(214);
|
|
var XHRSettings = __webpack_require__(45);
|
|
|
|
/**
|
|
* @classdesc
|
|
* The base File class used by all File Types that the Loader can support.
|
|
* You shouldn't create an instance of a File directly, but should extend it with your own class, setting a custom type and processing methods.
|
|
*
|
|
* @class File
|
|
* @memberof Phaser.Loader
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File.
|
|
* @param {Phaser.Types.Loader.FileConfig} fileConfig - The file configuration object, as created by the file type.
|
|
*/
|
|
var File = new Class({
|
|
|
|
initialize:
|
|
|
|
function File (loader, fileConfig)
|
|
{
|
|
/**
|
|
* A reference to the Loader that is going to load this file.
|
|
*
|
|
* @name Phaser.Loader.File#loader
|
|
* @type {Phaser.Loader.LoaderPlugin}
|
|
* @since 3.0.0
|
|
*/
|
|
this.loader = loader;
|
|
|
|
/**
|
|
* A reference to the Cache, or Texture Manager, that is going to store this file if it loads.
|
|
*
|
|
* @name Phaser.Loader.File#cache
|
|
* @type {(Phaser.Cache.BaseCache|Phaser.Textures.TextureManager)}
|
|
* @since 3.7.0
|
|
*/
|
|
this.cache = GetFastValue(fileConfig, 'cache', false);
|
|
|
|
/**
|
|
* The file type string (image, json, etc) for sorting within the Loader.
|
|
*
|
|
* @name Phaser.Loader.File#type
|
|
* @type {string}
|
|
* @since 3.0.0
|
|
*/
|
|
this.type = GetFastValue(fileConfig, 'type', false);
|
|
|
|
/**
|
|
* Unique cache key (unique within its file type)
|
|
*
|
|
* @name Phaser.Loader.File#key
|
|
* @type {string}
|
|
* @since 3.0.0
|
|
*/
|
|
this.key = GetFastValue(fileConfig, 'key', false);
|
|
|
|
var loadKey = this.key;
|
|
|
|
if (loader.prefix && loader.prefix !== '')
|
|
{
|
|
this.key = loader.prefix + loadKey;
|
|
}
|
|
|
|
if (!this.type || !this.key)
|
|
{
|
|
throw new Error('Invalid Loader.' + this.type + ' key');
|
|
}
|
|
|
|
var url = GetFastValue(fileConfig, 'url');
|
|
|
|
if (url === undefined)
|
|
{
|
|
url = loader.path + loadKey + '.' + GetFastValue(fileConfig, 'extension', '');
|
|
}
|
|
else if (typeof url === 'string' && !url.match(/^(?:blob:|data:|http:\/\/|https:\/\/|\/\/)/))
|
|
{
|
|
url = loader.path + url;
|
|
}
|
|
|
|
/**
|
|
* The URL of the file, not including baseURL.
|
|
*
|
|
* Automatically has Loader.path prepended to it if a string.
|
|
*
|
|
* Can also be a JavaScript Object, such as the results of parsing JSON data.
|
|
*
|
|
* @name Phaser.Loader.File#url
|
|
* @type {object|string}
|
|
* @since 3.0.0
|
|
*/
|
|
this.url = url;
|
|
|
|
/**
|
|
* The final URL this file will load from, including baseURL and path.
|
|
* Set automatically when the Loader calls 'load' on this file.
|
|
*
|
|
* @name Phaser.Loader.File#src
|
|
* @type {string}
|
|
* @since 3.0.0
|
|
*/
|
|
this.src = '';
|
|
|
|
/**
|
|
* The merged XHRSettings for this file.
|
|
*
|
|
* @name Phaser.Loader.File#xhrSettings
|
|
* @type {Phaser.Types.Loader.XHRSettingsObject}
|
|
* @since 3.0.0
|
|
*/
|
|
this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined));
|
|
|
|
if (GetFastValue(fileConfig, 'xhrSettings', false))
|
|
{
|
|
this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {}));
|
|
}
|
|
|
|
/**
|
|
* The XMLHttpRequest instance (as created by XHR Loader) that is loading this File.
|
|
*
|
|
* @name Phaser.Loader.File#xhrLoader
|
|
* @type {?XMLHttpRequest}
|
|
* @since 3.0.0
|
|
*/
|
|
this.xhrLoader = null;
|
|
|
|
/**
|
|
* The current state of the file. One of the FILE_CONST values.
|
|
*
|
|
* @name Phaser.Loader.File#state
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
this.state = (typeof(this.url) === 'function') ? CONST.FILE_POPULATED : CONST.FILE_PENDING;
|
|
|
|
/**
|
|
* The total size of this file.
|
|
* Set by onProgress and only if loading via XHR.
|
|
*
|
|
* @name Phaser.Loader.File#bytesTotal
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.bytesTotal = 0;
|
|
|
|
/**
|
|
* Updated as the file loads.
|
|
* Only set if loading via XHR.
|
|
*
|
|
* @name Phaser.Loader.File#bytesLoaded
|
|
* @type {number}
|
|
* @default -1
|
|
* @since 3.0.0
|
|
*/
|
|
this.bytesLoaded = -1;
|
|
|
|
/**
|
|
* A percentage value between 0 and 1 indicating how much of this file has loaded.
|
|
* Only set if loading via XHR.
|
|
*
|
|
* @name Phaser.Loader.File#percentComplete
|
|
* @type {number}
|
|
* @default -1
|
|
* @since 3.0.0
|
|
*/
|
|
this.percentComplete = -1;
|
|
|
|
/**
|
|
* For CORs based loading.
|
|
* If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set)
|
|
*
|
|
* @name Phaser.Loader.File#crossOrigin
|
|
* @type {(string|undefined)}
|
|
* @since 3.0.0
|
|
*/
|
|
this.crossOrigin = undefined;
|
|
|
|
/**
|
|
* The processed file data, stored here after the file has loaded.
|
|
*
|
|
* @name Phaser.Loader.File#data
|
|
* @type {*}
|
|
* @since 3.0.0
|
|
*/
|
|
this.data = undefined;
|
|
|
|
/**
|
|
* A config object that can be used by file types to store transitional data.
|
|
*
|
|
* @name Phaser.Loader.File#config
|
|
* @type {*}
|
|
* @since 3.0.0
|
|
*/
|
|
this.config = GetFastValue(fileConfig, 'config', {});
|
|
|
|
/**
|
|
* If this is a multipart file, i.e. an atlas and its json together, then this is a reference
|
|
* to the parent MultiFile. Set and used internally by the Loader or specific file types.
|
|
*
|
|
* @name Phaser.Loader.File#multiFile
|
|
* @type {?Phaser.Loader.MultiFile}
|
|
* @since 3.7.0
|
|
*/
|
|
this.multiFile;
|
|
|
|
/**
|
|
* Does this file have an associated linked file? Such as an image and a normal map.
|
|
* Atlases and Bitmap Fonts use the multiFile, because those files need loading together but aren't
|
|
* actually bound by data, where-as a linkFile is.
|
|
*
|
|
* @name Phaser.Loader.File#linkFile
|
|
* @type {?Phaser.Loader.File}
|
|
* @since 3.7.0
|
|
*/
|
|
this.linkFile;
|
|
},
|
|
|
|
/**
|
|
* Links this File with another, so they depend upon each other for loading and processing.
|
|
*
|
|
* @method Phaser.Loader.File#setLink
|
|
* @since 3.7.0
|
|
*
|
|
* @param {Phaser.Loader.File} fileB - The file to link to this one.
|
|
*/
|
|
setLink: function (fileB)
|
|
{
|
|
this.linkFile = fileB;
|
|
|
|
fileB.linkFile = this;
|
|
},
|
|
|
|
/**
|
|
* Resets the XHRLoader instance this file is using.
|
|
*
|
|
* @method Phaser.Loader.File#resetXHR
|
|
* @since 3.0.0
|
|
*/
|
|
resetXHR: function ()
|
|
{
|
|
if (this.xhrLoader)
|
|
{
|
|
this.xhrLoader.onload = undefined;
|
|
this.xhrLoader.onerror = undefined;
|
|
this.xhrLoader.onprogress = undefined;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called by the Loader, starts the actual file downloading.
|
|
* During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
|
|
* You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
|
|
*
|
|
* @method Phaser.Loader.File#load
|
|
* @since 3.0.0
|
|
*/
|
|
load: function ()
|
|
{
|
|
if (this.state === CONST.FILE_POPULATED)
|
|
{
|
|
// Can happen for example in a JSONFile if they've provided a JSON object instead of a URL
|
|
this.loader.nextFile(this, true);
|
|
}
|
|
else
|
|
{
|
|
this.state = CONST.FILE_LOADING;
|
|
|
|
this.src = GetURL(this, this.loader.baseURL);
|
|
|
|
if (this.src.indexOf('data:') === 0)
|
|
{
|
|
console.warn('Local data URIs are not supported: ' + this.key);
|
|
}
|
|
else
|
|
{
|
|
// The creation of this XHRLoader starts the load process going.
|
|
// It will automatically call the following, based on the load outcome:
|
|
//
|
|
// xhr.onload = this.onLoad
|
|
// xhr.onerror = this.onError
|
|
// xhr.onprogress = this.onProgress
|
|
|
|
this.xhrLoader = XHRLoader(this, this.loader.xhr);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called when the file finishes loading, is sent a DOM ProgressEvent.
|
|
*
|
|
* @method Phaser.Loader.File#onLoad
|
|
* @since 3.0.0
|
|
*
|
|
* @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
|
|
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load.
|
|
*/
|
|
onLoad: function (xhr, event)
|
|
{
|
|
var localFileOk = ((xhr.responseURL && xhr.responseURL.indexOf('file://') === 0 && event.target.status === 0));
|
|
|
|
var success = !(event.target && event.target.status !== 200) || localFileOk;
|
|
|
|
// Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called.
|
|
if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599)
|
|
{
|
|
success = false;
|
|
}
|
|
|
|
this.state = CONST.FILE_LOADED;
|
|
|
|
this.resetXHR();
|
|
|
|
this.loader.nextFile(this, success);
|
|
},
|
|
|
|
/**
|
|
* Called if the file errors while loading, is sent a DOM ProgressEvent.
|
|
*
|
|
* @method Phaser.Loader.File#onError
|
|
* @since 3.0.0
|
|
*
|
|
* @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
|
|
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error.
|
|
*/
|
|
onError: function ()
|
|
{
|
|
this.resetXHR();
|
|
|
|
this.loader.nextFile(this, false);
|
|
},
|
|
|
|
/**
|
|
* Called during the file load progress. Is sent a DOM ProgressEvent.
|
|
*
|
|
* @method Phaser.Loader.File#onProgress
|
|
* @fires Phaser.Loader.Events#FILE_PROGRESS
|
|
* @since 3.0.0
|
|
*
|
|
* @param {ProgressEvent} event - The DOM ProgressEvent.
|
|
*/
|
|
onProgress: function (event)
|
|
{
|
|
if (event.lengthComputable)
|
|
{
|
|
this.bytesLoaded = event.loaded;
|
|
this.bytesTotal = event.total;
|
|
|
|
this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1);
|
|
|
|
this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Usually overridden by the FileTypes and is called by Loader.nextFile.
|
|
* This method controls what extra work this File does with its loaded data, for example a JSON file will parse itself during this stage.
|
|
*
|
|
* @method Phaser.Loader.File#onProcess
|
|
* @since 3.0.0
|
|
*/
|
|
onProcess: function ()
|
|
{
|
|
this.state = CONST.FILE_PROCESSING;
|
|
|
|
this.onProcessComplete();
|
|
},
|
|
|
|
/**
|
|
* Called when the File has completed processing.
|
|
* Checks on the state of its multifile, if set.
|
|
*
|
|
* @method Phaser.Loader.File#onProcessComplete
|
|
* @since 3.7.0
|
|
*/
|
|
onProcessComplete: function ()
|
|
{
|
|
this.state = CONST.FILE_COMPLETE;
|
|
|
|
if (this.multiFile)
|
|
{
|
|
this.multiFile.onFileComplete(this);
|
|
}
|
|
|
|
this.loader.fileProcessComplete(this);
|
|
},
|
|
|
|
/**
|
|
* Called when the File has completed processing but it generated an error.
|
|
* Checks on the state of its multifile, if set.
|
|
*
|
|
* @method Phaser.Loader.File#onProcessError
|
|
* @since 3.7.0
|
|
*/
|
|
onProcessError: function ()
|
|
{
|
|
this.state = CONST.FILE_ERRORED;
|
|
|
|
if (this.multiFile)
|
|
{
|
|
this.multiFile.onFileFailed(this);
|
|
}
|
|
|
|
this.loader.fileProcessComplete(this);
|
|
},
|
|
|
|
/**
|
|
* Checks if a key matching the one used by this file exists in the target Cache or not.
|
|
* This is called automatically by the LoaderPlugin to decide if the file can be safely
|
|
* loaded or will conflict.
|
|
*
|
|
* @method Phaser.Loader.File#hasCacheConflict
|
|
* @since 3.7.0
|
|
*
|
|
* @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`.
|
|
*/
|
|
hasCacheConflict: function ()
|
|
{
|
|
return (this.cache && this.cache.exists(this.key));
|
|
},
|
|
|
|
/**
|
|
* Adds this file to its target cache upon successful loading and processing.
|
|
* This method is often overridden by specific file types.
|
|
*
|
|
* @method Phaser.Loader.File#addToCache
|
|
* @since 3.7.0
|
|
*/
|
|
addToCache: function ()
|
|
{
|
|
if (this.cache)
|
|
{
|
|
this.cache.add(this.key, this.data);
|
|
}
|
|
|
|
this.pendingDestroy();
|
|
},
|
|
|
|
/**
|
|
* Called once the file has been added to its cache and is now ready for deletion from the Loader.
|
|
* It will emit a `filecomplete` event from the LoaderPlugin.
|
|
*
|
|
* @method Phaser.Loader.File#pendingDestroy
|
|
* @fires Phaser.Loader.Events#FILE_COMPLETE
|
|
* @fires Phaser.Loader.Events#FILE_KEY_COMPLETE
|
|
* @since 3.7.0
|
|
*/
|
|
pendingDestroy: function (data)
|
|
{
|
|
if (data === undefined) { data = this.data; }
|
|
|
|
var key = this.key;
|
|
var type = this.type;
|
|
|
|
this.loader.emit(Events.FILE_COMPLETE, key, type, data);
|
|
this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type, data);
|
|
|
|
this.loader.flagForRemoval(this);
|
|
},
|
|
|
|
/**
|
|
* Destroy this File and any references it holds.
|
|
*
|
|
* @method Phaser.Loader.File#destroy
|
|
* @since 3.7.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.loader = null;
|
|
this.cache = null;
|
|
this.xhrSettings = null;
|
|
this.multiFile = null;
|
|
this.linkFile = null;
|
|
this.data = null;
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* Static method for creating object URL using URL API and setting it as image 'src' attribute.
|
|
* If URL API is not supported (usually on old browsers) it falls back to creating Base64 encoded url using FileReader.
|
|
*
|
|
* @method Phaser.Loader.File.createObjectURL
|
|
* @static
|
|
* @since 3.7.0
|
|
*
|
|
* @param {HTMLImageElement} image - Image object which 'src' attribute should be set to object URL.
|
|
* @param {Blob} blob - A Blob object to create an object URL for.
|
|
* @param {string} defaultType - Default mime type used if blob type is not available.
|
|
*/
|
|
File.createObjectURL = function (image, blob, defaultType)
|
|
{
|
|
if (typeof URL === 'function')
|
|
{
|
|
image.src = URL.createObjectURL(blob);
|
|
}
|
|
else
|
|
{
|
|
var reader = new FileReader();
|
|
|
|
reader.onload = function ()
|
|
{
|
|
image.removeAttribute('crossOrigin');
|
|
image.src = 'data:' + (blob.type || defaultType) + ';base64,' + reader.result.split(',')[1];
|
|
};
|
|
|
|
reader.onerror = image.onerror;
|
|
|
|
reader.readAsDataURL(blob);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Static method for releasing an existing object URL which was previously created
|
|
* by calling {@link File#createObjectURL} method.
|
|
*
|
|
* @method Phaser.Loader.File.revokeObjectURL
|
|
* @static
|
|
* @since 3.7.0
|
|
*
|
|
* @param {HTMLImageElement} image - Image object which 'src' attribute should be revoked.
|
|
*/
|
|
File.revokeObjectURL = function (image)
|
|
{
|
|
if (typeof URL === 'function')
|
|
{
|
|
URL.revokeObjectURL(image.src);
|
|
}
|
|
};
|
|
|
|
module.exports = File;
|
|
|
|
|
|
/***/ }),
|
|
/* 22 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var types = {};
|
|
|
|
/**
|
|
* @namespace Phaser.Loader.FileTypesManager
|
|
*/
|
|
|
|
var FileTypesManager = {
|
|
|
|
/**
|
|
* Static method called when a LoaderPlugin is created.
|
|
*
|
|
* Loops through the local types object and injects all of them as
|
|
* properties into the LoaderPlugin instance.
|
|
*
|
|
* @method Phaser.Loader.FileTypesManager.install
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - The LoaderPlugin to install the types into.
|
|
*/
|
|
install: function (loader)
|
|
{
|
|
for (var key in types)
|
|
{
|
|
loader[key] = types[key];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Static method called directly by the File Types.
|
|
*
|
|
* The key is a reference to the function used to load the files via the Loader, i.e. `image`.
|
|
*
|
|
* @method Phaser.Loader.FileTypesManager.register
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key - The key that will be used as the method name in the LoaderPlugin.
|
|
* @param {function} factoryFunction - The function that will be called when LoaderPlugin.key is invoked.
|
|
*/
|
|
register: function (key, factoryFunction)
|
|
{
|
|
types[key] = factoryFunction;
|
|
},
|
|
|
|
/**
|
|
* Removed all associated file types.
|
|
*
|
|
* @method Phaser.Loader.FileTypesManager.destroy
|
|
* @since 3.0.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
types = {};
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = FileTypesManager;
|
|
|
|
|
|
/***/ }),
|
|
/* 23 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var MATH_CONST = __webpack_require__(3);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Matrix used for display transformations for rendering.
|
|
*
|
|
* It is represented like so:
|
|
*
|
|
* ```
|
|
* | a | c | tx |
|
|
* | b | d | ty |
|
|
* | 0 | 0 | 1 |
|
|
* ```
|
|
*
|
|
* @class TransformMatrix
|
|
* @memberof Phaser.GameObjects.Components
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [a=1] - The Scale X value.
|
|
* @param {number} [b=0] - The Skew Y value.
|
|
* @param {number} [c=0] - The Skew X value.
|
|
* @param {number} [d=1] - The Scale Y value.
|
|
* @param {number} [tx=0] - The Translate X value.
|
|
* @param {number} [ty=0] - The Translate Y value.
|
|
*/
|
|
var TransformMatrix = new Class({
|
|
|
|
initialize:
|
|
|
|
function TransformMatrix (a, b, c, d, tx, ty)
|
|
{
|
|
if (a === undefined) { a = 1; }
|
|
if (b === undefined) { b = 0; }
|
|
if (c === undefined) { c = 0; }
|
|
if (d === undefined) { d = 1; }
|
|
if (tx === undefined) { tx = 0; }
|
|
if (ty === undefined) { ty = 0; }
|
|
|
|
/**
|
|
* The matrix values.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#matrix
|
|
* @type {Float32Array}
|
|
* @since 3.0.0
|
|
*/
|
|
this.matrix = new Float32Array([ a, b, c, d, tx, ty, 0, 0, 1 ]);
|
|
|
|
/**
|
|
* The decomposed matrix.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#decomposedMatrix
|
|
* @type {object}
|
|
* @since 3.0.0
|
|
*/
|
|
this.decomposedMatrix = {
|
|
translateX: 0,
|
|
translateY: 0,
|
|
scaleX: 1,
|
|
scaleY: 1,
|
|
rotation: 0
|
|
};
|
|
},
|
|
|
|
/**
|
|
* The Scale X value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#a
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
a: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[0];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[0] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Skew Y value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#b
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
b: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[1];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[1] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Skew X value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#c
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
c: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[2];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[2] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Scale Y value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#d
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
d: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[3];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[3] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Translate X value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#e
|
|
* @type {number}
|
|
* @since 3.11.0
|
|
*/
|
|
e: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[4];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[4] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Translate Y value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#f
|
|
* @type {number}
|
|
* @since 3.11.0
|
|
*/
|
|
f: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[5];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[5] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Translate X value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#tx
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
tx: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[4];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[4] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The Translate Y value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#ty
|
|
* @type {number}
|
|
* @since 3.4.0
|
|
*/
|
|
ty: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.matrix[5];
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.matrix[5] = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The rotation of the Matrix. Value is in radians.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#rotation
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
rotation: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.acos(this.a / this.scaleX) * ((Math.atan(-this.c / this.a) < 0) ? -1 : 1);
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The rotation of the Matrix, normalized to be within the Phaser right-handed
|
|
* clockwise rotation space. Value is in radians.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#rotationNormalized
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
rotationNormalized: {
|
|
|
|
get: function ()
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
|
|
if (a || b)
|
|
{
|
|
// var r = Math.sqrt(a * a + b * b);
|
|
|
|
return (b > 0) ? Math.acos(a / this.scaleX) : -Math.acos(a / this.scaleX);
|
|
}
|
|
else if (c || d)
|
|
{
|
|
// var s = Math.sqrt(c * c + d * d);
|
|
|
|
return MATH_CONST.TAU - ((d > 0) ? Math.acos(-c / this.scaleY) : -Math.acos(c / this.scaleY));
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The decomposed horizontal scale of the Matrix. This value is always positive.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#scaleX
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
scaleX: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.sqrt((this.a * this.a) + (this.b * this.b));
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The decomposed vertical scale of the Matrix. This value is always positive.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TransformMatrix#scaleY
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
scaleY: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.sqrt((this.c * this.c) + (this.d * this.d));
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Reset the Matrix to an identity matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#loadIdentity
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
loadIdentity: function ()
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[0] = 1;
|
|
matrix[1] = 0;
|
|
matrix[2] = 0;
|
|
matrix[3] = 1;
|
|
matrix[4] = 0;
|
|
matrix[5] = 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Translate the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#translate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal translation value.
|
|
* @param {number} y - The vertical translation value.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
translate: function (x, y)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[4] = matrix[0] * x + matrix[2] * y + matrix[4];
|
|
matrix[5] = matrix[1] * x + matrix[3] * y + matrix[5];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Scale the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal scale value.
|
|
* @param {number} y - The vertical scale value.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
scale: function (x, y)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[0] *= x;
|
|
matrix[1] *= x;
|
|
matrix[2] *= y;
|
|
matrix[3] *= y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#rotate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle - The angle of rotation in radians.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
rotate: function (angle)
|
|
{
|
|
var sin = Math.sin(angle);
|
|
var cos = Math.cos(angle);
|
|
|
|
var matrix = this.matrix;
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
|
|
matrix[0] = a * cos + c * sin;
|
|
matrix[1] = b * cos + d * sin;
|
|
matrix[2] = a * -sin + c * cos;
|
|
matrix[3] = b * -sin + d * cos;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Multiply this Matrix by the given Matrix.
|
|
*
|
|
* If an `out` Matrix is given then the results will be stored in it.
|
|
* If it is not given, this matrix will be updated in place instead.
|
|
* Use an `out` Matrix if you do not wish to mutate this matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} rhs - The Matrix to multiply by.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} [out] - An optional Matrix to store the results in.
|
|
*
|
|
* @return {(this|Phaser.GameObjects.Components.TransformMatrix)} Either this TransformMatrix, or the `out` Matrix, if given in the arguments.
|
|
*/
|
|
multiply: function (rhs, out)
|
|
{
|
|
var matrix = this.matrix;
|
|
var source = rhs.matrix;
|
|
|
|
var localA = matrix[0];
|
|
var localB = matrix[1];
|
|
var localC = matrix[2];
|
|
var localD = matrix[3];
|
|
var localE = matrix[4];
|
|
var localF = matrix[5];
|
|
|
|
var sourceA = source[0];
|
|
var sourceB = source[1];
|
|
var sourceC = source[2];
|
|
var sourceD = source[3];
|
|
var sourceE = source[4];
|
|
var sourceF = source[5];
|
|
|
|
var destinationMatrix = (out === undefined) ? this : out;
|
|
|
|
destinationMatrix.a = (sourceA * localA) + (sourceB * localC);
|
|
destinationMatrix.b = (sourceA * localB) + (sourceB * localD);
|
|
destinationMatrix.c = (sourceC * localA) + (sourceD * localC);
|
|
destinationMatrix.d = (sourceC * localB) + (sourceD * localD);
|
|
destinationMatrix.e = (sourceE * localA) + (sourceF * localC) + localE;
|
|
destinationMatrix.f = (sourceE * localB) + (sourceF * localD) + localF;
|
|
|
|
return destinationMatrix;
|
|
},
|
|
|
|
/**
|
|
* Multiply this Matrix by the matrix given, including the offset.
|
|
*
|
|
* The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`.
|
|
* The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#multiplyWithOffset
|
|
* @since 3.11.0
|
|
*
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
|
|
* @param {number} offsetX - Horizontal offset to factor in to the multiplication.
|
|
* @param {number} offsetY - Vertical offset to factor in to the multiplication.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
multiplyWithOffset: function (src, offsetX, offsetY)
|
|
{
|
|
var matrix = this.matrix;
|
|
var otherMatrix = src.matrix;
|
|
|
|
var a0 = matrix[0];
|
|
var b0 = matrix[1];
|
|
var c0 = matrix[2];
|
|
var d0 = matrix[3];
|
|
var tx0 = matrix[4];
|
|
var ty0 = matrix[5];
|
|
|
|
var pse = offsetX * a0 + offsetY * c0 + tx0;
|
|
var psf = offsetX * b0 + offsetY * d0 + ty0;
|
|
|
|
var a1 = otherMatrix[0];
|
|
var b1 = otherMatrix[1];
|
|
var c1 = otherMatrix[2];
|
|
var d1 = otherMatrix[3];
|
|
var tx1 = otherMatrix[4];
|
|
var ty1 = otherMatrix[5];
|
|
|
|
matrix[0] = a1 * a0 + b1 * c0;
|
|
matrix[1] = a1 * b0 + b1 * d0;
|
|
matrix[2] = c1 * a0 + d1 * c0;
|
|
matrix[3] = c1 * b0 + d1 * d0;
|
|
matrix[4] = tx1 * a0 + ty1 * c0 + pse;
|
|
matrix[5] = tx1 * b0 + ty1 * d0 + psf;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#transform
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The Scale X value.
|
|
* @param {number} b - The Shear Y value.
|
|
* @param {number} c - The Shear X value.
|
|
* @param {number} d - The Scale Y value.
|
|
* @param {number} tx - The Translate X value.
|
|
* @param {number} ty - The Translate Y value.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
transform: function (a, b, c, d, tx, ty)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
var a0 = matrix[0];
|
|
var b0 = matrix[1];
|
|
var c0 = matrix[2];
|
|
var d0 = matrix[3];
|
|
var tx0 = matrix[4];
|
|
var ty0 = matrix[5];
|
|
|
|
matrix[0] = a * a0 + b * c0;
|
|
matrix[1] = a * b0 + b * d0;
|
|
matrix[2] = c * a0 + d * c0;
|
|
matrix[3] = c * b0 + d * d0;
|
|
matrix[4] = tx * a0 + ty * c0 + tx0;
|
|
matrix[5] = tx * b0 + ty * d0 + ty0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform a point using this Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#transformPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The x coordinate of the point to transform.
|
|
* @param {number} y - The y coordinate of the point to transform.
|
|
* @param {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} point - The Point object to store the transformed coordinates.
|
|
*
|
|
* @return {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} The Point containing the transformed coordinates.
|
|
*/
|
|
transformPoint: function (x, y, point)
|
|
{
|
|
if (point === undefined) { point = { x: 0, y: 0 }; }
|
|
|
|
var matrix = this.matrix;
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
var tx = matrix[4];
|
|
var ty = matrix[5];
|
|
|
|
point.x = x * a + y * c + tx;
|
|
point.y = x * b + y * d + ty;
|
|
|
|
return point;
|
|
},
|
|
|
|
/**
|
|
* Invert the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#invert
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
invert: function ()
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
var tx = matrix[4];
|
|
var ty = matrix[5];
|
|
|
|
var n = a * d - b * c;
|
|
|
|
matrix[0] = d / n;
|
|
matrix[1] = -b / n;
|
|
matrix[2] = -c / n;
|
|
matrix[3] = a / n;
|
|
matrix[4] = (c * ty - d * tx) / n;
|
|
matrix[5] = -(a * ty - b * tx) / n;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix to copy those of the matrix given.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#copyFrom
|
|
* @since 3.11.0
|
|
*
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
copyFrom: function (src)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[0] = src.a;
|
|
matrix[1] = src.b;
|
|
matrix[2] = src.c;
|
|
matrix[3] = src.d;
|
|
matrix[4] = src.e;
|
|
matrix[5] = src.f;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix to copy those of the array given.
|
|
* Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#copyFromArray
|
|
* @since 3.11.0
|
|
*
|
|
* @param {array} src - The array of values to set into this matrix.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
copyFromArray: function (src)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[0] = src[0];
|
|
matrix[1] = src[1];
|
|
matrix[2] = src[2];
|
|
matrix[3] = src[3];
|
|
matrix[4] = src[4];
|
|
matrix[5] = src[5];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Copy the values from this Matrix to the given Canvas Rendering Context.
|
|
* This will use the Context.transform method.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#copyToContext
|
|
* @since 3.12.0
|
|
*
|
|
* @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
|
|
*
|
|
* @return {CanvasRenderingContext2D} The Canvas Rendering Context.
|
|
*/
|
|
copyToContext: function (ctx)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
|
|
|
|
return ctx;
|
|
},
|
|
|
|
/**
|
|
* Copy the values from this Matrix to the given Canvas Rendering Context.
|
|
* This will use the Context.setTransform method.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#setToContext
|
|
* @since 3.12.0
|
|
*
|
|
* @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
|
|
*
|
|
* @return {CanvasRenderingContext2D} The Canvas Rendering Context.
|
|
*/
|
|
setToContext: function (ctx)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
|
|
|
|
return ctx;
|
|
},
|
|
|
|
/**
|
|
* Copy the values in this Matrix to the array given.
|
|
*
|
|
* Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#copyToArray
|
|
* @since 3.12.0
|
|
*
|
|
* @param {array} [out] - The array to copy the matrix values in to.
|
|
*
|
|
* @return {array} An array where elements 0 to 5 contain the values from this matrix.
|
|
*/
|
|
copyToArray: function (out)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
if (out === undefined)
|
|
{
|
|
out = [ matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5] ];
|
|
}
|
|
else
|
|
{
|
|
out[0] = matrix[0];
|
|
out[1] = matrix[1];
|
|
out[2] = matrix[2];
|
|
out[3] = matrix[3];
|
|
out[4] = matrix[4];
|
|
out[5] = matrix[5];
|
|
}
|
|
|
|
return out;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#setTransform
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The Scale X value.
|
|
* @param {number} b - The Shear Y value.
|
|
* @param {number} c - The Shear X value.
|
|
* @param {number} d - The Scale Y value.
|
|
* @param {number} tx - The Translate X value.
|
|
* @param {number} ty - The Translate Y value.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
setTransform: function (a, b, c, d, tx, ty)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
matrix[0] = a;
|
|
matrix[1] = b;
|
|
matrix[2] = c;
|
|
matrix[3] = d;
|
|
matrix[4] = tx;
|
|
matrix[5] = ty;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Decompose this Matrix into its translation, scale and rotation values using QR decomposition.
|
|
*
|
|
* The result must be applied in the following order to reproduce the current matrix:
|
|
*
|
|
* translate -> rotate -> scale
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#decomposeMatrix
|
|
* @since 3.0.0
|
|
*
|
|
* @return {object} The decomposed Matrix.
|
|
*/
|
|
decomposeMatrix: function ()
|
|
{
|
|
var decomposedMatrix = this.decomposedMatrix;
|
|
|
|
var matrix = this.matrix;
|
|
|
|
// a = scale X (1)
|
|
// b = shear Y (0)
|
|
// c = shear X (0)
|
|
// d = scale Y (1)
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
|
|
var determ = a * d - b * c;
|
|
|
|
decomposedMatrix.translateX = matrix[4];
|
|
decomposedMatrix.translateY = matrix[5];
|
|
|
|
if (a || b)
|
|
{
|
|
var r = Math.sqrt(a * a + b * b);
|
|
|
|
decomposedMatrix.rotation = (b > 0) ? Math.acos(a / r) : -Math.acos(a / r);
|
|
decomposedMatrix.scaleX = r;
|
|
decomposedMatrix.scaleY = determ / r;
|
|
}
|
|
else if (c || d)
|
|
{
|
|
var s = Math.sqrt(c * c + d * d);
|
|
|
|
decomposedMatrix.rotation = Math.PI * 0.5 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s));
|
|
decomposedMatrix.scaleX = determ / s;
|
|
decomposedMatrix.scaleY = s;
|
|
}
|
|
else
|
|
{
|
|
decomposedMatrix.rotation = 0;
|
|
decomposedMatrix.scaleX = 0;
|
|
decomposedMatrix.scaleY = 0;
|
|
}
|
|
|
|
return decomposedMatrix;
|
|
},
|
|
|
|
/**
|
|
* Apply the identity, translate, rotate and scale operations on the Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#applyITRS
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal translation.
|
|
* @param {number} y - The vertical translation.
|
|
* @param {number} rotation - The angle of rotation in radians.
|
|
* @param {number} scaleX - The horizontal scale.
|
|
* @param {number} scaleY - The vertical scale.
|
|
*
|
|
* @return {this} This TransformMatrix.
|
|
*/
|
|
applyITRS: function (x, y, rotation, scaleX, scaleY)
|
|
{
|
|
var matrix = this.matrix;
|
|
|
|
var radianSin = Math.sin(rotation);
|
|
var radianCos = Math.cos(rotation);
|
|
|
|
// Translate
|
|
matrix[4] = x;
|
|
matrix[5] = y;
|
|
|
|
// Rotate and Scale
|
|
matrix[0] = radianCos * scaleX;
|
|
matrix[1] = radianSin * scaleX;
|
|
matrix[2] = -radianSin * scaleY;
|
|
matrix[3] = radianCos * scaleY;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of
|
|
* the current matrix with its transformation applied.
|
|
*
|
|
* Can be used to translate points from world to local space.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#applyInverse
|
|
* @since 3.12.0
|
|
*
|
|
* @param {number} x - The x position to translate.
|
|
* @param {number} y - The y position to translate.
|
|
* @param {Phaser.Math.Vector2} [output] - A Vector2, or point-like object, to store the results in.
|
|
*
|
|
* @return {Phaser.Math.Vector2} The coordinates, inverse-transformed through this matrix.
|
|
*/
|
|
applyInverse: function (x, y, output)
|
|
{
|
|
if (output === undefined) { output = new Vector2(); }
|
|
|
|
var matrix = this.matrix;
|
|
|
|
var a = matrix[0];
|
|
var b = matrix[1];
|
|
var c = matrix[2];
|
|
var d = matrix[3];
|
|
var tx = matrix[4];
|
|
var ty = matrix[5];
|
|
|
|
var id = 1 / ((a * d) + (c * -b));
|
|
|
|
output.x = (d * id * x) + (-c * id * y) + (((ty * c) - (tx * d)) * id);
|
|
output.y = (a * id * y) + (-b * id * x) + (((-ty * a) + (tx * b)) * id);
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns the X component of this matrix multiplied by the given values.
|
|
* This is the same as `x * a + y * c + e`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#getX
|
|
* @since 3.12.0
|
|
*
|
|
* @param {number} x - The x value.
|
|
* @param {number} y - The y value.
|
|
*
|
|
* @return {number} The calculated x value.
|
|
*/
|
|
getX: function (x, y)
|
|
{
|
|
return x * this.a + y * this.c + this.e;
|
|
},
|
|
|
|
/**
|
|
* Returns the Y component of this matrix multiplied by the given values.
|
|
* This is the same as `x * b + y * d + f`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#getY
|
|
* @since 3.12.0
|
|
*
|
|
* @param {number} x - The x value.
|
|
* @param {number} y - The y value.
|
|
*
|
|
* @return {number} The calculated y value.
|
|
*/
|
|
getY: function (x, y)
|
|
{
|
|
return x * this.b + y * this.d + this.f;
|
|
},
|
|
|
|
/**
|
|
* Returns the X component of this matrix multiplied by the given values.
|
|
*
|
|
* This is the same as `x * a + y * c + e`, optionally passing via `Math.round`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#getXRound
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number} x - The x value.
|
|
* @param {number} y - The y value.
|
|
* @param {boolean} [round=false] - Math.round the resulting value?
|
|
*
|
|
* @return {number} The calculated x value.
|
|
*/
|
|
getXRound: function (x, y, round)
|
|
{
|
|
var v = this.getX(x, y);
|
|
|
|
if (round)
|
|
{
|
|
v = Math.round(v);
|
|
}
|
|
|
|
return v;
|
|
},
|
|
|
|
/**
|
|
* Returns the Y component of this matrix multiplied by the given values.
|
|
*
|
|
* This is the same as `x * b + y * d + f`, optionally passing via `Math.round`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#getYRound
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number} x - The x value.
|
|
* @param {number} y - The y value.
|
|
* @param {boolean} [round=false] - Math.round the resulting value?
|
|
*
|
|
* @return {number} The calculated y value.
|
|
*/
|
|
getYRound: function (x, y, round)
|
|
{
|
|
var v = this.getY(x, y);
|
|
|
|
if (round)
|
|
{
|
|
v = Math.round(v);
|
|
}
|
|
|
|
return v;
|
|
},
|
|
|
|
/**
|
|
* Returns a string that can be used in a CSS Transform call as a `matrix` property.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#getCSSMatrix
|
|
* @since 3.12.0
|
|
*
|
|
* @return {string} A string containing the CSS Transform matrix values.
|
|
*/
|
|
getCSSMatrix: function ()
|
|
{
|
|
var m = this.matrix;
|
|
|
|
return 'matrix(' + m[0] + ',' + m[1] + ',' + m[2] + ',' + m[3] + ',' + m[4] + ',' + m[5] + ')';
|
|
},
|
|
|
|
/**
|
|
* Destroys this Transform Matrix.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TransformMatrix#destroy
|
|
* @since 3.4.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.matrix = null;
|
|
this.decomposedMatrix = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = TransformMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 24 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Checks if an array can be used as a matrix.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.CheckMatrix
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix]
|
|
*
|
|
* @param {T[][]} [matrix] - The array to check.
|
|
*
|
|
* @return {boolean} `true` if the given `matrix` array is a valid matrix.
|
|
*/
|
|
var CheckMatrix = function (matrix)
|
|
{
|
|
if (!Array.isArray(matrix) || matrix.length < 2 || !Array.isArray(matrix[0]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// How long is the first row?
|
|
var size = matrix[0].length;
|
|
|
|
// Validate the rest of the rows are the same length
|
|
for (var i = 1; i < matrix.length; i++)
|
|
{
|
|
if (matrix[i].length !== size)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
module.exports = CheckMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 25 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var Contains = __webpack_require__(296);
|
|
var GetPoint = __webpack_require__(59);
|
|
var GetPoints = __webpack_require__(297);
|
|
var GEOM_CONST = __webpack_require__(26);
|
|
var Line = __webpack_require__(298);
|
|
var Random = __webpack_require__(303);
|
|
|
|
/**
|
|
* @classdesc
|
|
* Encapsulates a 2D rectangle defined by its corner point in the top-left and its extends in x (width) and y (height)
|
|
*
|
|
* @class Rectangle
|
|
* @memberof Phaser.Geom
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The X coordinate of the top left corner of the Rectangle.
|
|
* @param {number} [y=0] - The Y coordinate of the top left corner of the Rectangle.
|
|
* @param {number} [width=0] - The width of the Rectangle.
|
|
* @param {number} [height=0] - The height of the Rectangle.
|
|
*/
|
|
var Rectangle = new Class({
|
|
|
|
initialize:
|
|
|
|
function Rectangle (x, y, width, height)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = 0; }
|
|
if (width === undefined) { width = 0; }
|
|
if (height === undefined) { height = 0; }
|
|
|
|
/**
|
|
* The geometry constant type of this object: `GEOM_CONST.RECTANGLE`.
|
|
* Used for fast type comparisons.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#type
|
|
* @type {integer}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
this.type = GEOM_CONST.RECTANGLE;
|
|
|
|
/**
|
|
* The X coordinate of the top left corner of the Rectangle.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.x = x;
|
|
|
|
/**
|
|
* The Y coordinate of the top left corner of the Rectangle.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.y = y;
|
|
|
|
/**
|
|
* The width of the Rectangle, i.e. the distance between its left side (defined by `x`) and its right side.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#width
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.width = width;
|
|
|
|
/**
|
|
* The height of the Rectangle, i.e. the distance between its top side (defined by `y`) and its bottom side.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#height
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.height = height;
|
|
},
|
|
|
|
/**
|
|
* Checks if the given point is inside the Rectangle's bounds.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#contains
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The X coordinate of the point to check.
|
|
* @param {number} y - The Y coordinate of the point to check.
|
|
*
|
|
* @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`.
|
|
*/
|
|
contains: function (x, y)
|
|
{
|
|
return Contains(this, x, y);
|
|
},
|
|
|
|
/**
|
|
* Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter.
|
|
*
|
|
* The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is.
|
|
*
|
|
* A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [output,$return]
|
|
*
|
|
* @param {number} position - The normalized distance into the Rectangle's perimeter to return.
|
|
* @param {(Phaser.Geom.Point|object)} [output] - An object to update with the `x` and `y` coordinates of the point.
|
|
*
|
|
* @return {(Phaser.Geom.Point|object)} The updated `output` object, or a new Point if no `output` object was given.
|
|
*/
|
|
getPoint: function (position, output)
|
|
{
|
|
return GetPoint(this, position, output);
|
|
},
|
|
|
|
/**
|
|
* Returns an array of points from the perimeter of the Rectangle, each spaced out based on the quantity or step required.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getPoints
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point[]} O - [output,$return]
|
|
*
|
|
* @param {integer} quantity - The number of points to return. Set to `false` or 0 to return an arbitrary number of points (`perimeter / stepRate`) evenly spaced around the Rectangle based on the `stepRate`.
|
|
* @param {number} [stepRate] - If `quantity` is 0, determines the normalized distance between each returned point.
|
|
* @param {(array|Phaser.Geom.Point[])} [output] - An array to which to append the points.
|
|
*
|
|
* @return {(array|Phaser.Geom.Point[])} The modified `output` array, or a new array if none was provided.
|
|
*/
|
|
getPoints: function (quantity, stepRate, output)
|
|
{
|
|
return GetPoints(this, quantity, stepRate, output);
|
|
},
|
|
|
|
/**
|
|
* Returns a random point within the Rectangle's bounds.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getRandomPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [point,$return]
|
|
*
|
|
* @param {Phaser.Geom.Point} [point] - The object in which to store the `x` and `y` coordinates of the point.
|
|
*
|
|
* @return {Phaser.Geom.Point} The updated `point`, or a new Point if none was provided.
|
|
*/
|
|
getRandomPoint: function (point)
|
|
{
|
|
return Random(this, point);
|
|
},
|
|
|
|
/**
|
|
* Sets the position, width, and height of the Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#setTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The X coordinate of the top left corner of the Rectangle.
|
|
* @param {number} y - The Y coordinate of the top left corner of the Rectangle.
|
|
* @param {number} width - The width of the Rectangle.
|
|
* @param {number} height - The height of the Rectangle.
|
|
*
|
|
* @return {this} This Rectangle object.
|
|
*/
|
|
setTo: function (x, y, width, height)
|
|
{
|
|
this.x = x;
|
|
this.y = y;
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Resets the position, width, and height of the Rectangle to 0.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#setEmpty
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Rectangle object.
|
|
*/
|
|
setEmpty: function ()
|
|
{
|
|
return this.setTo(0, 0, 0, 0);
|
|
},
|
|
|
|
/**
|
|
* Sets the position of the Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#setPosition
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The X coordinate of the top left corner of the Rectangle.
|
|
* @param {number} [y=x] - The Y coordinate of the top left corner of the Rectangle.
|
|
*
|
|
* @return {this} This Rectangle object.
|
|
*/
|
|
setPosition: function (x, y)
|
|
{
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the width and height of the Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#setSize
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} width - The width to set the Rectangle to.
|
|
* @param {number} [height=width] - The height to set the Rectangle to.
|
|
*
|
|
* @return {this} This Rectangle object.
|
|
*/
|
|
setSize: function (width, height)
|
|
{
|
|
if (height === undefined) { height = width; }
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Determines if the Rectangle is empty. A Rectangle is empty if its width or height is less than or equal to 0.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#isEmpty
|
|
* @since 3.0.0
|
|
*
|
|
* @return {boolean} `true` if the Rectangle is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
|
|
*/
|
|
isEmpty: function ()
|
|
{
|
|
return (this.width <= 0 || this.height <= 0);
|
|
},
|
|
|
|
/**
|
|
* Returns a Line object that corresponds to the top of this Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getLineA
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Line} O - [line,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
|
|
*
|
|
* @return {Phaser.Geom.Line} A Line object that corresponds to the top of this Rectangle.
|
|
*/
|
|
getLineA: function (line)
|
|
{
|
|
if (line === undefined) { line = new Line(); }
|
|
|
|
line.setTo(this.x, this.y, this.right, this.y);
|
|
|
|
return line;
|
|
},
|
|
|
|
/**
|
|
* Returns a Line object that corresponds to the right of this Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getLineB
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Line} O - [line,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
|
|
*
|
|
* @return {Phaser.Geom.Line} A Line object that corresponds to the right of this Rectangle.
|
|
*/
|
|
getLineB: function (line)
|
|
{
|
|
if (line === undefined) { line = new Line(); }
|
|
|
|
line.setTo(this.right, this.y, this.right, this.bottom);
|
|
|
|
return line;
|
|
},
|
|
|
|
/**
|
|
* Returns a Line object that corresponds to the bottom of this Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getLineC
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Line} O - [line,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
|
|
*
|
|
* @return {Phaser.Geom.Line} A Line object that corresponds to the bottom of this Rectangle.
|
|
*/
|
|
getLineC: function (line)
|
|
{
|
|
if (line === undefined) { line = new Line(); }
|
|
|
|
line.setTo(this.right, this.bottom, this.x, this.bottom);
|
|
|
|
return line;
|
|
},
|
|
|
|
/**
|
|
* Returns a Line object that corresponds to the left of this Rectangle.
|
|
*
|
|
* @method Phaser.Geom.Rectangle#getLineD
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Line} O - [line,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
|
|
*
|
|
* @return {Phaser.Geom.Line} A Line object that corresponds to the left of this Rectangle.
|
|
*/
|
|
getLineD: function (line)
|
|
{
|
|
if (line === undefined) { line = new Line(); }
|
|
|
|
line.setTo(this.x, this.bottom, this.x, this.y);
|
|
|
|
return line;
|
|
},
|
|
|
|
/**
|
|
* The x coordinate of the left of the Rectangle.
|
|
* Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#left
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
left: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.x;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (value >= this.right)
|
|
{
|
|
this.width = 0;
|
|
}
|
|
else
|
|
{
|
|
this.width = this.right - value;
|
|
}
|
|
|
|
this.x = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The sum of the x and width properties.
|
|
* Changing the right property of a Rectangle object has no effect on the x, y and height properties, however it does affect the width property.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#right
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
right: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.x + this.width;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (value <= this.x)
|
|
{
|
|
this.width = 0;
|
|
}
|
|
else
|
|
{
|
|
this.width = value - this.x;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
|
|
* However it does affect the height property, whereas changing the y value does not affect the height property.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#top
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
top: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.y;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (value >= this.bottom)
|
|
{
|
|
this.height = 0;
|
|
}
|
|
else
|
|
{
|
|
this.height = (this.bottom - value);
|
|
}
|
|
|
|
this.y = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The sum of the y and height properties.
|
|
* Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#bottom
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
bottom: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.y + this.height;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (value <= this.y)
|
|
{
|
|
this.height = 0;
|
|
}
|
|
else
|
|
{
|
|
this.height = value - this.y;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The x coordinate of the center of the Rectangle.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#centerX
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
centerX: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.x + (this.width / 2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.x = value - (this.width / 2);
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The y coordinate of the center of the Rectangle.
|
|
*
|
|
* @name Phaser.Geom.Rectangle#centerY
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
centerY: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.y + (this.height / 2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.y = value - (this.height / 2);
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Rectangle;
|
|
|
|
|
|
/***/ }),
|
|
/* 26 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var GEOM_CONST = {
|
|
|
|
/**
|
|
* A Circle Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.CIRCLE
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
CIRCLE: 0,
|
|
|
|
/**
|
|
* An Ellipse Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.ELLIPSE
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
ELLIPSE: 1,
|
|
|
|
/**
|
|
* A Line Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.LINE
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
LINE: 2,
|
|
|
|
/**
|
|
* A Point Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.POINT
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
POINT: 3,
|
|
|
|
/**
|
|
* A Polygon Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.POLYGON
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
POLYGON: 4,
|
|
|
|
/**
|
|
* A Rectangle Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.RECTANGLE
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
RECTANGLE: 5,
|
|
|
|
/**
|
|
* A Triangle Geometry object type.
|
|
*
|
|
* @name Phaser.Geom.TRIANGLE
|
|
* @type {integer}
|
|
* @since 3.19.0
|
|
*/
|
|
TRIANGLE: 6
|
|
|
|
};
|
|
|
|
module.exports = GEOM_CONST;
|
|
|
|
|
|
/***/ }),
|
|
/* 27 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var IsPlainObject = __webpack_require__(7);
|
|
|
|
// @param {boolean} deep - Perform a deep copy?
|
|
// @param {object} target - The target object to copy to.
|
|
// @return {object} The extended object.
|
|
|
|
/**
|
|
* This is a slightly modified version of http://api.jquery.com/jQuery.extend/
|
|
*
|
|
* @function Phaser.Utils.Objects.Extend
|
|
* @since 3.0.0
|
|
*
|
|
* @param {...*} [args] - The objects that will be mixed.
|
|
*
|
|
* @return {object} The extended object.
|
|
*/
|
|
var Extend = function ()
|
|
{
|
|
var options, name, src, copy, copyIsArray, clone,
|
|
target = arguments[0] || {},
|
|
i = 1,
|
|
length = arguments.length,
|
|
deep = false;
|
|
|
|
// Handle a deep copy situation
|
|
if (typeof target === 'boolean')
|
|
{
|
|
deep = target;
|
|
target = arguments[1] || {};
|
|
|
|
// skip the boolean and the target
|
|
i = 2;
|
|
}
|
|
|
|
// extend Phaser if only one argument is passed
|
|
if (length === i)
|
|
{
|
|
target = this;
|
|
--i;
|
|
}
|
|
|
|
for (; i < length; i++)
|
|
{
|
|
// Only deal with non-null/undefined values
|
|
if ((options = arguments[i]) != null)
|
|
{
|
|
// Extend the base object
|
|
for (name in options)
|
|
{
|
|
src = target[name];
|
|
copy = options[name];
|
|
|
|
// Prevent never-ending loop
|
|
if (target === copy)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Recurse if we're merging plain objects or arrays
|
|
if (deep && copy && (IsPlainObject(copy) || (copyIsArray = Array.isArray(copy))))
|
|
{
|
|
if (copyIsArray)
|
|
{
|
|
copyIsArray = false;
|
|
clone = src && Array.isArray(src) ? src : [];
|
|
}
|
|
else
|
|
{
|
|
clone = src && IsPlainObject(src) ? src : {};
|
|
}
|
|
|
|
// Never move original objects, clone them
|
|
target[name] = Extend(deep, clone, copy);
|
|
|
|
// Don't bring in undefined values
|
|
}
|
|
else if (copy !== undefined)
|
|
{
|
|
target[name] = copy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return the modified object
|
|
return target;
|
|
};
|
|
|
|
module.exports = Extend;
|
|
|
|
|
|
/***/ }),
|
|
/* 28 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Find the angle of a segment from (x1, y1) -> (x2, y2).
|
|
*
|
|
* @function Phaser.Math.Angle.Between
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The angle in radians.
|
|
*/
|
|
var Between = function (x1, y1, x2, y2)
|
|
{
|
|
return Math.atan2(y2 - y1, x2 - x1);
|
|
};
|
|
|
|
module.exports = Between;
|
|
|
|
|
|
/***/ }),
|
|
/* 29 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Normalize an angle to the [0, 2pi] range.
|
|
*
|
|
* @function Phaser.Math.Angle.Normalize
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle - The angle to normalize, in radians.
|
|
*
|
|
* @return {number} The normalized angle, in radians.
|
|
*/
|
|
var Normalize = function (angle)
|
|
{
|
|
angle = angle % (2 * Math.PI);
|
|
|
|
if (angle >= 0)
|
|
{
|
|
return angle;
|
|
}
|
|
else
|
|
{
|
|
return angle + 2 * Math.PI;
|
|
}
|
|
};
|
|
|
|
module.exports = Normalize;
|
|
|
|
|
|
/***/ }),
|
|
/* 30 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MathWrap = __webpack_require__(6);
|
|
|
|
/**
|
|
* Wrap an angle.
|
|
*
|
|
* Wraps the angle to a value in the range of -PI to PI.
|
|
*
|
|
* @function Phaser.Math.Angle.Wrap
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle - The angle to wrap, in radians.
|
|
*
|
|
* @return {number} The wrapped angle, in radians.
|
|
*/
|
|
var Wrap = function (angle)
|
|
{
|
|
return MathWrap(angle, -Math.PI, Math.PI);
|
|
};
|
|
|
|
module.exports = Wrap;
|
|
|
|
|
|
/***/ }),
|
|
/* 31 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Wrap = __webpack_require__(6);
|
|
|
|
/**
|
|
* Wrap an angle in degrees.
|
|
*
|
|
* Wraps the angle to a value in the range of -180 to 180.
|
|
*
|
|
* @function Phaser.Math.Angle.WrapDegrees
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle - The angle to wrap, in degrees.
|
|
*
|
|
* @return {number} The wrapped angle, in degrees.
|
|
*/
|
|
var WrapDegrees = function (angle)
|
|
{
|
|
return Wrap(angle, -180, 180);
|
|
};
|
|
|
|
module.exports = WrapDegrees;
|
|
|
|
|
|
/***/ }),
|
|
/* 32 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Check whether the given values are fuzzily equal.
|
|
*
|
|
* Two numbers are fuzzily equal if their difference is less than `epsilon`.
|
|
*
|
|
* @function Phaser.Math.Fuzzy.Equal
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The first value.
|
|
* @param {number} b - The second value.
|
|
* @param {number} [epsilon=0.0001] - The epsilon.
|
|
*
|
|
* @return {boolean} `true` if the values are fuzzily equal, otherwise `false`.
|
|
*/
|
|
var Equal = function (a, b, epsilon)
|
|
{
|
|
if (epsilon === undefined) { epsilon = 0.0001; }
|
|
|
|
return Math.abs(a - b) < epsilon;
|
|
};
|
|
|
|
module.exports = Equal;
|
|
|
|
|
|
/***/ }),
|
|
/* 33 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Factorial = __webpack_require__(34);
|
|
|
|
/**
|
|
* Calculates the Bernstein basis from the three factorial coefficients.
|
|
*
|
|
* @function Phaser.Math.Bernstein
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} n - The first value.
|
|
* @param {number} i - The second value.
|
|
*
|
|
* @return {number} The Bernstein basis of Factorial(n) / Factorial(i) / Factorial(n - i)
|
|
*/
|
|
var Bernstein = function (n, i)
|
|
{
|
|
return Factorial(n) / Factorial(i) / Factorial(n - i);
|
|
};
|
|
|
|
module.exports = Bernstein;
|
|
|
|
|
|
/***/ }),
|
|
/* 34 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculates the factorial of a given number for integer values greater than 0.
|
|
*
|
|
* @function Phaser.Math.Factorial
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - A positive integer to calculate the factorial of.
|
|
*
|
|
* @return {number} The factorial of the given number.
|
|
*/
|
|
var Factorial = function (value)
|
|
{
|
|
if (value === 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
var res = value;
|
|
|
|
while (--value)
|
|
{
|
|
res *= value;
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
module.exports = Factorial;
|
|
|
|
|
|
/***/ }),
|
|
/* 35 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculates a Catmull-Rom value from the given points, based on an alpha of 0.5.
|
|
*
|
|
* @function Phaser.Math.CatmullRom
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} t - The amount to interpolate by.
|
|
* @param {number} p0 - The first control point.
|
|
* @param {number} p1 - The second control point.
|
|
* @param {number} p2 - The third control point.
|
|
* @param {number} p3 - The fourth control point.
|
|
*
|
|
* @return {number} The Catmull-Rom value.
|
|
*/
|
|
var CatmullRom = function (t, p0, p1, p2, p3)
|
|
{
|
|
var v0 = (p2 - p0) * 0.5;
|
|
var v1 = (p3 - p1) * 0.5;
|
|
var t2 = t * t;
|
|
var t3 = t * t2;
|
|
|
|
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
|
|
};
|
|
|
|
module.exports = CatmullRom;
|
|
|
|
|
|
/***/ }),
|
|
/* 36 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculates a linear (interpolation) value over t.
|
|
*
|
|
* @function Phaser.Math.Linear
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} p0 - The first point.
|
|
* @param {number} p1 - The second point.
|
|
* @param {number} t - The percentage between p0 and p1 to return, represented as a number between 0 and 1.
|
|
*
|
|
* @return {number} The step t% of the way between p0 and p1.
|
|
*/
|
|
var Linear = function (p0, p1, t)
|
|
{
|
|
return (p1 - p0) * t + p0;
|
|
};
|
|
|
|
module.exports = Linear;
|
|
|
|
|
|
/***/ }),
|
|
/* 37 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate a smooth interpolation percentage of `x` between `min` and `max`.
|
|
*
|
|
* The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge,
|
|
* 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial,
|
|
* between 0 and 1 otherwise.
|
|
*
|
|
* @function Phaser.Math.SmoothStep
|
|
* @since 3.0.0
|
|
* @see {@link https://en.wikipedia.org/wiki/Smoothstep}
|
|
*
|
|
* @param {number} x - The input value.
|
|
* @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
|
|
* @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
|
|
*
|
|
* @return {number} The percentage of interpolation, between 0 and 1.
|
|
*/
|
|
var SmoothStep = function (x, min, max)
|
|
{
|
|
if (x <= min)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (x >= max)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
x = (x - min) / (max - min);
|
|
|
|
return x * x * (3 - 2 * x);
|
|
};
|
|
|
|
module.exports = SmoothStep;
|
|
|
|
|
|
/***/ }),
|
|
/* 38 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate a smoother interpolation percentage of `x` between `min` and `max`.
|
|
*
|
|
* The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge,
|
|
* 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial,
|
|
* between 0 and 1 otherwise.
|
|
*
|
|
* Produces an even smoother interpolation than {@link Phaser.Math.SmoothStep}.
|
|
*
|
|
* @function Phaser.Math.SmootherStep
|
|
* @since 3.0.0
|
|
* @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
|
|
*
|
|
* @param {number} x - The input value.
|
|
* @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
|
|
* @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
|
|
*
|
|
* @return {number} The percentage of interpolation, between 0 and 1.
|
|
*/
|
|
var SmootherStep = function (x, min, max)
|
|
{
|
|
x = Math.max(0, Math.min(1, (x - min) / (max - min)));
|
|
|
|
return x * x * x * (x * (x * 6 - 15) + 10);
|
|
};
|
|
|
|
module.exports = SmootherStep;
|
|
|
|
|
|
/***/ }),
|
|
/* 39 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Rotate a `point` around `x` and `y` to the given `angle`, at the same distance.
|
|
*
|
|
* In polar notation, this maps a point from (r, t) to (r, angle), vs. the origin (x, y).
|
|
*
|
|
* @function Phaser.Math.RotateAround
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
|
|
*
|
|
* @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
|
|
* @param {number} x - The horizontal coordinate to rotate around.
|
|
* @param {number} y - The vertical coordinate to rotate around.
|
|
* @param {number} angle - The angle of rotation in radians.
|
|
*
|
|
* @return {Phaser.Types.Math.Vector2Like} The given point.
|
|
*/
|
|
var RotateAround = function (point, x, y, angle)
|
|
{
|
|
var c = Math.cos(angle);
|
|
var s = Math.sin(angle);
|
|
|
|
var tx = point.x - x;
|
|
var ty = point.y - y;
|
|
|
|
point.x = tx * c - ty * s + x;
|
|
point.y = tx * s + ty * c + y;
|
|
|
|
return point;
|
|
};
|
|
|
|
module.exports = RotateAround;
|
|
|
|
|
|
/***/ }),
|
|
/* 40 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Round a given number so it is further away from zero. That is, positive numbers are rounded up, and negative numbers are rounded down.
|
|
*
|
|
* @function Phaser.Math.RoundAwayFromZero
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The number to round.
|
|
*
|
|
* @return {number} The rounded number, rounded away from zero.
|
|
*/
|
|
var RoundAwayFromZero = function (value)
|
|
{
|
|
// "Opposite" of truncate.
|
|
return (value > 0) ? Math.ceil(value) : Math.floor(value);
|
|
};
|
|
|
|
module.exports = RoundAwayFromZero;
|
|
|
|
|
|
/***/ }),
|
|
/* 41 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* Takes the `x` and `y` coordinates and transforms them into the same space as
|
|
* defined by the position, rotation and scale values.
|
|
*
|
|
* @function Phaser.Math.TransformXY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The x coordinate to be transformed.
|
|
* @param {number} y - The y coordinate to be transformed.
|
|
* @param {number} positionX - Horizontal position of the transform point.
|
|
* @param {number} positionY - Vertical position of the transform point.
|
|
* @param {number} rotation - Rotation of the transform point, in radians.
|
|
* @param {number} scaleX - Horizontal scale of the transform point.
|
|
* @param {number} scaleY - Vertical scale of the transform point.
|
|
* @param {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} [output] - The output vector, point or object for the translated coordinates.
|
|
*
|
|
* @return {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} The translated point.
|
|
*/
|
|
var TransformXY = function (x, y, positionX, positionY, rotation, scaleX, scaleY, output)
|
|
{
|
|
if (output === undefined) { output = new Vector2(); }
|
|
|
|
var radianSin = Math.sin(rotation);
|
|
var radianCos = Math.cos(rotation);
|
|
|
|
// Rotate and Scale
|
|
var a = radianCos * scaleX;
|
|
var b = radianSin * scaleX;
|
|
var c = -radianSin * scaleY;
|
|
var d = radianCos * scaleY;
|
|
|
|
// Invert
|
|
var id = 1 / ((a * d) + (c * -b));
|
|
|
|
output.x = (d * id * x) + (-c * id * y) + (((positionY * c) - (positionX * d)) * id);
|
|
output.y = (a * id * y) + (-b * id * x) + (((-positionY * a) + (positionX * b)) * id);
|
|
|
|
return output;
|
|
};
|
|
|
|
module.exports = TransformXY;
|
|
|
|
|
|
/***/ }),
|
|
/* 42 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A three-dimensional matrix.
|
|
*
|
|
* Defaults to the identity matrix when instantiated.
|
|
*
|
|
* @class Matrix3
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} [m] - Optional Matrix3 to copy values from.
|
|
*/
|
|
var Matrix3 = new Class({
|
|
|
|
initialize:
|
|
|
|
function Matrix3 (m)
|
|
{
|
|
/**
|
|
* The matrix values.
|
|
*
|
|
* @name Phaser.Math.Matrix3#val
|
|
* @type {Float32Array}
|
|
* @since 3.0.0
|
|
*/
|
|
this.val = new Float32Array(9);
|
|
|
|
if (m)
|
|
{
|
|
// Assume Matrix3 with val:
|
|
this.copy(m);
|
|
}
|
|
else
|
|
{
|
|
// Default to identity
|
|
this.identity();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Make a clone of this Matrix3.
|
|
*
|
|
* @method Phaser.Math.Matrix3#clone
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix3} A clone of this Matrix3.
|
|
*/
|
|
clone: function ()
|
|
{
|
|
return new Matrix3(this);
|
|
},
|
|
|
|
/**
|
|
* This method is an alias for `Matrix3.copy`.
|
|
*
|
|
* @method Phaser.Math.Matrix3#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} src - The Matrix to set the values of this Matrix's from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
set: function (src)
|
|
{
|
|
return this.copy(src);
|
|
},
|
|
|
|
/**
|
|
* Copy the values of a given Matrix into this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} src - The Matrix to copy the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
var out = this.val;
|
|
var a = src.val;
|
|
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Copy the values of a given Matrix4 into this Matrix3.
|
|
*
|
|
* @method Phaser.Math.Matrix3#fromMat4
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} m - The Matrix4 to copy the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
fromMat4: function (m)
|
|
{
|
|
var a = m.val;
|
|
var out = this.val;
|
|
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[4];
|
|
out[4] = a[5];
|
|
out[5] = a[6];
|
|
out[6] = a[8];
|
|
out[7] = a[9];
|
|
out[8] = a[10];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix from the given array.
|
|
*
|
|
* @method Phaser.Math.Matrix3#fromArray
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} a - The array to copy the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
fromArray: function (a)
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = a[0];
|
|
out[1] = a[1];
|
|
out[2] = a[2];
|
|
out[3] = a[3];
|
|
out[4] = a[4];
|
|
out[5] = a[5];
|
|
out[6] = a[6];
|
|
out[7] = a[7];
|
|
out[8] = a[8];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Reset this Matrix to an identity (default) matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#identity
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
identity: function ()
|
|
{
|
|
var out = this.val;
|
|
|
|
out[0] = 1;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
out[4] = 1;
|
|
out[5] = 0;
|
|
out[6] = 0;
|
|
out[7] = 0;
|
|
out[8] = 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transpose this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#transpose
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
transpose: function ()
|
|
{
|
|
var a = this.val;
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a12 = a[5];
|
|
|
|
a[1] = a[3];
|
|
a[2] = a[6];
|
|
a[3] = a01;
|
|
a[5] = a[7];
|
|
a[6] = a02;
|
|
a[7] = a12;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Invert this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#invert
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
invert: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a10 = a[3];
|
|
var a11 = a[4];
|
|
var a12 = a[5];
|
|
var a20 = a[6];
|
|
var a21 = a[7];
|
|
var a22 = a[8];
|
|
|
|
var b01 = a22 * a11 - a12 * a21;
|
|
var b11 = -a22 * a10 + a12 * a20;
|
|
var b21 = a21 * a10 - a11 * a20;
|
|
|
|
// Calculate the determinant
|
|
var det = a00 * b01 + a01 * b11 + a02 * b21;
|
|
|
|
if (!det)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
det = 1 / det;
|
|
|
|
a[0] = b01 * det;
|
|
a[1] = (-a22 * a01 + a02 * a21) * det;
|
|
a[2] = (a12 * a01 - a02 * a11) * det;
|
|
a[3] = b11 * det;
|
|
a[4] = (a22 * a00 - a02 * a20) * det;
|
|
a[5] = (-a12 * a00 + a02 * a10) * det;
|
|
a[6] = b21 * det;
|
|
a[7] = (-a21 * a00 + a01 * a20) * det;
|
|
a[8] = (a11 * a00 - a01 * a10) * det;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the adjoint, or adjugate, of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#adjoint
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
adjoint: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a10 = a[3];
|
|
var a11 = a[4];
|
|
var a12 = a[5];
|
|
var a20 = a[6];
|
|
var a21 = a[7];
|
|
var a22 = a[8];
|
|
|
|
a[0] = (a11 * a22 - a12 * a21);
|
|
a[1] = (a02 * a21 - a01 * a22);
|
|
a[2] = (a01 * a12 - a02 * a11);
|
|
a[3] = (a12 * a20 - a10 * a22);
|
|
a[4] = (a00 * a22 - a02 * a20);
|
|
a[5] = (a02 * a10 - a00 * a12);
|
|
a[6] = (a10 * a21 - a11 * a20);
|
|
a[7] = (a01 * a20 - a00 * a21);
|
|
a[8] = (a00 * a11 - a01 * a10);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the determinant of this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#determinant
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The determinant of this Matrix.
|
|
*/
|
|
determinant: function ()
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a10 = a[3];
|
|
var a11 = a[4];
|
|
var a12 = a[5];
|
|
var a20 = a[6];
|
|
var a21 = a[7];
|
|
var a22 = a[8];
|
|
|
|
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
|
|
},
|
|
|
|
/**
|
|
* Multiply this Matrix by the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} src - The Matrix to multiply this Matrix by.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
multiply: function (src)
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a10 = a[3];
|
|
var a11 = a[4];
|
|
var a12 = a[5];
|
|
var a20 = a[6];
|
|
var a21 = a[7];
|
|
var a22 = a[8];
|
|
|
|
var b = src.val;
|
|
|
|
var b00 = b[0];
|
|
var b01 = b[1];
|
|
var b02 = b[2];
|
|
var b10 = b[3];
|
|
var b11 = b[4];
|
|
var b12 = b[5];
|
|
var b20 = b[6];
|
|
var b21 = b[7];
|
|
var b22 = b[8];
|
|
|
|
a[0] = b00 * a00 + b01 * a10 + b02 * a20;
|
|
a[1] = b00 * a01 + b01 * a11 + b02 * a21;
|
|
a[2] = b00 * a02 + b01 * a12 + b02 * a22;
|
|
|
|
a[3] = b10 * a00 + b11 * a10 + b12 * a20;
|
|
a[4] = b10 * a01 + b11 * a11 + b12 * a21;
|
|
a[5] = b10 * a02 + b11 * a12 + b12 * a22;
|
|
|
|
a[6] = b20 * a00 + b21 * a10 + b22 * a20;
|
|
a[7] = b20 * a01 + b21 * a11 + b22 * a21;
|
|
a[8] = b20 * a02 + b21 * a12 + b22 * a22;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Translate this Matrix using the given Vector.
|
|
*
|
|
* @method Phaser.Math.Matrix3#translate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
translate: function (v)
|
|
{
|
|
var a = this.val;
|
|
var x = v.x;
|
|
var y = v.y;
|
|
|
|
a[6] = x * a[0] + y * a[3] + a[6];
|
|
a[7] = x * a[1] + y * a[4] + a[7];
|
|
a[8] = x * a[2] + y * a[5] + a[8];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a rotation transformation to this Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#rotate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The angle in radians to rotate by.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
rotate: function (rad)
|
|
{
|
|
var a = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a10 = a[3];
|
|
var a11 = a[4];
|
|
var a12 = a[5];
|
|
|
|
var s = Math.sin(rad);
|
|
var c = Math.cos(rad);
|
|
|
|
a[0] = c * a00 + s * a10;
|
|
a[1] = c * a01 + s * a11;
|
|
a[2] = c * a02 + s * a12;
|
|
|
|
a[3] = c * a10 - s * a00;
|
|
a[4] = c * a11 - s * a01;
|
|
a[5] = c * a12 - s * a02;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a scale transformation to this Matrix.
|
|
*
|
|
* Uses the `x` and `y` components of the given Vector to scale the Matrix.
|
|
*
|
|
* @method Phaser.Math.Matrix3#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
scale: function (v)
|
|
{
|
|
var a = this.val;
|
|
var x = v.x;
|
|
var y = v.y;
|
|
|
|
a[0] = x * a[0];
|
|
a[1] = x * a[1];
|
|
a[2] = x * a[2];
|
|
|
|
a[3] = y * a[3];
|
|
a[4] = y * a[4];
|
|
a[5] = y * a[5];
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix from the given Quaternion.
|
|
*
|
|
* @method Phaser.Math.Matrix3#fromQuat
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
fromQuat: function (q)
|
|
{
|
|
var x = q.x;
|
|
var y = q.y;
|
|
var z = q.z;
|
|
var w = q.w;
|
|
|
|
var x2 = x + x;
|
|
var y2 = y + y;
|
|
var z2 = z + z;
|
|
|
|
var xx = x * x2;
|
|
var xy = x * y2;
|
|
var xz = x * z2;
|
|
|
|
var yy = y * y2;
|
|
var yz = y * z2;
|
|
var zz = z * z2;
|
|
|
|
var wx = w * x2;
|
|
var wy = w * y2;
|
|
var wz = w * z2;
|
|
|
|
var out = this.val;
|
|
|
|
out[0] = 1 - (yy + zz);
|
|
out[3] = xy + wz;
|
|
out[6] = xz - wy;
|
|
|
|
out[1] = xy - wz;
|
|
out[4] = 1 - (xx + zz);
|
|
out[7] = yz + wx;
|
|
|
|
out[2] = xz + wy;
|
|
out[5] = yz - wx;
|
|
out[8] = 1 - (xx + yy);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set the values of this Matrix3 to be normalized from the given Matrix4.
|
|
*
|
|
* @method Phaser.Math.Matrix3#normalFromMat4
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} m - The Matrix4 to normalize the values from.
|
|
*
|
|
* @return {Phaser.Math.Matrix3} This Matrix3.
|
|
*/
|
|
normalFromMat4: function (m)
|
|
{
|
|
var a = m.val;
|
|
var out = this.val;
|
|
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
|
|
var a10 = a[4];
|
|
var a11 = a[5];
|
|
var a12 = a[6];
|
|
var a13 = a[7];
|
|
|
|
var a20 = a[8];
|
|
var a21 = a[9];
|
|
var a22 = a[10];
|
|
var a23 = a[11];
|
|
|
|
var a30 = a[12];
|
|
var a31 = a[13];
|
|
var a32 = a[14];
|
|
var a33 = a[15];
|
|
|
|
var b00 = a00 * a11 - a01 * a10;
|
|
var b01 = a00 * a12 - a02 * a10;
|
|
var b02 = a00 * a13 - a03 * a10;
|
|
var b03 = a01 * a12 - a02 * a11;
|
|
|
|
var b04 = a01 * a13 - a03 * a11;
|
|
var b05 = a02 * a13 - a03 * a12;
|
|
var b06 = a20 * a31 - a21 * a30;
|
|
var b07 = a20 * a32 - a22 * a30;
|
|
|
|
var b08 = a20 * a33 - a23 * a30;
|
|
var b09 = a21 * a32 - a22 * a31;
|
|
var b10 = a21 * a33 - a23 * a31;
|
|
var b11 = a22 * a33 - a23 * a32;
|
|
|
|
// Calculate the determinant
|
|
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
|
|
if (!det)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
det = 1 / det;
|
|
|
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
|
|
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
|
|
|
|
out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
|
|
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
|
|
|
|
out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
|
|
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
|
|
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Matrix3;
|
|
|
|
|
|
/***/ }),
|
|
/* 43 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
var Matrix3 = __webpack_require__(42);
|
|
var NOOP = __webpack_require__(1);
|
|
var Vector3 = __webpack_require__(13);
|
|
|
|
var EPSILON = 0.000001;
|
|
|
|
// Some shared 'private' arrays
|
|
var siNext = new Int8Array([ 1, 2, 0 ]);
|
|
var tmp = new Float32Array([ 0, 0, 0 ]);
|
|
|
|
var xUnitVec3 = new Vector3(1, 0, 0);
|
|
var yUnitVec3 = new Vector3(0, 1, 0);
|
|
|
|
var tmpvec = new Vector3();
|
|
var tmpMat3 = new Matrix3();
|
|
|
|
/**
|
|
* @classdesc
|
|
* A quaternion.
|
|
*
|
|
* @class Quaternion
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The x component.
|
|
* @param {number} [y=0] - The y component.
|
|
* @param {number} [z=0] - The z component.
|
|
* @param {number} [w=1] - The w component.
|
|
*/
|
|
var Quaternion = new Class({
|
|
|
|
initialize:
|
|
|
|
function Quaternion (x, y, z, w)
|
|
{
|
|
/**
|
|
* The x component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#_x
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.50.0
|
|
*/
|
|
|
|
/**
|
|
* The y component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#_y
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.50.0
|
|
*/
|
|
|
|
/**
|
|
* The z component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#_z
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.50.0
|
|
*/
|
|
|
|
/**
|
|
* The w component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#_w
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.50.0
|
|
*/
|
|
|
|
/**
|
|
* This callback is invoked, if set, each time a value in this quaternion is changed.
|
|
* The callback is passed one argument, a reference to this quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#onChangeCallback
|
|
* @type {function}
|
|
* @since 3.50.0
|
|
*/
|
|
this.onChangeCallback = NOOP;
|
|
|
|
this.set(x, y, z, w);
|
|
},
|
|
|
|
/**
|
|
* The x component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
x: {
|
|
get: function ()
|
|
{
|
|
return this._x;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._x = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* The y component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
y: {
|
|
get: function ()
|
|
{
|
|
return this._y;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._y = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* The z component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#z
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
z: {
|
|
get: function ()
|
|
{
|
|
return this._z;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._z = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* The w component of this Quaternion.
|
|
*
|
|
* @name Phaser.Math.Quaternion#w
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
w: {
|
|
get: function ()
|
|
{
|
|
return this._w;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._w = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Copy the components of a given Quaternion or Vector into this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} src - The Quaternion or Vector to copy the components from.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
return this.set(src);
|
|
},
|
|
|
|
/**
|
|
* Set the components of this Quaternion and optionally call the `onChangeCallback`.
|
|
*
|
|
* @method Phaser.Math.Quaternion#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(number|object)} [x=0] - The x component, or an object containing x, y, z, and w components.
|
|
* @param {number} [y=0] - The y component.
|
|
* @param {number} [z=0] - The z component.
|
|
* @param {number} [w=0] - The w component.
|
|
* @param {boolean} [update=true] - Call the `onChangeCallback`?
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
set: function (x, y, z, w, update)
|
|
{
|
|
if (update === undefined) { update = true; }
|
|
|
|
if (typeof x === 'object')
|
|
{
|
|
this._x = x.x || 0;
|
|
this._y = x.y || 0;
|
|
this._z = x.z || 0;
|
|
this._w = x.w || 0;
|
|
}
|
|
else
|
|
{
|
|
this._x = x || 0;
|
|
this._y = y || 0;
|
|
this._z = z || 0;
|
|
this._w = w || 0;
|
|
}
|
|
|
|
if (update)
|
|
{
|
|
this.onChangeCallback(this);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Add a given Quaternion or Vector to this Quaternion. Addition is component-wise.
|
|
*
|
|
* @method Phaser.Math.Quaternion#add
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to add to this Quaternion.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
add: function (v)
|
|
{
|
|
this._x += v.x;
|
|
this._y += v.y;
|
|
this._z += v.z;
|
|
this._w += v.w;
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Subtract a given Quaternion or Vector from this Quaternion. Subtraction is component-wise.
|
|
*
|
|
* @method Phaser.Math.Quaternion#subtract
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to subtract from this Quaternion.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
subtract: function (v)
|
|
{
|
|
this._x -= v.x;
|
|
this._y -= v.y;
|
|
this._z -= v.z;
|
|
this._w -= v.w;
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Scale this Quaternion by the given value.
|
|
*
|
|
* @method Phaser.Math.Quaternion#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} scale - The value to scale this Quaternion by.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
scale: function (scale)
|
|
{
|
|
this._x *= scale;
|
|
this._y *= scale;
|
|
this._z *= scale;
|
|
this._w *= scale;
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the length of this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#length
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Quaternion.
|
|
*/
|
|
length: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
|
|
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
},
|
|
|
|
/**
|
|
* Calculate the length of this Quaternion squared.
|
|
*
|
|
* @method Phaser.Math.Quaternion#lengthSq
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Quaternion, squared.
|
|
*/
|
|
lengthSq: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
|
|
return x * x + y * y + z * z + w * w;
|
|
},
|
|
|
|
/**
|
|
* Normalize this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#normalize
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
normalize: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
var len = x * x + y * y + z * z + w * w;
|
|
|
|
if (len > 0)
|
|
{
|
|
len = 1 / Math.sqrt(len);
|
|
|
|
this._x = x * len;
|
|
this._y = y * len;
|
|
this._z = z * len;
|
|
this._w = w * len;
|
|
}
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the dot product of this Quaternion and the given Quaternion or Vector.
|
|
*
|
|
* @method Phaser.Math.Quaternion#dot
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to dot product with this Quaternion.
|
|
*
|
|
* @return {number} The dot product of this Quaternion and the given Quaternion or Vector.
|
|
*/
|
|
dot: function (v)
|
|
{
|
|
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
|
|
},
|
|
|
|
/**
|
|
* Linearly interpolate this Quaternion towards the given Quaternion or Vector.
|
|
*
|
|
* @method Phaser.Math.Quaternion#lerp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to interpolate towards.
|
|
* @param {number} [t=0] - The percentage of interpolation.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
lerp: function (v, t)
|
|
{
|
|
if (t === undefined) { t = 0; }
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
return this.set(
|
|
ax + t * (v.x - ax),
|
|
ay + t * (v.y - ay),
|
|
az + t * (v.z - az),
|
|
aw + t * (v.w - aw)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Rotates this Quaternion based on the two given vectors.
|
|
*
|
|
* @method Phaser.Math.Quaternion#rotationTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} a - The transform rotation vector.
|
|
* @param {Phaser.Math.Vector3} b - The target rotation vector.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
rotationTo: function (a, b)
|
|
{
|
|
var dot = a.x * b.x + a.y * b.y + a.z * b.z;
|
|
|
|
if (dot < -0.999999)
|
|
{
|
|
if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON)
|
|
{
|
|
tmpvec.copy(yUnitVec3).cross(a);
|
|
}
|
|
|
|
tmpvec.normalize();
|
|
|
|
return this.setAxisAngle(tmpvec, Math.PI);
|
|
|
|
}
|
|
else if (dot > 0.999999)
|
|
{
|
|
return this.set(0, 0, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
tmpvec.copy(a).cross(b);
|
|
|
|
this._x = tmpvec.x;
|
|
this._y = tmpvec.y;
|
|
this._z = tmpvec.z;
|
|
this._w = 1 + dot;
|
|
|
|
return this.normalize();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set the axes of this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#setAxes
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} view - The view axis.
|
|
* @param {Phaser.Math.Vector3} right - The right axis.
|
|
* @param {Phaser.Math.Vector3} up - The upwards axis.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
setAxes: function (view, right, up)
|
|
{
|
|
var m = tmpMat3.val;
|
|
|
|
m[0] = right.x;
|
|
m[3] = right.y;
|
|
m[6] = right.z;
|
|
|
|
m[1] = up.x;
|
|
m[4] = up.y;
|
|
m[7] = up.z;
|
|
|
|
m[2] = -view.x;
|
|
m[5] = -view.y;
|
|
m[8] = -view.z;
|
|
|
|
return this.fromMat3(tmpMat3).normalize();
|
|
},
|
|
|
|
/**
|
|
* Reset this Matrix to an identity (default) Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#identity
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
identity: function ()
|
|
{
|
|
return this.set(0, 0, 0, 1);
|
|
},
|
|
|
|
/**
|
|
* Set the axis angle of this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#setAxisAngle
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} axis - The axis.
|
|
* @param {number} rad - The angle in radians.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
setAxisAngle: function (axis, rad)
|
|
{
|
|
rad = rad * 0.5;
|
|
|
|
var s = Math.sin(rad);
|
|
|
|
return this.set(
|
|
s * axis.x,
|
|
s * axis.y,
|
|
s * axis.z,
|
|
Math.cos(rad)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Multiply this Quaternion by the given Quaternion or Vector.
|
|
*
|
|
* @method Phaser.Math.Quaternion#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to multiply this Quaternion by.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
multiply: function (b)
|
|
{
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
var bx = b.x;
|
|
var by = b.y;
|
|
var bz = b.z;
|
|
var bw = b.w;
|
|
|
|
return this.set(
|
|
ax * bw + aw * bx + ay * bz - az * by,
|
|
ay * bw + aw * by + az * bx - ax * bz,
|
|
az * bw + aw * bz + ax * by - ay * bx,
|
|
aw * bw - ax * bx - ay * by - az * bz
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Smoothly linearly interpolate this Quaternion towards the given Quaternion or Vector.
|
|
*
|
|
* @method Phaser.Math.Quaternion#slerp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to interpolate towards.
|
|
* @param {number} t - The percentage of interpolation.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
slerp: function (b, t)
|
|
{
|
|
// benchmarks: http://jsperf.com/quaternion-slerp-implementations
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
var bx = b.x;
|
|
var by = b.y;
|
|
var bz = b.z;
|
|
var bw = b.w;
|
|
|
|
// calc cosine
|
|
var cosom = ax * bx + ay * by + az * bz + aw * bw;
|
|
|
|
// adjust signs (if necessary)
|
|
if (cosom < 0)
|
|
{
|
|
cosom = -cosom;
|
|
bx = - bx;
|
|
by = - by;
|
|
bz = - bz;
|
|
bw = - bw;
|
|
}
|
|
|
|
// "from" and "to" quaternions are very close
|
|
// ... so we can do a linear interpolation
|
|
var scale0 = 1 - t;
|
|
var scale1 = t;
|
|
|
|
// calculate coefficients
|
|
if ((1 - cosom) > EPSILON)
|
|
{
|
|
// standard case (slerp)
|
|
var omega = Math.acos(cosom);
|
|
var sinom = Math.sin(omega);
|
|
|
|
scale0 = Math.sin((1.0 - t) * omega) / sinom;
|
|
scale1 = Math.sin(t * omega) / sinom;
|
|
}
|
|
|
|
// calculate final values
|
|
return this.set(
|
|
scale0 * ax + scale1 * bx,
|
|
scale0 * ay + scale1 * by,
|
|
scale0 * az + scale1 * bz,
|
|
scale0 * aw + scale1 * bw
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Invert this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#invert
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
invert: function ()
|
|
{
|
|
var a0 = this.x;
|
|
var a1 = this.y;
|
|
var a2 = this.z;
|
|
var a3 = this.w;
|
|
|
|
var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
|
|
var invDot = (dot) ? 1 / dot : 0;
|
|
|
|
return this.set(
|
|
-a0 * invDot,
|
|
-a1 * invDot,
|
|
-a2 * invDot,
|
|
a3 * invDot
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Convert this Quaternion into its conjugate.
|
|
*
|
|
* Sets the x, y and z components.
|
|
*
|
|
* @method Phaser.Math.Quaternion#conjugate
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
conjugate: function ()
|
|
{
|
|
this._x = -this.x;
|
|
this._y = -this.y;
|
|
this._z = -this.z;
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Rotate this Quaternion on the X axis.
|
|
*
|
|
* @method Phaser.Math.Quaternion#rotateX
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The rotation angle in radians.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
rotateX: function (rad)
|
|
{
|
|
rad *= 0.5;
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
var bx = Math.sin(rad);
|
|
var bw = Math.cos(rad);
|
|
|
|
return this.set(
|
|
ax * bw + aw * bx,
|
|
ay * bw + az * bx,
|
|
az * bw - ay * bx,
|
|
aw * bw - ax * bx
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Rotate this Quaternion on the Y axis.
|
|
*
|
|
* @method Phaser.Math.Quaternion#rotateY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The rotation angle in radians.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
rotateY: function (rad)
|
|
{
|
|
rad *= 0.5;
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
var by = Math.sin(rad);
|
|
var bw = Math.cos(rad);
|
|
|
|
return this.set(
|
|
ax * bw - az * by,
|
|
ay * bw + aw * by,
|
|
az * bw + ax * by,
|
|
aw * bw - ay * by
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Rotate this Quaternion on the Z axis.
|
|
*
|
|
* @method Phaser.Math.Quaternion#rotateZ
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} rad - The rotation angle in radians.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
rotateZ: function (rad)
|
|
{
|
|
rad *= 0.5;
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
var bz = Math.sin(rad);
|
|
var bw = Math.cos(rad);
|
|
|
|
return this.set(
|
|
ax * bw + ay * bz,
|
|
ay * bw - ax * bz,
|
|
az * bw + aw * bz,
|
|
aw * bw - az * bz
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Create a unit (or rotation) Quaternion from its x, y, and z components.
|
|
*
|
|
* Sets the w component.
|
|
*
|
|
* @method Phaser.Math.Quaternion#calculateW
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
calculateW: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
|
|
this.w = -Math.sqrt(1.0 - x * x - y * y - z * z);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set this Quaternion from the given Euler, based on Euler order.
|
|
*
|
|
* @method Phaser.Math.Quaternion#setFromEuler
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Euler} euler - The Euler to convert from.
|
|
* @param {boolean} [update=true] - Run the `onChangeCallback`?
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
setFromEuler: function (euler, update)
|
|
{
|
|
var x = euler.x / 2;
|
|
var y = euler.y / 2;
|
|
var z = euler.z / 2;
|
|
|
|
var c1 = Math.cos(x);
|
|
var c2 = Math.cos(y);
|
|
var c3 = Math.cos(z);
|
|
|
|
var s1 = Math.sin(x);
|
|
var s2 = Math.sin(y);
|
|
var s3 = Math.sin(z);
|
|
|
|
switch (euler.order)
|
|
{
|
|
case 'XYZ':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 + c1 * s2 * s3,
|
|
c1 * s2 * c3 - s1 * c2 * s3,
|
|
c1 * c2 * s3 + s1 * s2 * c3,
|
|
c1 * c2 * c3 - s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 'YXZ':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 + c1 * s2 * s3,
|
|
c1 * s2 * c3 - s1 * c2 * s3,
|
|
c1 * c2 * s3 - s1 * s2 * c3,
|
|
c1 * c2 * c3 + s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 'ZXY':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 - c1 * s2 * s3,
|
|
c1 * s2 * c3 + s1 * c2 * s3,
|
|
c1 * c2 * s3 + s1 * s2 * c3,
|
|
c1 * c2 * c3 - s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 'ZYX':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 - c1 * s2 * s3,
|
|
c1 * s2 * c3 + s1 * c2 * s3,
|
|
c1 * c2 * s3 - s1 * s2 * c3,
|
|
c1 * c2 * c3 + s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 'YZX':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 + c1 * s2 * s3,
|
|
c1 * s2 * c3 + s1 * c2 * s3,
|
|
c1 * c2 * s3 - s1 * s2 * c3,
|
|
c1 * c2 * c3 - s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 'XZY':
|
|
{
|
|
this.set(
|
|
s1 * c2 * c3 - c1 * s2 * s3,
|
|
c1 * s2 * c3 - s1 * c2 * s3,
|
|
c1 * c2 * s3 + s1 * s2 * c3,
|
|
c1 * c2 * c3 + s1 * s2 * s3,
|
|
update
|
|
);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the rotation of this Quaternion from the given Matrix4.
|
|
*
|
|
* @method Phaser.Math.Quaternion#setFromRotationMatrix
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to set the rotation from.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
setFromRotationMatrix: function (mat4)
|
|
{
|
|
var m = mat4.val;
|
|
|
|
var m11 = m[0];
|
|
var m12 = m[4];
|
|
var m13 = m[8];
|
|
var m21 = m[1];
|
|
var m22 = m[5];
|
|
var m23 = m[9];
|
|
var m31 = m[2];
|
|
var m32 = m[6];
|
|
var m33 = m[10];
|
|
|
|
var trace = m11 + m22 + m33;
|
|
var s;
|
|
|
|
if (trace > 0)
|
|
{
|
|
s = 0.5 / Math.sqrt(trace + 1.0);
|
|
|
|
this.set(
|
|
(m32 - m23) * s,
|
|
(m13 - m31) * s,
|
|
(m21 - m12) * s,
|
|
0.25 / s
|
|
);
|
|
}
|
|
else if (m11 > m22 && m11 > m33)
|
|
{
|
|
s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
|
|
|
|
this.set(
|
|
0.25 * s,
|
|
(m12 + m21) / s,
|
|
(m13 + m31) / s,
|
|
(m32 - m23) / s
|
|
);
|
|
}
|
|
else if (m22 > m33)
|
|
{
|
|
s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
|
|
|
|
this.set(
|
|
(m12 + m21) / s,
|
|
0.25 * s,
|
|
(m23 + m32) / s,
|
|
(m13 - m31) / s
|
|
);
|
|
}
|
|
else
|
|
{
|
|
s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
|
|
|
|
this.set(
|
|
(m13 + m31) / s,
|
|
(m23 + m32) / s,
|
|
0.25 * s,
|
|
(m21 - m12) / s
|
|
);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Convert the given Matrix into this Quaternion.
|
|
*
|
|
* @method Phaser.Math.Quaternion#fromMat3
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix3} mat - The Matrix to convert from.
|
|
*
|
|
* @return {Phaser.Math.Quaternion} This Quaternion.
|
|
*/
|
|
fromMat3: function (mat)
|
|
{
|
|
// benchmarks:
|
|
// http://jsperf.com/typed-array-access-speed
|
|
// http://jsperf.com/conversion-of-3x3-matrix-to-quaternion
|
|
|
|
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
|
|
// article "Quaternion Calculus and Fast Animation".
|
|
var m = mat.val;
|
|
var fTrace = m[0] + m[4] + m[8];
|
|
var fRoot;
|
|
|
|
if (fTrace > 0)
|
|
{
|
|
// |w| > 1/2, may as well choose w > 1/2
|
|
fRoot = Math.sqrt(fTrace + 1.0); // 2w
|
|
|
|
this.w = 0.5 * fRoot;
|
|
|
|
fRoot = 0.5 / fRoot; // 1/(4w)
|
|
|
|
this._x = (m[7] - m[5]) * fRoot;
|
|
this._y = (m[2] - m[6]) * fRoot;
|
|
this._z = (m[3] - m[1]) * fRoot;
|
|
}
|
|
else
|
|
{
|
|
// |w| <= 1/2
|
|
var i = 0;
|
|
|
|
if (m[4] > m[0])
|
|
{
|
|
i = 1;
|
|
}
|
|
|
|
if (m[8] > m[i * 3 + i])
|
|
{
|
|
i = 2;
|
|
}
|
|
|
|
var j = siNext[i];
|
|
var k = siNext[j];
|
|
|
|
// This isn't quite as clean without array access
|
|
fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1);
|
|
tmp[i] = 0.5 * fRoot;
|
|
|
|
fRoot = 0.5 / fRoot;
|
|
|
|
tmp[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
|
|
tmp[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
|
|
|
|
this._x = tmp[0];
|
|
this._y = tmp[1];
|
|
this._z = tmp[2];
|
|
this._w = (m[k * 3 + j] - m[j * 3 + k]) * fRoot;
|
|
}
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Quaternion;
|
|
|
|
|
|
/***/ }),
|
|
/* 44 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Extend = __webpack_require__(27);
|
|
var XHRSettings = __webpack_require__(45);
|
|
|
|
/**
|
|
* Takes two XHRSettings Objects and creates a new XHRSettings object from them.
|
|
*
|
|
* The new object is seeded by the values given in the global settings, but any setting in
|
|
* the local object overrides the global ones.
|
|
*
|
|
* @function Phaser.Loader.MergeXHRSettings
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} global - The global XHRSettings object.
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} local - The local XHRSettings object.
|
|
*
|
|
* @return {Phaser.Types.Loader.XHRSettingsObject} A newly formed XHRSettings object.
|
|
*/
|
|
var MergeXHRSettings = function (global, local)
|
|
{
|
|
var output = (global === undefined) ? XHRSettings() : Extend({}, global);
|
|
|
|
if (local)
|
|
{
|
|
for (var setting in local)
|
|
{
|
|
if (local[setting] !== undefined)
|
|
{
|
|
output[setting] = local[setting];
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
|
|
module.exports = MergeXHRSettings;
|
|
|
|
|
|
/***/ }),
|
|
/* 45 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Creates an XHRSettings Object with default values.
|
|
*
|
|
* @function Phaser.Loader.XHRSettings
|
|
* @since 3.0.0
|
|
*
|
|
* @param {XMLHttpRequestResponseType} [responseType=''] - The responseType, such as 'text'.
|
|
* @param {boolean} [async=true] - Should the XHR request use async or not?
|
|
* @param {string} [user=''] - Optional username for the XHR request.
|
|
* @param {string} [password=''] - Optional password for the XHR request.
|
|
* @param {integer} [timeout=0] - Optional XHR timeout value.
|
|
* @param {boolean} [withCredentials=false] - Optional XHR withCredentials value.
|
|
*
|
|
* @return {Phaser.Types.Loader.XHRSettingsObject} The XHRSettings object as used by the Loader.
|
|
*/
|
|
var XHRSettings = function (responseType, async, user, password, timeout, withCredentials)
|
|
{
|
|
if (responseType === undefined) { responseType = ''; }
|
|
if (async === undefined) { async = true; }
|
|
if (user === undefined) { user = ''; }
|
|
if (password === undefined) { password = ''; }
|
|
if (timeout === undefined) { timeout = 0; }
|
|
if (withCredentials === undefined) { withCredentials = false; }
|
|
|
|
// Before sending a request, set the xhr.responseType to "text",
|
|
// "arraybuffer", "blob", or "document", depending on your data needs.
|
|
// Note, setting xhr.responseType = '' (or omitting) will default the response to "text".
|
|
|
|
return {
|
|
|
|
// Ignored by the Loader, only used by File.
|
|
responseType: responseType,
|
|
|
|
async: async,
|
|
|
|
// credentials
|
|
user: user,
|
|
password: password,
|
|
|
|
// timeout in ms (0 = no timeout)
|
|
timeout: timeout,
|
|
|
|
// setRequestHeader
|
|
headers: undefined,
|
|
header: undefined,
|
|
headerValue: undefined,
|
|
requestedWith: false,
|
|
|
|
// overrideMimeType
|
|
overrideMimeType: undefined,
|
|
|
|
// withCredentials
|
|
withCredentials: withCredentials
|
|
|
|
};
|
|
};
|
|
|
|
module.exports = XHRSettings;
|
|
|
|
|
|
/***/ }),
|
|
/* 46 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for calculating and setting the size of a non-Frame based Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.ComputedSize
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var ComputedSize = {
|
|
|
|
/**
|
|
* The native (un-scaled) width of this Game Object.
|
|
*
|
|
* Changing this value will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or use
|
|
* the `displayWidth` property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ComputedSize#width
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
width: 0,
|
|
|
|
/**
|
|
* The native (un-scaled) height of this Game Object.
|
|
*
|
|
* Changing this value will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or use
|
|
* the `displayHeight` property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ComputedSize#height
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
height: 0,
|
|
|
|
/**
|
|
* The displayed width of this Game Object.
|
|
*
|
|
* This value takes into account the scale factor.
|
|
*
|
|
* Setting this value will adjust the Game Object's scale property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ComputedSize#displayWidth
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayWidth: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.scaleX * this.width;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.scaleX = value / this.width;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The displayed height of this Game Object.
|
|
*
|
|
* This value takes into account the scale factor.
|
|
*
|
|
* Setting this value will adjust the Game Object's scale property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ComputedSize#displayHeight
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayHeight: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.scaleY * this.height;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.scaleY = value / this.height;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the internal size of this Game Object, as used for frame or physics body creation.
|
|
*
|
|
* This will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or call the
|
|
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
|
|
* to do so by giving pixel values.
|
|
*
|
|
* If you have enabled this Game Object for input, changing the size will _not_ change the
|
|
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
|
|
*
|
|
* @method Phaser.GameObjects.Components.ComputedSize#setSize
|
|
* @since 3.4.0
|
|
*
|
|
* @param {number} width - The width of this Game Object.
|
|
* @param {number} height - The height of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setSize: function (width, height)
|
|
{
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the display size of this Game Object.
|
|
*
|
|
* Calling this will adjust the scale.
|
|
*
|
|
* @method Phaser.GameObjects.Components.ComputedSize#setDisplaySize
|
|
* @since 3.4.0
|
|
*
|
|
* @param {number} width - The width of this Game Object.
|
|
* @param {number} height - The height of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setDisplaySize: function (width, height)
|
|
{
|
|
this.displayWidth = width;
|
|
this.displayHeight = height;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ComputedSize;
|
|
|
|
|
|
/***/ }),
|
|
/* 47 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for setting the depth of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Depth
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Depth = {
|
|
|
|
/**
|
|
* Private internal value. Holds the depth of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Depth#_depth
|
|
* @type {integer}
|
|
* @private
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
_depth: 0,
|
|
|
|
/**
|
|
* The depth of this Game Object within the Scene.
|
|
*
|
|
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
|
|
* of Game Objects, without actually moving their position in the display list.
|
|
*
|
|
* The default depth is zero. A Game Object with a higher depth
|
|
* value will always render in front of one with a lower value.
|
|
*
|
|
* Setting the depth will queue a depth sort event within the Scene.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Depth#depth
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
depth: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._depth;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.scene.sys.queueDepthSort();
|
|
this._depth = value;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The depth of this Game Object within the Scene.
|
|
*
|
|
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
|
|
* of Game Objects, without actually moving their position in the display list.
|
|
*
|
|
* The default depth is zero. A Game Object with a higher depth
|
|
* value will always render in front of one with a lower value.
|
|
*
|
|
* Setting the depth will queue a depth sort event within the Scene.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Depth#setDepth
|
|
* @since 3.0.0
|
|
*
|
|
* @param {integer} value - The depth of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setDepth: function (value)
|
|
{
|
|
if (value === undefined) { value = 0; }
|
|
|
|
this.depth = value;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Depth;
|
|
|
|
|
|
/***/ }),
|
|
/* 48 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for visually flipping a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Flip
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Flip = {
|
|
|
|
/**
|
|
* The horizontally flipped state of the Game Object.
|
|
*
|
|
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
|
|
* Flipping always takes place from the middle of the texture and does not impact the scale value.
|
|
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Flip#flipX
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.0.0
|
|
*/
|
|
flipX: false,
|
|
|
|
/**
|
|
* The vertically flipped state of the Game Object.
|
|
*
|
|
* A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)
|
|
* Flipping always takes place from the middle of the texture and does not impact the scale value.
|
|
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Flip#flipY
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.0.0
|
|
*/
|
|
flipY: false,
|
|
|
|
/**
|
|
* Toggles the horizontal flipped state of this Game Object.
|
|
*
|
|
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
|
|
* Flipping always takes place from the middle of the texture and does not impact the scale value.
|
|
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#toggleFlipX
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
toggleFlipX: function ()
|
|
{
|
|
this.flipX = !this.flipX;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Toggles the vertical flipped state of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#toggleFlipY
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
toggleFlipY: function ()
|
|
{
|
|
this.flipY = !this.flipY;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the horizontal flipped state of this Game Object.
|
|
*
|
|
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
|
|
* Flipping always takes place from the middle of the texture and does not impact the scale value.
|
|
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#setFlipX
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setFlipX: function (value)
|
|
{
|
|
this.flipX = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the vertical flipped state of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#setFlipY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setFlipY: function (value)
|
|
{
|
|
this.flipY = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the horizontal and vertical flipped state of this Game Object.
|
|
*
|
|
* A Game Object that is flipped will render inversed on the flipped axis.
|
|
* Flipping always takes place from the middle of the texture and does not impact the scale value.
|
|
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#setFlip
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
|
|
* @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setFlip: function (x, y)
|
|
{
|
|
this.flipX = x;
|
|
this.flipY = y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Flip#resetFlip
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
resetFlip: function ()
|
|
{
|
|
this.flipX = false;
|
|
this.flipY = false;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Flip;
|
|
|
|
|
|
/***/ }),
|
|
/* 49 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the Scroll Factor of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.ScrollFactor
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var ScrollFactor = {
|
|
|
|
/**
|
|
* The horizontal scroll factor of this Game Object.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
|
|
* It does not change the Game Objects actual position values.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Game Object.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorX
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
scrollFactorX: 1,
|
|
|
|
/**
|
|
* The vertical scroll factor of this Game Object.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
|
|
* It does not change the Game Objects actual position values.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Game Object.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorY
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
scrollFactorY: 1,
|
|
|
|
/**
|
|
* Sets the scroll factor of this Game Object.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
|
|
* It does not change the Game Objects actual position values.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Game Object.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @method Phaser.GameObjects.Components.ScrollFactor#setScrollFactor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal scroll factor of this Game Object.
|
|
* @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setScrollFactor: function (x, y)
|
|
{
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.scrollFactorX = x;
|
|
this.scrollFactorY = y;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ScrollFactor;
|
|
|
|
|
|
/***/ }),
|
|
/* 50 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MATH_CONST = __webpack_require__(3);
|
|
var TransformMatrix = __webpack_require__(23);
|
|
var TransformXY = __webpack_require__(41);
|
|
var WrapAngle = __webpack_require__(30);
|
|
var WrapAngleDegrees = __webpack_require__(31);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
// global bitmask flag for GameObject.renderMask (used by Scale)
|
|
var _FLAG = 4; // 0100
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the position, scale and rotation of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Transform
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Transform = {
|
|
|
|
/**
|
|
* Private internal value. Holds the horizontal scale value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#_scaleX
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_scaleX: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the vertical scale value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#_scaleY
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_scaleY: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the rotation value in radians.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#_rotation
|
|
* @type {number}
|
|
* @private
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
_rotation: 0,
|
|
|
|
/**
|
|
* The x position of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
x: 0,
|
|
|
|
/**
|
|
* The y position of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
y: 0,
|
|
|
|
/**
|
|
* The z position of this Game Object.
|
|
*
|
|
* Note: The z position does not control the rendering order of 2D Game Objects. Use
|
|
* {@link Phaser.GameObjects.Components.Depth#depth} instead.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#z
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
z: 0,
|
|
|
|
/**
|
|
* The w position of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#w
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
w: 0,
|
|
|
|
/**
|
|
* This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object
|
|
* to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`.
|
|
*
|
|
* Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this
|
|
* isn't the case, use the `scaleX` or `scaleY` properties instead.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#scale
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.18.0
|
|
*/
|
|
scale: {
|
|
|
|
get: function ()
|
|
{
|
|
return (this._scaleX + this._scaleY) / 2;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._scaleX = value;
|
|
this._scaleY = value;
|
|
|
|
if (value === 0)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The horizontal scale of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#scaleX
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
scaleX: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._scaleX;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._scaleX = value;
|
|
|
|
if (value === 0)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The vertical scale of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#scaleY
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
scaleY: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._scaleY;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._scaleY = value;
|
|
|
|
if (value === 0)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The angle of this Game Object as expressed in degrees.
|
|
*
|
|
* Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left
|
|
* and -90 is up.
|
|
*
|
|
* If you prefer to work in radians, see the `rotation` property instead.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#angle
|
|
* @type {integer}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
angle: {
|
|
|
|
get: function ()
|
|
{
|
|
return WrapAngleDegrees(this._rotation * MATH_CONST.RAD_TO_DEG);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
// value is in degrees
|
|
this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* The angle of this Game Object in radians.
|
|
*
|
|
* Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left
|
|
* and -PI/2 is up.
|
|
*
|
|
* If you prefer to work in degrees, see the `angle` property instead.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Transform#rotation
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
rotation: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._rotation;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
// value is in radians
|
|
this._rotation = WrapAngle(value);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sets the position of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setPosition
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The x position of this Game Object.
|
|
* @param {number} [y=x] - The y position of this Game Object. If not set it will use the `x` value.
|
|
* @param {number} [z=0] - The z position of this Game Object.
|
|
* @param {number} [w=0] - The w position of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setPosition: function (x, y, z, w)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = x; }
|
|
if (z === undefined) { z = 0; }
|
|
if (w === undefined) { w = 0; }
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.w = w;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Copies an object's coordinates to this Game Object's position.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#copyPosition
|
|
* @since 3.50.0
|
|
*
|
|
* @param {(Phaser.Types.Math.Vector2Like|Phaser.Types.Math.Vector3Like|Phaser.Types.Math.Vector4Like)} source - An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
copyPosition: function (source)
|
|
{
|
|
if (source.x !== undefined) { this.x = source.x; }
|
|
if (source.y !== undefined) { this.y = source.y; }
|
|
if (source.z !== undefined) { this.z = source.z; }
|
|
if (source.w !== undefined) { this.w = source.w; }
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the position of this Game Object to be a random position within the confines of
|
|
* the given area.
|
|
*
|
|
* If no area is specified a random position between 0 x 0 and the game width x height is used instead.
|
|
*
|
|
* The position does not factor in the size of this Game Object, meaning that only the origin is
|
|
* guaranteed to be within the area.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setRandomPosition
|
|
* @since 3.8.0
|
|
*
|
|
* @param {number} [x=0] - The x position of the top-left of the random area.
|
|
* @param {number} [y=0] - The y position of the top-left of the random area.
|
|
* @param {number} [width] - The width of the random area.
|
|
* @param {number} [height] - The height of the random area.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setRandomPosition: function (x, y, width, height)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = 0; }
|
|
if (width === undefined) { width = this.scene.sys.scale.width; }
|
|
if (height === undefined) { height = this.scene.sys.scale.height; }
|
|
|
|
this.x = x + (Math.random() * width);
|
|
this.y = y + (Math.random() * height);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the rotation of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setRotation
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [radians=0] - The rotation of this Game Object, in radians.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setRotation: function (radians)
|
|
{
|
|
if (radians === undefined) { radians = 0; }
|
|
|
|
this.rotation = radians;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the angle of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setAngle
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [degrees=0] - The rotation of this Game Object, in degrees.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setAngle: function (degrees)
|
|
{
|
|
if (degrees === undefined) { degrees = 0; }
|
|
|
|
this.angle = degrees;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the scale of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setScale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal scale of this Game Object.
|
|
* @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the `x` value.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setScale: function (x, y)
|
|
{
|
|
if (x === undefined) { x = 1; }
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.scaleX = x;
|
|
this.scaleY = y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the x position of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setX
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [value=0] - The x position of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setX: function (value)
|
|
{
|
|
if (value === undefined) { value = 0; }
|
|
|
|
this.x = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the y position of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [value=0] - The y position of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setY: function (value)
|
|
{
|
|
if (value === undefined) { value = 0; }
|
|
|
|
this.y = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the z position of this Game Object.
|
|
*
|
|
* Note: The z position does not control the rendering order of 2D Game Objects. Use
|
|
* {@link Phaser.GameObjects.Components.Depth#setDepth} instead.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setZ
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [value=0] - The z position of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setZ: function (value)
|
|
{
|
|
if (value === undefined) { value = 0; }
|
|
|
|
this.z = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the w position of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#setW
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [value=0] - The w position of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setW: function (value)
|
|
{
|
|
if (value === undefined) { value = 0; }
|
|
|
|
this.w = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Gets the local transform matrix for this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#getLocalTransformMatrix
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
|
|
*
|
|
* @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
|
|
*/
|
|
getLocalTransformMatrix: function (tempMatrix)
|
|
{
|
|
if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); }
|
|
|
|
return tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
|
|
},
|
|
|
|
/**
|
|
* Gets the world transform matrix for this Game Object, factoring in any parent Containers.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#getWorldTransformMatrix
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations.
|
|
*
|
|
* @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
|
|
*/
|
|
getWorldTransformMatrix: function (tempMatrix, parentMatrix)
|
|
{
|
|
if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); }
|
|
if (parentMatrix === undefined) { parentMatrix = new TransformMatrix(); }
|
|
|
|
var parent = this.parentContainer;
|
|
|
|
if (!parent)
|
|
{
|
|
return this.getLocalTransformMatrix(tempMatrix);
|
|
}
|
|
|
|
tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
|
|
|
|
while (parent)
|
|
{
|
|
parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY);
|
|
|
|
parentMatrix.multiply(tempMatrix, tempMatrix);
|
|
|
|
parent = parent.parentContainer;
|
|
}
|
|
|
|
return tempMatrix;
|
|
},
|
|
|
|
/**
|
|
* Takes the given `x` and `y` coordinates and converts them into local space for this
|
|
* Game Object, taking into account parent and local transforms, and the Display Origin.
|
|
*
|
|
* The returned Vector2 contains the translated point in its properties.
|
|
*
|
|
* A Camera needs to be provided in order to handle modified scroll factors. If no
|
|
* camera is specified, it will use the `main` camera from the Scene to which this
|
|
* Game Object belongs.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#getLocalPoint
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number} x - The x position to translate.
|
|
* @param {number} y - The y position to translate.
|
|
* @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
|
|
*
|
|
* @return {Phaser.Math.Vector2} The translated point.
|
|
*/
|
|
getLocalPoint: function (x, y, point, camera)
|
|
{
|
|
if (!point) { point = new Vector2(); }
|
|
if (!camera) { camera = this.scene.sys.cameras.main; }
|
|
|
|
var csx = camera.scrollX;
|
|
var csy = camera.scrollY;
|
|
|
|
var px = x + (csx * this.scrollFactorX) - csx;
|
|
var py = y + (csy * this.scrollFactorY) - csy;
|
|
|
|
if (this.parentContainer)
|
|
{
|
|
this.getWorldTransformMatrix().applyInverse(px, py, point);
|
|
}
|
|
else
|
|
{
|
|
TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point);
|
|
}
|
|
|
|
// Normalize origin
|
|
if (this._originComponent)
|
|
{
|
|
point.x += this._displayOriginX;
|
|
point.y += this._displayOriginY;
|
|
}
|
|
|
|
return point;
|
|
},
|
|
|
|
/**
|
|
* Gets the sum total rotation of all of this Game Objects parent Containers.
|
|
*
|
|
* The returned value is in radians and will be zero if this Game Object has no parent container.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Transform#getParentRotation
|
|
* @since 3.18.0
|
|
*
|
|
* @return {number} The sum total rotation, in radians, of all parent containers of this Game Object.
|
|
*/
|
|
getParentRotation: function ()
|
|
{
|
|
var rotation = 0;
|
|
|
|
var parent = this.parentContainer;
|
|
|
|
while (parent)
|
|
{
|
|
rotation += parent.rotation;
|
|
|
|
parent = parent.parentContainer;
|
|
}
|
|
|
|
return rotation;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Transform;
|
|
|
|
|
|
/***/ }),
|
|
/* 51 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// bitmask flag for GameObject.renderMask
|
|
var _FLAG = 1; // 0001
|
|
|
|
/**
|
|
* Provides methods used for setting the visibility of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Visible
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Visible = {
|
|
|
|
/**
|
|
* Private internal value. Holds the visible value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Visible#_visible
|
|
* @type {boolean}
|
|
* @private
|
|
* @default true
|
|
* @since 3.0.0
|
|
*/
|
|
_visible: true,
|
|
|
|
/**
|
|
* The visible state of the Game Object.
|
|
*
|
|
* An invisible Game Object will skip rendering, but will still process update logic.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Visible#visible
|
|
* @type {boolean}
|
|
* @since 3.0.0
|
|
*/
|
|
visible: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._visible;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (value)
|
|
{
|
|
this._visible = true;
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
else
|
|
{
|
|
this._visible = false;
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the visibility of this Game Object.
|
|
*
|
|
* An invisible Game Object will skip rendering, but will still process update logic.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Visible#setVisible
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} value - The visible state of the Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setVisible: function (value)
|
|
{
|
|
this.visible = value;
|
|
|
|
return this;
|
|
}
|
|
};
|
|
|
|
module.exports = Visible;
|
|
|
|
|
|
/***/ }),
|
|
/* 52 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var ComponentsToJSON = __webpack_require__(53);
|
|
var DataManager = __webpack_require__(219);
|
|
var EventEmitter = __webpack_require__(226);
|
|
var Events = __webpack_require__(54);
|
|
|
|
/**
|
|
* @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);
|
|
|
|
/**
|
|
* A reference to the Scene to which this Game Object belongs.
|
|
*
|
|
* Game Objects can only belong to one Scene.
|
|
*
|
|
* You should consider this property as being read-only. You cannot move a
|
|
* Game Object to another Scene by simply changing it.
|
|
*
|
|
* @name Phaser.GameObjects.GameObject#scene
|
|
* @type {Phaser.Scene}
|
|
* @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 current state of this Game Object.
|
|
*
|
|
* Phaser itself will never modify this value, although plugins may do so.
|
|
*
|
|
* Use this property to track the state of a Game Object during its lifetime. For example, it could change from
|
|
* a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant
|
|
* in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons.
|
|
* If you need to store complex data about your Game Object, look at using the Data Component instead.
|
|
*
|
|
* @name Phaser.GameObjects.GameObject#state
|
|
* @type {(integer|string)}
|
|
* @since 3.16.0
|
|
*/
|
|
this.state = 0;
|
|
|
|
/**
|
|
* 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.Types.Input.InteractiveObject}
|
|
* @default null
|
|
* @since 3.0.0
|
|
*/
|
|
this.input = null;
|
|
|
|
/**
|
|
* If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body.
|
|
*
|
|
* @name Phaser.GameObjects.GameObject#body
|
|
* @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)}
|
|
* @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;
|
|
},
|
|
|
|
/**
|
|
* Sets the current state of this Game Object.
|
|
*
|
|
* Phaser itself will never modify the State of a Game Object, although plugins may do so.
|
|
*
|
|
* For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'.
|
|
* The state value should typically be an integer (ideally mapped to a constant
|
|
* in your game code), but could also be a string. It is recommended to keep it light and simple.
|
|
* If you need to store complex data about your Game Object, look at using the Data Component instead.
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#setState
|
|
* @since 3.16.0
|
|
*
|
|
* @param {(integer|string)} value - The state of the Game Object.
|
|
*
|
|
* @return {this} This GameObject.
|
|
*/
|
|
setState: function (value)
|
|
{
|
|
this.state = 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 of 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;
|
|
},
|
|
|
|
/**
|
|
* Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0.
|
|
*
|
|
* 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.
|
|
*
|
|
* When the value is first set, a `setdata` event is emitted from this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#incData
|
|
* @since 3.23.0
|
|
*
|
|
* @param {(string|object)} key - The key to increase the value for.
|
|
* @param {*} [data] - The value to increase for the given key.
|
|
*
|
|
* @return {this} This GameObject.
|
|
*/
|
|
incData: function (key, value)
|
|
{
|
|
if (!this.data)
|
|
{
|
|
this.data = new DataManager(this);
|
|
}
|
|
|
|
this.data.inc(key, value);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false.
|
|
*
|
|
* 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.
|
|
*
|
|
* When the value is first set, a `setdata` event is emitted from this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#toggleData
|
|
* @since 3.23.0
|
|
*
|
|
* @param {(string|object)} key - The key to toggle the value for.
|
|
*
|
|
* @return {this} This GameObject.
|
|
*/
|
|
toggleData: function (key)
|
|
{
|
|
if (!this.data)
|
|
{
|
|
this.data = new DataManager(this);
|
|
}
|
|
|
|
this.data.toggle(key);
|
|
|
|
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.
|
|
*
|
|
* @example
|
|
* sprite.setInteractive();
|
|
*
|
|
* @example
|
|
* sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains);
|
|
*
|
|
* @example
|
|
* graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains);
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#setInteractive
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame.
|
|
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. 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 (hitArea, hitAreaCallback, dropZone)
|
|
{
|
|
this.scene.sys.input.enable(this, hitArea, hitAreaCallback, 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;
|
|
},
|
|
|
|
/**
|
|
* This callback is invoked when this Game Object is added to a Scene.
|
|
*
|
|
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
|
|
* will use this, such as Sprites, to add themselves into the Update List.
|
|
*
|
|
* You can also listen for the `ADDED_TO_SCENE` event from this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#addedToScene
|
|
* @since 3.50.0
|
|
*/
|
|
addedToScene: function ()
|
|
{
|
|
},
|
|
|
|
/**
|
|
* This callback is invoked when this Game Object is removed from a Scene.
|
|
*
|
|
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
|
|
* will use this, such as Sprites, to removed themselves from the Update List.
|
|
*
|
|
* You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.GameObject#removedFromScene
|
|
* @since 3.50.0
|
|
*/
|
|
removedFromScene: function ()
|
|
{
|
|
},
|
|
|
|
/**
|
|
* 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 {Phaser.Types.GameObjects.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));
|
|
|
|
return indexes;
|
|
},
|
|
|
|
/**
|
|
* Destroys this Game Object removing it from the Display List and Update List and
|
|
* severing all ties to parent resources.
|
|
*
|
|
* Also removes itself from the Input Manager and Physics Manager if previously enabled.
|
|
*
|
|
* Use this to remove a Game Object 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.GameObject#destroy
|
|
* @fires Phaser.GameObjects.Events#DESTROY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} [fromScene=false] - Is this Game Object being destroyed as the result of a Scene shutdown?
|
|
*/
|
|
destroy: function (fromScene)
|
|
{
|
|
if (fromScene === undefined) { fromScene = false; }
|
|
|
|
// This Game Object has already been destroyed
|
|
if (!this.scene || this.ignoreDestroy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this.preDestroy)
|
|
{
|
|
this.preDestroy.call(this);
|
|
}
|
|
|
|
this.emit(Events.DESTROY, this);
|
|
|
|
var sys = this.scene.sys;
|
|
|
|
if (!fromScene)
|
|
{
|
|
sys.displayList.remove(this);
|
|
}
|
|
|
|
if (this.input)
|
|
{
|
|
sys.input.clear(this);
|
|
this.input = undefined;
|
|
}
|
|
|
|
if (this.data)
|
|
{
|
|
this.data.destroy();
|
|
|
|
this.data = undefined;
|
|
}
|
|
|
|
if (this.body)
|
|
{
|
|
this.body.destroy();
|
|
this.body = undefined;
|
|
}
|
|
|
|
// Tell the Scene to re-sort the children
|
|
if (!fromScene)
|
|
{
|
|
sys.queueDepthSort();
|
|
}
|
|
|
|
this.active = false;
|
|
this.visible = false;
|
|
|
|
this.scene = undefined;
|
|
|
|
this.parentContainer = undefined;
|
|
|
|
this.removeAllListeners();
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not.
|
|
*
|
|
* @constant {integer} RENDER_MASK
|
|
* @memberof Phaser.GameObjects.GameObject
|
|
* @default
|
|
*/
|
|
GameObject.RENDER_MASK = 15;
|
|
|
|
module.exports = GameObject;
|
|
|
|
|
|
/***/ }),
|
|
/* 53 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Build a JSON representation of the given Game Object.
|
|
*
|
|
* This is typically extended further by Game Object specific implementations.
|
|
*
|
|
* @method Phaser.GameObjects.Components.ToJSON
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to export as JSON.
|
|
*
|
|
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
|
|
*/
|
|
var ToJSON = function (gameObject)
|
|
{
|
|
var out = {
|
|
name: gameObject.name,
|
|
type: gameObject.type,
|
|
x: gameObject.x,
|
|
y: gameObject.y,
|
|
depth: gameObject.depth,
|
|
scale: {
|
|
x: gameObject.scaleX,
|
|
y: gameObject.scaleY
|
|
},
|
|
origin: {
|
|
x: gameObject.originX,
|
|
y: gameObject.originY
|
|
},
|
|
flipX: gameObject.flipX,
|
|
flipY: gameObject.flipY,
|
|
rotation: gameObject.rotation,
|
|
alpha: gameObject.alpha,
|
|
visible: gameObject.visible,
|
|
blendMode: gameObject.blendMode,
|
|
textureKey: '',
|
|
frameKey: '',
|
|
data: {}
|
|
};
|
|
|
|
if (gameObject.texture)
|
|
{
|
|
out.textureKey = gameObject.texture.key;
|
|
out.frameKey = gameObject.frame.name;
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = ToJSON;
|
|
|
|
|
|
/***/ }),
|
|
/* 54 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.GameObjects.Events
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
ADDED_TO_SCENE: __webpack_require__(227),
|
|
DESTROY: __webpack_require__(228),
|
|
REMOVED_FROM_SCENE: __webpack_require__(229),
|
|
VIDEO_COMPLETE: __webpack_require__(230),
|
|
VIDEO_CREATED: __webpack_require__(231),
|
|
VIDEO_ERROR: __webpack_require__(232),
|
|
VIDEO_LOOP: __webpack_require__(233),
|
|
VIDEO_PLAY: __webpack_require__(234),
|
|
VIDEO_SEEKED: __webpack_require__(235),
|
|
VIDEO_SEEKING: __webpack_require__(236),
|
|
VIDEO_STOP: __webpack_require__(237),
|
|
VIDEO_TIMEOUT: __webpack_require__(238),
|
|
VIDEO_UNLOCKED: __webpack_require__(239)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 55 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Transposes the elements of the given matrix (array of arrays).
|
|
*
|
|
* The transpose of a matrix is a new matrix whose rows are the columns of the original.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.TransposeMatrix
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [array,$return]
|
|
*
|
|
* @param {T[][]} [array] - The array matrix to transpose.
|
|
*
|
|
* @return {T[][]} A new array matrix which is a transposed version of the given array.
|
|
*/
|
|
var TransposeMatrix = function (array)
|
|
{
|
|
var sourceRowCount = array.length;
|
|
var sourceColCount = array[0].length;
|
|
|
|
var result = new Array(sourceColCount);
|
|
|
|
for (var i = 0; i < sourceColCount; i++)
|
|
{
|
|
result[i] = new Array(sourceRowCount);
|
|
|
|
for (var j = sourceRowCount - 1; j > -1; j--)
|
|
{
|
|
result[i][j] = array[j][i];
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
module.exports = TransposeMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 56 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the element at the start of the array to the end, shifting all items in the process.
|
|
* The "rotation" happens to the left.
|
|
*
|
|
* @function Phaser.Utils.Array.RotateLeft
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The array to shift to the left. This array is modified in place.
|
|
* @param {integer} [total=1] - The number of times to shift the array.
|
|
*
|
|
* @return {*} The most recently shifted element.
|
|
*/
|
|
var RotateLeft = function (array, total)
|
|
{
|
|
if (total === undefined) { total = 1; }
|
|
|
|
var element = null;
|
|
|
|
for (var i = 0; i < total; i++)
|
|
{
|
|
element = array.shift();
|
|
array.push(element);
|
|
}
|
|
|
|
return element;
|
|
};
|
|
|
|
module.exports = RotateLeft;
|
|
|
|
|
|
/***/ }),
|
|
/* 57 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the element at the end of the array to the start, shifting all items in the process.
|
|
* The "rotation" happens to the right.
|
|
*
|
|
* @function Phaser.Utils.Array.RotateRight
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The array to shift to the right. This array is modified in place.
|
|
* @param {integer} [total=1] - The number of times to shift the array.
|
|
*
|
|
* @return {*} The most recently shifted element.
|
|
*/
|
|
var RotateRight = function (array, total)
|
|
{
|
|
if (total === undefined) { total = 1; }
|
|
|
|
var element = null;
|
|
|
|
for (var i = 0; i < total; i++)
|
|
{
|
|
element = array.pop();
|
|
array.unshift(element);
|
|
}
|
|
|
|
return element;
|
|
};
|
|
|
|
module.exports = RotateRight;
|
|
|
|
|
|
/***/ }),
|
|
/* 58 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Shuffles the contents of the given array using the Fisher-Yates implementation.
|
|
*
|
|
* The original array is modified directly and returned.
|
|
*
|
|
* @function Phaser.Utils.Array.Shuffle
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[]} - [array,$return]
|
|
*
|
|
* @param {T[]} array - The array to shuffle. This array is modified in place.
|
|
*
|
|
* @return {T[]} The shuffled array.
|
|
*/
|
|
var Shuffle = function (array)
|
|
{
|
|
for (var i = array.length - 1; i > 0; i--)
|
|
{
|
|
var j = Math.floor(Math.random() * (i + 1));
|
|
var temp = array[i];
|
|
array[i] = array[j];
|
|
array[j] = temp;
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = Shuffle;
|
|
|
|
|
|
/***/ }),
|
|
/* 59 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Perimeter = __webpack_require__(60);
|
|
var Point = __webpack_require__(12);
|
|
|
|
/**
|
|
* Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter.
|
|
*
|
|
* The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is.
|
|
*
|
|
* A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.GetPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from.
|
|
* @param {number} position - The normalized distance into the Rectangle's perimeter to return.
|
|
* @param {(Phaser.Geom.Point|object)} [out] - An object to update with the `x` and `y` coordinates of the point.
|
|
*
|
|
* @return {Phaser.Geom.Point} The updated `output` object, or a new Point if no `output` object was given.
|
|
*/
|
|
var GetPoint = function (rectangle, position, out)
|
|
{
|
|
if (out === undefined) { out = new Point(); }
|
|
|
|
if (position <= 0 || position >= 1)
|
|
{
|
|
out.x = rectangle.x;
|
|
out.y = rectangle.y;
|
|
|
|
return out;
|
|
}
|
|
|
|
var p = Perimeter(rectangle) * position;
|
|
|
|
if (position > 0.5)
|
|
{
|
|
p -= (rectangle.width + rectangle.height);
|
|
|
|
if (p <= rectangle.width)
|
|
{
|
|
// Face 3
|
|
out.x = rectangle.right - p;
|
|
out.y = rectangle.bottom;
|
|
}
|
|
else
|
|
{
|
|
// Face 4
|
|
out.x = rectangle.x;
|
|
out.y = rectangle.bottom - (p - rectangle.width);
|
|
}
|
|
}
|
|
else if (p <= rectangle.width)
|
|
{
|
|
// Face 1
|
|
out.x = rectangle.x + p;
|
|
out.y = rectangle.y;
|
|
}
|
|
else
|
|
{
|
|
// Face 2
|
|
out.x = rectangle.right;
|
|
out.y = rectangle.y + (p - rectangle.width);
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = GetPoint;
|
|
|
|
|
|
/***/ }),
|
|
/* 60 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculates the perimeter of a Rectangle.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.Perimeter
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rect - The Rectangle to use.
|
|
*
|
|
* @return {number} The perimeter of the Rectangle, equal to `(width * 2) + (height * 2)`.
|
|
*/
|
|
var Perimeter = function (rect)
|
|
{
|
|
return 2 * (rect.width + rect.height);
|
|
};
|
|
|
|
module.exports = Perimeter;
|
|
|
|
|
|
/***/ }),
|
|
/* 61 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var BuildGameObject = __webpack_require__(62);
|
|
var Class = __webpack_require__(0);
|
|
var GetValue = __webpack_require__(10);
|
|
var ResizeEvent = __webpack_require__(174);
|
|
var ScenePlugin = __webpack_require__(175);
|
|
var Spine = __webpack_require__(199);
|
|
var SpineFile = __webpack_require__(200);
|
|
var SpineGameObject = __webpack_require__(218);
|
|
var SpineContainer = __webpack_require__(251);
|
|
var NOOP = __webpack_require__(1);
|
|
|
|
/**
|
|
* @classdesc
|
|
* The Spine Plugin is a Scene based plugin that handles the creation and rendering of Spine Game Objects.
|
|
*
|
|
* Find more details about Spine itself at http://esotericsoftware.com/.
|
|
*
|
|
* All rendering and object creation is handled via the official Spine Runtimes. This version of the plugin
|
|
* uses the Spine 3.8.95 runtimes. Please note that due to the way the Spine runtimes use semver, you will
|
|
* get breaking changes in point-releases. Therefore, files created in a different version of Spine may not
|
|
* work as a result, without you first updating the runtimes and rebuilding the plugin.
|
|
*
|
|
* Esoteric themselves recommend that you freeze your Spine editor version against the runtime versions.
|
|
* You can find more information about this here: http://esotericsoftware.com/spine-settings#Version
|
|
*
|
|
* Please note that you require a Spine license in order to use Spine Runtimes in your games.
|
|
*
|
|
* You can install this plugin into your Phaser game by either importing it, if you're using ES6:
|
|
*
|
|
* ```javascript
|
|
* import * as SpinePlugin from './SpinePlugin.js';
|
|
* ```
|
|
*
|
|
* and then adding it to your Phaser Game configuration:
|
|
*
|
|
* ```javascript
|
|
* plugins: {
|
|
* scene: [
|
|
* { key: 'SpinePlugin', plugin: window.SpinePlugin, mapping: 'spine' }
|
|
* ]
|
|
* }
|
|
* ```
|
|
*
|
|
* If you're using ES5 then you can load the Spine Plugin in a Scene files payload, _within_ your
|
|
* Game Configuration object, like this:
|
|
*
|
|
* ```javascript
|
|
* scene: {
|
|
* preload: preload,
|
|
* create: create,
|
|
* pack: {
|
|
* files: [
|
|
* { type: 'scenePlugin', key: 'SpinePlugin', url: 'plugins/SpinePlugin.js', sceneKey: 'spine' }
|
|
* ]
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* Loading it like this allows you to then use commands such as `this.load.spine` from within the
|
|
* same Scene. Alternatively, you can use the method `this.load.plugin` to load the plugin via the normal
|
|
* Phaser Loader. However, doing so will not add it to the current Scene. It will be available from any
|
|
* subsequent Scenes.
|
|
*
|
|
* Assuming a default environment you access it from within a Scene by using the `this.spine` reference.
|
|
*
|
|
* When this plugin is installed into a Scene it will add a Loader File Type, allowing you to load
|
|
* Spine files directly, i.e.:
|
|
*
|
|
* ```javascript
|
|
* this.load.spine('stretchyman', 'stretchyman-pro.json', [ 'stretchyman-pma.atlas' ], true);
|
|
* ```
|
|
*
|
|
* It also installs two Game Object Factory methods, allowing you to create Spine Game Objects
|
|
* and Spine Containers:
|
|
*
|
|
* ```javascript
|
|
* const man = this.add.spine(512, 650, 'stretchyman');
|
|
*
|
|
* const container = this.add.spineContainer();
|
|
*
|
|
* container.add(man);
|
|
* ```
|
|
*
|
|
* The first argument is the key which you used when importing the Spine data. There are lots of
|
|
* things you can specify, such as the animation name, skeleton, slot attachments and more. Please
|
|
* see the respective documentation and examples for further details.
|
|
*
|
|
* Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary.
|
|
* The associated atlas files are scanned for any texture files present in them, which are then loaded.
|
|
* If you have exported your Spine data with preMultipliedAlpha set, then you should enable this in the
|
|
* load arguments, or you may see black outlines around skeleton textures.
|
|
*
|
|
* The Spine plugin is local to the Scene in which it is installed. This means a change to something,
|
|
* such as the Skeleton Debug Renderer, in this Scene, will not impact the renderer in any other Scene.
|
|
* The only exception to this is with the caches this plugin creates. Spine atlas and texture data are
|
|
* stored in their own caches, which are global, meaning they're accessible from any Scene in your
|
|
* game, regardless if the Scene loaded the Spine data or not.
|
|
*
|
|
* When destroying a Phaser Game instance, if you need to re-create it again on the same page without
|
|
* reloading, you must remember to remove the Spine Plugin as part of your tear-down process:
|
|
*
|
|
* ```javascript
|
|
* this.plugins.removeScenePlugin('SpinePlugin');
|
|
* ```
|
|
*
|
|
* For details about the Spine Runtime API see http://esotericsoftware.com/spine-api-reference
|
|
*
|
|
* @class SpinePlugin
|
|
* @extends Phaser.Plugins.ScenePlugin
|
|
* @constructor
|
|
* @since 3.19.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
|
|
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Phaser Plugin Manager.
|
|
*/
|
|
var SpinePlugin = new Class({
|
|
|
|
Extends: ScenePlugin,
|
|
|
|
initialize:
|
|
|
|
function SpinePlugin (scene, pluginManager)
|
|
{
|
|
ScenePlugin.call(this, scene, pluginManager);
|
|
|
|
var game = pluginManager.game;
|
|
|
|
/**
|
|
* A read-only flag that indicates if the game is running under WebGL or Canvas.
|
|
*
|
|
* @name SpinePlugin#isWebGL
|
|
* @type {boolean}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
this.isWebGL = (game.config.renderType === 2);
|
|
|
|
/**
|
|
* A custom cache that stores the Spine atlas data.
|
|
*
|
|
* This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
|
|
* no matter which Scene you are in.
|
|
*
|
|
* @name SpinePlugin#cache
|
|
* @type {Phaser.Cache.BaseCache}
|
|
* @since 3.19.0
|
|
*/
|
|
this.cache = game.cache.addCustom('spine');
|
|
|
|
/**
|
|
* A custom cache that stores the Spine Textures.
|
|
*
|
|
* This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
|
|
* no matter which Scene you are in.
|
|
*
|
|
* @name SpinePlugin#spineTextures
|
|
* @type {Phaser.Cache.BaseCache}
|
|
* @since 3.19.0
|
|
*/
|
|
this.spineTextures = game.cache.addCustom('spineTextures');
|
|
|
|
/**
|
|
* A reference to the global JSON Cache.
|
|
*
|
|
* @name SpinePlugin#json
|
|
* @type {Phaser.Cache.BaseCache}
|
|
* @since 3.19.0
|
|
*/
|
|
this.json = game.cache.json;
|
|
|
|
/**
|
|
* A reference to the global Texture Manager.
|
|
*
|
|
* @name SpinePlugin#textures
|
|
* @type {Phaser.Textures.TextureManager}
|
|
* @since 3.19.0
|
|
*/
|
|
this.textures = game.textures;
|
|
|
|
/**
|
|
* A flag that sets if the Skeleton Renderers will render debug information over the top
|
|
* of the skeleton or not.
|
|
*
|
|
* @name SpinePlugin#drawDebug
|
|
* @type {boolean}
|
|
* @since 3.19.0
|
|
*/
|
|
this.drawDebug = false;
|
|
|
|
/**
|
|
* The underlying WebGL context of the Phaser renderer.
|
|
*
|
|
* Only set if running in WebGL mode.
|
|
*
|
|
* @name SpinePlugin#gl
|
|
* @type {WebGLRenderingContext}
|
|
* @since 3.19.0
|
|
*/
|
|
this.gl;
|
|
|
|
/**
|
|
* A reference to either the Canvas or WebGL Renderer that this Game is using.
|
|
*
|
|
* @name SpinePlugin#renderer
|
|
* @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)}
|
|
* @since 3.19.0
|
|
*/
|
|
this.renderer;
|
|
|
|
/**
|
|
* An instance of the Spine WebGL Scene Renderer.
|
|
*
|
|
* Only set if running in WebGL mode.
|
|
*
|
|
* @name SpinePlugin#sceneRenderer
|
|
* @type {spine.webgl.SceneRenderer}
|
|
* @since 3.19.0
|
|
*/
|
|
this.sceneRenderer;
|
|
|
|
/**
|
|
* An instance of the Spine Skeleton Renderer.
|
|
*
|
|
* @name SpinePlugin#skeletonRenderer
|
|
* @type {(spine.canvas.SkeletonRenderer|spine.webgl.SkeletonRenderer)}
|
|
* @since 3.19.0
|
|
*/
|
|
this.skeletonRenderer;
|
|
|
|
/**
|
|
* An instance of the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only set if running in WebGL mode.
|
|
*
|
|
* @name SpinePlugin#skeletonDebugRenderer
|
|
* @type {spine.webgl.skeletonDebugRenderer}
|
|
* @since 3.19.0
|
|
*/
|
|
this.skeletonDebugRenderer;
|
|
|
|
/**
|
|
* A reference to the Spine runtime.
|
|
* This is the runtime created by Esoteric Software
|
|
*
|
|
* @name SpinePlugin#plugin
|
|
* @type {spine}
|
|
* @since 3.19.0
|
|
*/
|
|
this.plugin = Spine;
|
|
|
|
/**
|
|
* An internal vector3 used by the screen to world method.
|
|
*
|
|
* @name SpinePlugin#temp1
|
|
* @private
|
|
* @type {spine.webgl.Vector3}
|
|
* @since 3.19.0
|
|
*/
|
|
this.temp1;
|
|
|
|
/**
|
|
* An internal vector3 used by the screen to world method.
|
|
*
|
|
* @name SpinePlugin#temp2
|
|
* @private
|
|
* @type {spine.webgl.Vector3}
|
|
* @since 3.19.0
|
|
*/
|
|
this.temp2;
|
|
|
|
if (this.isWebGL)
|
|
{
|
|
this.runtime = Spine.webgl;
|
|
|
|
this.renderer = game.renderer;
|
|
this.gl = game.renderer.gl;
|
|
|
|
this.getAtlas = this.getAtlasWebGL;
|
|
}
|
|
else
|
|
{
|
|
this.runtime = Spine.canvas;
|
|
|
|
this.renderer = game.renderer;
|
|
|
|
this.getAtlas = this.getAtlasCanvas;
|
|
}
|
|
|
|
// Headless mode?
|
|
if (!this.renderer)
|
|
{
|
|
this.renderer = {
|
|
width: game.scale.width,
|
|
height: game.scale.height,
|
|
preRender: NOOP,
|
|
postRender: NOOP,
|
|
render: NOOP,
|
|
destroy: NOOP
|
|
};
|
|
}
|
|
|
|
var _this = this;
|
|
|
|
var add = function (x, y, key, animationName, loop)
|
|
{
|
|
var spineGO = new SpineGameObject(this.scene, _this, x, y, key, animationName, loop);
|
|
|
|
this.displayList.add(spineGO);
|
|
this.updateList.add(spineGO);
|
|
|
|
return spineGO;
|
|
};
|
|
|
|
var make = function (config, addToScene)
|
|
{
|
|
if (config === undefined) { config = {}; }
|
|
|
|
var key = GetValue(config, 'key', null);
|
|
var animationName = GetValue(config, 'animationName', null);
|
|
var loop = GetValue(config, 'loop', false);
|
|
|
|
var spineGO = new SpineGameObject(this.scene, _this, 0, 0, key, animationName, loop);
|
|
|
|
if (addToScene !== undefined)
|
|
{
|
|
config.add = addToScene;
|
|
}
|
|
|
|
BuildGameObject(this.scene, spineGO, config);
|
|
|
|
// Spine specific
|
|
var skinName = GetValue(config, 'skinName', false);
|
|
|
|
if (skinName)
|
|
{
|
|
spineGO.setSkinByName(skinName);
|
|
}
|
|
|
|
var slotName = GetValue(config, 'slotName', false);
|
|
var attachmentName = GetValue(config, 'attachmentName', null);
|
|
|
|
if (slotName)
|
|
{
|
|
spineGO.setAttachment(slotName, attachmentName);
|
|
}
|
|
|
|
return spineGO.refresh();
|
|
};
|
|
|
|
var addContainer = function (x, y, children)
|
|
{
|
|
var spineGO = new SpineContainer(this.scene, _this, x, y, children);
|
|
|
|
this.displayList.add(spineGO);
|
|
|
|
return spineGO;
|
|
};
|
|
|
|
var makeContainer = function (config, addToScene)
|
|
{
|
|
if (config === undefined) { config = {}; }
|
|
|
|
var x = GetValue(config, 'x', 0);
|
|
var y = GetValue(config, 'y', 0);
|
|
var children = GetValue(config, 'children', null);
|
|
|
|
var container = new SpineContainer(this.scene, _this, x, y, children);
|
|
|
|
if (addToScene !== undefined)
|
|
{
|
|
config.add = addToScene;
|
|
}
|
|
|
|
BuildGameObject(this.scene, container, config);
|
|
|
|
return container;
|
|
};
|
|
|
|
pluginManager.registerFileType('spine', this.spineFileCallback, scene);
|
|
pluginManager.registerGameObject('spine', add, make);
|
|
pluginManager.registerGameObject('spineContainer', addContainer, makeContainer);
|
|
},
|
|
|
|
/**
|
|
* Internal boot handler.
|
|
*
|
|
* @method SpinePlugin#boot
|
|
* @private
|
|
* @since 3.19.0
|
|
*/
|
|
boot: function ()
|
|
{
|
|
if (this.isWebGL)
|
|
{
|
|
this.bootWebGL();
|
|
this.onResize();
|
|
this.game.scale.on(ResizeEvent, this.onResize, this);
|
|
}
|
|
else
|
|
{
|
|
this.bootCanvas();
|
|
}
|
|
|
|
var eventEmitter = this.systems.events;
|
|
|
|
eventEmitter.once('shutdown', this.shutdown, this);
|
|
eventEmitter.once('destroy', this.destroy, this);
|
|
|
|
this.game.events.once('destroy', this.gameDestroy, this);
|
|
},
|
|
|
|
/**
|
|
* Internal boot handler for the Canvas Renderer.
|
|
*
|
|
* @method SpinePlugin#bootCanvas
|
|
* @private
|
|
* @since 3.19.0
|
|
*/
|
|
bootCanvas: function ()
|
|
{
|
|
this.skeletonRenderer = new Spine.canvas.SkeletonRenderer(this.scene.sys.context);
|
|
},
|
|
|
|
/**
|
|
* Internal boot handler for the WebGL Renderer.
|
|
*
|
|
* @method SpinePlugin#bootWebGL
|
|
* @private
|
|
* @since 3.19.0
|
|
*/
|
|
bootWebGL: function ()
|
|
{
|
|
this.sceneRenderer = new Spine.webgl.SceneRenderer(this.renderer.canvas, this.gl, true);
|
|
|
|
// Monkeypatch the Spine setBlendMode functions, or batching is destroyed!
|
|
|
|
var setBlendMode = function (srcBlend, dstBlend)
|
|
{
|
|
if (srcBlend !== this.srcBlend || dstBlend !== this.dstBlend)
|
|
{
|
|
var gl = this.context.gl;
|
|
|
|
this.srcBlend = srcBlend;
|
|
this.dstBlend = dstBlend;
|
|
|
|
if (this.isDrawing)
|
|
{
|
|
this.flush();
|
|
gl.blendFunc(this.srcBlend, this.dstBlend);
|
|
}
|
|
}
|
|
};
|
|
|
|
this.sceneRenderer.batcher.setBlendMode = setBlendMode;
|
|
this.sceneRenderer.shapes.setBlendMode = setBlendMode;
|
|
|
|
this.skeletonRenderer = this.sceneRenderer.skeletonRenderer;
|
|
this.skeletonDebugRenderer = this.sceneRenderer.skeletonDebugRenderer;
|
|
|
|
this.temp1 = new Spine.webgl.Vector3(0, 0, 0);
|
|
this.temp2 = new Spine.webgl.Vector3(0, 0, 0);
|
|
},
|
|
|
|
/**
|
|
* Gets a loaded Spine Atlas from the cache and creates a new Spine Texture Atlas,
|
|
* then returns it. You do not normally need to invoke this method directly.
|
|
*
|
|
* @method SpinePlugin#getAtlasCanvas
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} key - The key of the Spine Atlas to create.
|
|
*
|
|
* @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
|
|
*/
|
|
getAtlasCanvas: function (key)
|
|
{
|
|
var atlasEntry = this.cache.get(key);
|
|
|
|
if (!atlasEntry)
|
|
{
|
|
console.warn('No atlas data for: ' + key);
|
|
return;
|
|
}
|
|
|
|
var atlas;
|
|
var spineTextures = this.spineTextures;
|
|
|
|
if (spineTextures.has(key))
|
|
{
|
|
atlas = spineTextures.get(key);
|
|
}
|
|
else
|
|
{
|
|
var textures = this.textures;
|
|
|
|
atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
|
|
{
|
|
return new Spine.canvas.CanvasTexture(textures.get(atlasEntry.prefix + path).getSourceImage());
|
|
});
|
|
}
|
|
|
|
return atlas;
|
|
},
|
|
|
|
/**
|
|
* Gets a loaded Spine Atlas from the cache and creates a new Spine Texture Atlas,
|
|
* then returns it. You do not normally need to invoke this method directly.
|
|
*
|
|
* @method SpinePlugin#getAtlasWebGL
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} key - The key of the Spine Atlas to create.
|
|
*
|
|
* @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
|
|
*/
|
|
getAtlasWebGL: function (key)
|
|
{
|
|
var atlasEntry = this.cache.get(key);
|
|
|
|
if (!atlasEntry)
|
|
{
|
|
console.warn('No atlas data for: ' + key);
|
|
return;
|
|
}
|
|
|
|
var atlas;
|
|
var spineTextures = this.spineTextures;
|
|
|
|
if (spineTextures.has(key))
|
|
{
|
|
atlas = spineTextures.get(key);
|
|
}
|
|
else
|
|
{
|
|
var textures = this.textures;
|
|
|
|
var gl = this.sceneRenderer.context.gl;
|
|
|
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
|
|
atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
|
|
{
|
|
return new Spine.webgl.GLTexture(gl, textures.get(atlasEntry.prefix + path).getSourceImage(), false);
|
|
});
|
|
}
|
|
|
|
return atlas;
|
|
},
|
|
|
|
/**
|
|
* Adds a Spine Skeleton and Atlas file, or array of files, to the current load queue.
|
|
*
|
|
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
|
|
*
|
|
* ```javascript
|
|
* function preload ()
|
|
* {
|
|
* this.load.spine('spineBoy', 'boy.json', 'boy.atlas', true);
|
|
* }
|
|
* ```
|
|
*
|
|
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
|
|
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
|
|
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
|
|
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
|
|
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
|
|
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
|
|
* loaded.
|
|
*
|
|
* If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring
|
|
* its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details.
|
|
*
|
|
* Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary. The associated
|
|
* atlas files are scanned for any texture files present in them, which are then loaded. If you have exported
|
|
* your Spine data with preMultipliedAlpha set, then you should enable this in the arguments, or you may see black
|
|
* outlines around skeleton textures.
|
|
*
|
|
* The key must be a unique String. It is used to add the file to the global Spine cache upon a successful load.
|
|
* The key should be unique both in terms of files being loaded and files already present in the Spine cache.
|
|
* Loading a file using a key that is already taken will result in a warning.
|
|
*
|
|
* Instead of passing arguments you can pass a configuration object, such as:
|
|
*
|
|
* ```javascript
|
|
* this.load.spine({
|
|
* key: 'mainmenu',
|
|
* jsonURL: 'boy.json',
|
|
* atlasURL: 'boy.atlas',
|
|
* preMultipliedAlpha: true
|
|
* });
|
|
* ```
|
|
*
|
|
* If you need to load multiple Spine atlas files, provide them as an array:
|
|
*
|
|
* ```javascript
|
|
* function preload ()
|
|
* {
|
|
* this.load.spine('demos', 'demos.json', [ 'atlas1.atlas', 'atlas2.atlas' ], true);
|
|
* }
|
|
* ```
|
|
*
|
|
* See the documentation for `Phaser.Types.Loader.FileTypes.SpineFileConfig` for more details.
|
|
*
|
|
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
|
|
* key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
|
|
* this is what you would use to retrieve the data from the Spine plugin.
|
|
*
|
|
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
|
|
*
|
|
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
|
|
* and no URL is given then the Loader will set the URL to be "alien.json". It will always add `.json` as the extension, although
|
|
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
|
|
*
|
|
* Note: The ability to load this type of file will only be available if the Spine Plugin has been built or loaded into Phaser.
|
|
*
|
|
* @method Phaser.Loader.LoaderPlugin#spine
|
|
* @fires Phaser.Loader.LoaderPlugin#ADD
|
|
* @since 3.19.0
|
|
*
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
|
|
* @param {string} jsonURL - The absolute or relative URL to load the Spine json file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
|
|
* @param {string|string[]} atlasURL - The absolute or relative URL to load the Spine atlas file from. If undefined or `null` it will be set to `<key>.atlas`, i.e. if `key` was "alien" then the URL will be "alien.atlas".
|
|
* @param {boolean} [preMultipliedAlpha=false] - Do the texture files include pre-multiplied alpha or not?
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the Spine json file. Used in replacement of the Loaders default XHR Settings.
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the Spine atlas file. Used in replacement of the Loaders default XHR Settings.
|
|
*
|
|
* @return {Phaser.Loader.LoaderPlugin} The Loader instance.
|
|
*/
|
|
spineFileCallback: function (key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings)
|
|
{
|
|
var multifile;
|
|
|
|
if (Array.isArray(key))
|
|
{
|
|
for (var i = 0; i < key.length; i++)
|
|
{
|
|
multifile = new SpineFile(this, key[i]);
|
|
|
|
this.addFile(multifile.files);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
multifile = new SpineFile(this, key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings);
|
|
|
|
this.addFile(multifile.files);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Converts the given x and y screen coordinates into the world space of the given Skeleton.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#worldToLocal
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} x - The screen space x coordinate to convert.
|
|
* @param {number} y - The screen space y coordinate to convert.
|
|
* @param {spine.Skeleton} skeleton - The Spine Skeleton to convert into.
|
|
* @param {spine.Bone} [bone] - Optional bone of the Skeleton to convert into.
|
|
*
|
|
* @return {spine.Vector2} A Vector2 containing the translated point.
|
|
*/
|
|
worldToLocal: function (x, y, skeleton, bone)
|
|
{
|
|
var temp1 = this.temp1;
|
|
var temp2 = this.temp2;
|
|
var camera = this.sceneRenderer.camera;
|
|
|
|
temp1.set(x + skeleton.x, y - skeleton.y, 0);
|
|
|
|
var width = camera.viewportWidth;
|
|
var height = camera.viewportHeight;
|
|
|
|
camera.screenToWorld(temp1, width, height);
|
|
|
|
if (bone && bone.parent !== null)
|
|
{
|
|
bone.parent.worldToLocal(temp2.set(temp1.x - skeleton.x, temp1.y - skeleton.y, 0));
|
|
|
|
return new Spine.Vector2(temp2.x, temp2.y);
|
|
}
|
|
else if (bone)
|
|
{
|
|
return new Spine.Vector2(temp1.x - skeleton.x, temp1.y - skeleton.y);
|
|
}
|
|
else
|
|
{
|
|
return new Spine.Vector2(temp1.x, temp1.y);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Returns a Spine Vector2 based on the given x and y values.
|
|
*
|
|
* @method SpinePlugin#getVector2
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} x - The Vector x value.
|
|
* @param {number} y - The Vector y value.
|
|
*
|
|
* @return {spine.Vector2} A Spine Vector2 based on the given values.
|
|
*/
|
|
getVector2: function (x, y)
|
|
{
|
|
return new Spine.Vector2(x, y);
|
|
},
|
|
|
|
/**
|
|
* Returns a Spine Vector2 based on the given x, y and z values.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#getVector3
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} x - The Vector x value.
|
|
* @param {number} y - The Vector y value.
|
|
* @param {number} z - The Vector z value.
|
|
*
|
|
* @return {spine.Vector2} A Spine Vector2 based on the given values.
|
|
*/
|
|
getVector3: function (x, y, z)
|
|
{
|
|
return new Spine.webgl.Vector3(x, y, z);
|
|
},
|
|
|
|
/**
|
|
* Sets `drawBones` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugBones
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugBones: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawBones = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawRegionAttachments` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugRegionAttachments
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugRegionAttachments: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawRegionAttachments = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawBoundingBoxes` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugBoundingBoxes
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugBoundingBoxes: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawBoundingBoxes = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawMeshHull` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugMeshHull
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugMeshHull: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawMeshHull = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawMeshTriangles` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugMeshTriangles
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugMeshTriangles: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawMeshTriangles = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawPaths` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugPaths
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugPaths: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawPaths = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawSkeletonXY` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugSkeletonXY
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugSkeletonXY: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawSkeletonXY = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets `drawClipping` in the Spine Skeleton Debug Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setDebugClipping
|
|
* @since 3.19.0
|
|
*
|
|
* @param {boolean} [value=true] - The value to set in the debug property.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setDebugClipping: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.skeletonDebugRenderer.drawClipping = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the given vertex effect on the Spine Skeleton Renderer.
|
|
*
|
|
* Only works in WebGL.
|
|
*
|
|
* @method SpinePlugin#setEffect
|
|
* @since 3.19.0
|
|
*
|
|
* @param {spine.VertexEffect} [effect] - The vertex effect to set on the Skeleton Renderer.
|
|
*
|
|
* @return {this} This Spine Plugin.
|
|
*/
|
|
setEffect: function (effect)
|
|
{
|
|
this.sceneRenderer.skeletonRenderer.vertexEffect = effect;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Creates a Spine Skeleton based on the given key and optional Skeleton JSON data.
|
|
*
|
|
* The Skeleton data should have already been loaded before calling this method.
|
|
*
|
|
* @method SpinePlugin#createSkeleton
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} key - The key of the Spine skeleton data, as loaded by the plugin. If the Spine JSON contains multiple skeletons, reference them with a period, i.e. `set.spineBoy`.
|
|
* @param {object} [skeletonJSON] - Optional Skeleton JSON data to use, instead of getting it from the cache.
|
|
*
|
|
* @return {(any|null)} This Spine Skeleton data object, or `null` if the key was invalid.
|
|
*/
|
|
createSkeleton: function (key, skeletonJSON)
|
|
{
|
|
var atlasKey = key;
|
|
var jsonKey = key;
|
|
var split = (key.indexOf('.') !== -1);
|
|
|
|
if (split)
|
|
{
|
|
var parts = key.split('.');
|
|
|
|
atlasKey = parts.shift();
|
|
jsonKey = parts.join('.');
|
|
}
|
|
|
|
var atlasData = this.cache.get(atlasKey);
|
|
var atlas = this.getAtlas(atlasKey);
|
|
|
|
if (!atlas)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (!this.spineTextures.has(atlasKey))
|
|
{
|
|
this.spineTextures.add(atlasKey, atlas);
|
|
}
|
|
|
|
var preMultipliedAlpha = atlasData.preMultipliedAlpha;
|
|
|
|
var atlasLoader = new Spine.AtlasAttachmentLoader(atlas);
|
|
|
|
var skeletonJson = new Spine.SkeletonJson(atlasLoader);
|
|
|
|
var data;
|
|
|
|
if (skeletonJSON)
|
|
{
|
|
data = skeletonJSON;
|
|
}
|
|
else
|
|
{
|
|
var json = this.json.get(atlasKey);
|
|
|
|
data = (split) ? GetValue(json, jsonKey) : json;
|
|
}
|
|
|
|
if (data)
|
|
{
|
|
var skeletonData = skeletonJson.readSkeletonData(data);
|
|
|
|
var skeleton = new Spine.Skeleton(skeletonData);
|
|
|
|
return { skeletonData: skeletonData, skeleton: skeleton, preMultipliedAlpha: preMultipliedAlpha };
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Creates a new Animation State and Animation State Data for the given skeleton.
|
|
*
|
|
* The returned object contains two properties: `state` and `stateData` respectively.
|
|
*
|
|
* @method SpinePlugin#createAnimationState
|
|
* @since 3.19.0
|
|
*
|
|
* @param {spine.Skeleton} skeleton - The Skeleton to create the Animation State for.
|
|
*
|
|
* @return {any} An object containing the Animation State and Animation State Data instances.
|
|
*/
|
|
createAnimationState: function (skeleton)
|
|
{
|
|
var stateData = new Spine.AnimationStateData(skeleton.data);
|
|
|
|
var state = new Spine.AnimationState(stateData);
|
|
|
|
return { stateData: stateData, state: state };
|
|
},
|
|
|
|
/**
|
|
* Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
|
|
*
|
|
* The returned object contains two properties: `offset` and `size`:
|
|
*
|
|
* `offset` - The distance from the skeleton origin to the bottom left corner of the AABB.
|
|
* `size` - The width and height of the AABB.
|
|
*
|
|
* @method SpinePlugin#getBounds
|
|
* @since 3.19.0
|
|
*
|
|
* @param {spine.Skeleton} skeleton - The Skeleton to get the bounds from.
|
|
*
|
|
* @return {any} The bounds object.
|
|
*/
|
|
getBounds: function (skeleton)
|
|
{
|
|
var offset = new Spine.Vector2();
|
|
var size = new Spine.Vector2();
|
|
|
|
skeleton.getBounds(offset, size, []);
|
|
|
|
return { offset: offset, size: size };
|
|
},
|
|
|
|
/**
|
|
* Internal handler for when the renderer resizes.
|
|
*
|
|
* Only called if running in WebGL.
|
|
*
|
|
* @method SpinePlugin#onResize
|
|
* @since 3.19.0
|
|
*/
|
|
onResize: function ()
|
|
{
|
|
var renderer = this.renderer;
|
|
var sceneRenderer = this.sceneRenderer;
|
|
|
|
var viewportWidth = renderer.width;
|
|
var viewportHeight = renderer.height;
|
|
|
|
sceneRenderer.camera.position.x = viewportWidth / 2;
|
|
sceneRenderer.camera.position.y = viewportHeight / 2;
|
|
|
|
sceneRenderer.camera.viewportWidth = viewportWidth;
|
|
sceneRenderer.camera.viewportHeight = viewportHeight;
|
|
},
|
|
|
|
/**
|
|
* The Scene that owns this plugin is shutting down.
|
|
*
|
|
* We need to kill and reset all internal properties as well as stop listening to Scene events.
|
|
*
|
|
* @method SpinePlugin#shutdown
|
|
* @private
|
|
* @since 3.19.0
|
|
*/
|
|
shutdown: function ()
|
|
{
|
|
var eventEmitter = this.systems.events;
|
|
|
|
eventEmitter.off('shutdown', this.shutdown, this);
|
|
|
|
if (this.isWebGL)
|
|
{
|
|
this.game.scale.off(ResizeEvent, this.onResize, this);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* The Scene that owns this plugin is being destroyed.
|
|
*
|
|
* We need to shutdown and then kill off all external references.
|
|
*
|
|
* @method SpinePlugin#destroy
|
|
* @private
|
|
* @since 3.19.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.shutdown();
|
|
|
|
this.game = null;
|
|
this.scene = null;
|
|
this.systems = null;
|
|
|
|
this.cache = null;
|
|
this.spineTextures = null;
|
|
this.json = null;
|
|
this.textures = null;
|
|
this.skeletonRenderer = null;
|
|
this.gl = null;
|
|
},
|
|
|
|
/**
|
|
* The Game that owns this plugin is being destroyed.
|
|
*
|
|
* Dispose of the Scene Renderer and remove the Game Objects.
|
|
*
|
|
* @method SpinePlugin#gameDestroy
|
|
* @private
|
|
* @since 3.50.0
|
|
*/
|
|
gameDestroy: function ()
|
|
{
|
|
this.destroy();
|
|
|
|
if (this.sceneRenderer)
|
|
{
|
|
this.sceneRenderer.dispose();
|
|
}
|
|
|
|
this.sceneRenderer = null;
|
|
this.pluginManager = null;
|
|
|
|
this.pluginManager.removeGameObject('spine', true, true);
|
|
this.pluginManager.removeGameObject('spineContainer', true, true);
|
|
}
|
|
|
|
});
|
|
|
|
SpinePlugin.SpineGameObject = SpineGameObject;
|
|
SpinePlugin.SpineContainer = SpineContainer;
|
|
|
|
/**
|
|
* Creates a new Spine Game Object and adds it to the Scene.
|
|
*
|
|
* The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
|
|
* skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
|
|
* do not have a Phaser origin.
|
|
*
|
|
* If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
|
|
* character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
|
|
* multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
|
|
* that.
|
|
*
|
|
* ```javascript
|
|
* let jelly = this.add.spine(512, 550, 'jelly', 'jelly-think', true);
|
|
* ```
|
|
*
|
|
* The key is optional. If not passed here, you need to call `SpineGameObject.setSkeleton()` to use it.
|
|
*
|
|
* The animation name is also optional and can be set later via `SpineGameObject.setAnimation`.
|
|
*
|
|
* Should you wish for more control over the object creation, such as setting a slot attachment or skin
|
|
* name, then use `SpinePlugin.make` instead.
|
|
*
|
|
* @method SpinePlugin#add
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} x - The horizontal position of this Game Object in the world.
|
|
* @param {number} y - The vertical position of this Game Object in the world.
|
|
* @param {string} [key] - The key of the Spine Skeleton this Game Object will use, as stored in the Spine Plugin.
|
|
* @param {string} [animationName] - The name of the animation to set on this Skeleton.
|
|
* @param {boolean} [loop=false] - Should the animation playback be looped or not?
|
|
*
|
|
* @return {SpineGameObject} The Game Object that was created.
|
|
*/
|
|
|
|
/**
|
|
* Creates a new Spine Game Object from the given configuration file and optionally adds it to the Scene.
|
|
*
|
|
* The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
|
|
* skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
|
|
* do not have a Phaser origin.
|
|
*
|
|
* If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
|
|
* character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
|
|
* multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
|
|
* that.
|
|
*
|
|
* ```javascript
|
|
* let jelly = this.make.spine({
|
|
* x: 500, y: 500, key: 'jelly',
|
|
* scale: 1.5,
|
|
* skinName: 'square_Green',
|
|
* animationName: 'jelly-idle', loop: true,
|
|
* slotName: 'hat', attachmentName: 'images/La_14'
|
|
* });
|
|
* ```
|
|
*
|
|
* @method SpinePlugin#make
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} config - The configuration object this Game Object will use to create itself.
|
|
* @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object.
|
|
*
|
|
* @return {SpineGameObject} The Game Object that was created.
|
|
*/
|
|
|
|
module.exports = SpinePlugin;
|
|
|
|
|
|
/***/ }),
|
|
/* 62 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var BlendModes = __webpack_require__(17);
|
|
var GetAdvancedValue = __webpack_require__(63);
|
|
|
|
/**
|
|
* Builds a Game Object using the provided configuration object.
|
|
*
|
|
* @function Phaser.GameObjects.BuildGameObject
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene.
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The initial GameObject.
|
|
* @param {Phaser.Types.GameObjects.GameObjectConfig} config - The config to build the GameObject with.
|
|
*
|
|
* @return {Phaser.GameObjects.GameObject} The built Game Object.
|
|
*/
|
|
var BuildGameObject = function (scene, gameObject, config)
|
|
{
|
|
// Position
|
|
|
|
gameObject.x = GetAdvancedValue(config, 'x', 0);
|
|
gameObject.y = GetAdvancedValue(config, 'y', 0);
|
|
gameObject.depth = GetAdvancedValue(config, 'depth', 0);
|
|
|
|
// Flip
|
|
|
|
gameObject.flipX = GetAdvancedValue(config, 'flipX', false);
|
|
gameObject.flipY = GetAdvancedValue(config, 'flipY', false);
|
|
|
|
// Scale
|
|
// Either: { scale: 2 } or { scale: { x: 2, y: 2 }}
|
|
|
|
var scale = GetAdvancedValue(config, 'scale', null);
|
|
|
|
if (typeof scale === 'number')
|
|
{
|
|
gameObject.setScale(scale);
|
|
}
|
|
else if (scale !== null)
|
|
{
|
|
gameObject.scaleX = GetAdvancedValue(scale, 'x', 1);
|
|
gameObject.scaleY = GetAdvancedValue(scale, 'y', 1);
|
|
}
|
|
|
|
// ScrollFactor
|
|
// Either: { scrollFactor: 2 } or { scrollFactor: { x: 2, y: 2 }}
|
|
|
|
var scrollFactor = GetAdvancedValue(config, 'scrollFactor', null);
|
|
|
|
if (typeof scrollFactor === 'number')
|
|
{
|
|
gameObject.setScrollFactor(scrollFactor);
|
|
}
|
|
else if (scrollFactor !== null)
|
|
{
|
|
gameObject.scrollFactorX = GetAdvancedValue(scrollFactor, 'x', 1);
|
|
gameObject.scrollFactorY = GetAdvancedValue(scrollFactor, 'y', 1);
|
|
}
|
|
|
|
// Rotation
|
|
|
|
gameObject.rotation = GetAdvancedValue(config, 'rotation', 0);
|
|
|
|
var angle = GetAdvancedValue(config, 'angle', null);
|
|
|
|
if (angle !== null)
|
|
{
|
|
gameObject.angle = angle;
|
|
}
|
|
|
|
// Alpha
|
|
|
|
gameObject.alpha = GetAdvancedValue(config, 'alpha', 1);
|
|
|
|
// Origin
|
|
// Either: { origin: 0.5 } or { origin: { x: 0.5, y: 0.5 }}
|
|
|
|
var origin = GetAdvancedValue(config, 'origin', null);
|
|
|
|
if (typeof origin === 'number')
|
|
{
|
|
gameObject.setOrigin(origin);
|
|
}
|
|
else if (origin !== null)
|
|
{
|
|
var ox = GetAdvancedValue(origin, 'x', 0.5);
|
|
var oy = GetAdvancedValue(origin, 'y', 0.5);
|
|
|
|
gameObject.setOrigin(ox, oy);
|
|
}
|
|
|
|
// BlendMode
|
|
|
|
gameObject.blendMode = GetAdvancedValue(config, 'blendMode', BlendModes.NORMAL);
|
|
|
|
// Visible
|
|
|
|
gameObject.visible = GetAdvancedValue(config, 'visible', true);
|
|
|
|
// Add to Scene
|
|
|
|
var add = GetAdvancedValue(config, 'add', true);
|
|
|
|
if (add)
|
|
{
|
|
scene.sys.displayList.add(gameObject);
|
|
}
|
|
|
|
if (gameObject.preUpdate)
|
|
{
|
|
scene.sys.updateList.add(gameObject);
|
|
}
|
|
|
|
return gameObject;
|
|
};
|
|
|
|
module.exports = BuildGameObject;
|
|
|
|
|
|
/***/ }),
|
|
/* 63 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MATH = __webpack_require__(64);
|
|
var GetValue = __webpack_require__(10);
|
|
|
|
/**
|
|
* Retrieves a value from an object. Allows for more advanced selection options, including:
|
|
*
|
|
* Allowed types:
|
|
*
|
|
* Implicit
|
|
* {
|
|
* x: 4
|
|
* }
|
|
*
|
|
* From function
|
|
* {
|
|
* x: function ()
|
|
* }
|
|
*
|
|
* Randomly pick one element from the array
|
|
* {
|
|
* x: [a, b, c, d, e, f]
|
|
* }
|
|
*
|
|
* Random integer between min and max:
|
|
* {
|
|
* x: { randInt: [min, max] }
|
|
* }
|
|
*
|
|
* Random float between min and max:
|
|
* {
|
|
* x: { randFloat: [min, max] }
|
|
* }
|
|
*
|
|
*
|
|
* @function Phaser.Utils.Objects.GetAdvancedValue
|
|
* @since 3.0.0
|
|
*
|
|
* @param {object} source - The object to retrieve the value from.
|
|
* @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
|
|
* @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
|
|
*
|
|
* @return {*} The value of the requested key.
|
|
*/
|
|
var GetAdvancedValue = function (source, key, defaultValue)
|
|
{
|
|
var value = GetValue(source, key, null);
|
|
|
|
if (value === null)
|
|
{
|
|
return defaultValue;
|
|
}
|
|
else if (Array.isArray(value))
|
|
{
|
|
return MATH.RND.pick(value);
|
|
}
|
|
else if (typeof value === 'object')
|
|
{
|
|
if (value.hasOwnProperty('randInt'))
|
|
{
|
|
return MATH.RND.integerInRange(value.randInt[0], value.randInt[1]);
|
|
}
|
|
else if (value.hasOwnProperty('randFloat'))
|
|
{
|
|
return MATH.RND.realInRange(value.randFloat[0], value.randFloat[1]);
|
|
}
|
|
}
|
|
else if (typeof value === 'function')
|
|
{
|
|
return value(key);
|
|
}
|
|
|
|
return value;
|
|
};
|
|
|
|
module.exports = GetAdvancedValue;
|
|
|
|
|
|
/***/ }),
|
|
/* 64 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CONST = __webpack_require__(3);
|
|
var Extend = __webpack_require__(27);
|
|
|
|
/**
|
|
* @namespace Phaser.Math
|
|
*/
|
|
|
|
var PhaserMath = {
|
|
|
|
// Collections of functions
|
|
Angle: __webpack_require__(65),
|
|
Distance: __webpack_require__(74),
|
|
Easing: __webpack_require__(82),
|
|
Fuzzy: __webpack_require__(127),
|
|
Interpolation: __webpack_require__(132),
|
|
Pow2: __webpack_require__(140),
|
|
Snap: __webpack_require__(144),
|
|
|
|
// Expose the RNG Class
|
|
RandomDataGenerator: __webpack_require__(148),
|
|
|
|
// Single functions
|
|
Average: __webpack_require__(149),
|
|
Bernstein: __webpack_require__(33),
|
|
Between: __webpack_require__(150),
|
|
CatmullRom: __webpack_require__(35),
|
|
CeilTo: __webpack_require__(151),
|
|
Clamp: __webpack_require__(4),
|
|
DegToRad: __webpack_require__(19),
|
|
Difference: __webpack_require__(152),
|
|
Euler: __webpack_require__(153),
|
|
Factorial: __webpack_require__(34),
|
|
FloatBetween: __webpack_require__(18),
|
|
FloorTo: __webpack_require__(154),
|
|
FromPercent: __webpack_require__(155),
|
|
GetSpeed: __webpack_require__(156),
|
|
IsEven: __webpack_require__(157),
|
|
IsEvenStrict: __webpack_require__(158),
|
|
Linear: __webpack_require__(36),
|
|
MaxAdd: __webpack_require__(159),
|
|
MinSub: __webpack_require__(160),
|
|
Percent: __webpack_require__(161),
|
|
RadToDeg: __webpack_require__(9),
|
|
RandomXY: __webpack_require__(162),
|
|
RandomXYZ: __webpack_require__(163),
|
|
RandomXYZW: __webpack_require__(164),
|
|
Rotate: __webpack_require__(165),
|
|
RotateAround: __webpack_require__(39),
|
|
RotateAroundDistance: __webpack_require__(166),
|
|
RotateTo: __webpack_require__(167),
|
|
RoundAwayFromZero: __webpack_require__(40),
|
|
RoundTo: __webpack_require__(168),
|
|
SinCosTableGenerator: __webpack_require__(169),
|
|
SmootherStep: __webpack_require__(38),
|
|
SmoothStep: __webpack_require__(37),
|
|
ToXY: __webpack_require__(170),
|
|
TransformXY: __webpack_require__(41),
|
|
Within: __webpack_require__(171),
|
|
Wrap: __webpack_require__(6),
|
|
|
|
// Vector classes
|
|
Vector2: __webpack_require__(2),
|
|
Vector3: __webpack_require__(13),
|
|
Vector4: __webpack_require__(172),
|
|
Matrix3: __webpack_require__(42),
|
|
Matrix4: __webpack_require__(20),
|
|
Quaternion: __webpack_require__(43),
|
|
RotateVec3: __webpack_require__(173)
|
|
|
|
};
|
|
|
|
// Merge in the consts
|
|
|
|
PhaserMath = Extend(false, PhaserMath, CONST);
|
|
|
|
// Export it
|
|
|
|
module.exports = PhaserMath;
|
|
|
|
|
|
/***/ }),
|
|
/* 65 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Angle
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Between: __webpack_require__(28),
|
|
BetweenPoints: __webpack_require__(66),
|
|
BetweenPointsY: __webpack_require__(67),
|
|
BetweenY: __webpack_require__(68),
|
|
CounterClockwise: __webpack_require__(8),
|
|
Normalize: __webpack_require__(29),
|
|
Random: __webpack_require__(69),
|
|
RandomDegrees: __webpack_require__(70),
|
|
Reverse: __webpack_require__(71),
|
|
RotateTo: __webpack_require__(72),
|
|
ShortestBetween: __webpack_require__(73),
|
|
Wrap: __webpack_require__(30),
|
|
WrapDegrees: __webpack_require__(31)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 66 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y).
|
|
*
|
|
* Calculates the angle of the vector from the first point to the second point.
|
|
*
|
|
* @function Phaser.Math.Angle.BetweenPoints
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} point1 - The first point.
|
|
* @param {Phaser.Types.Math.Vector2Like} point2 - The second point.
|
|
*
|
|
* @return {number} The angle in radians.
|
|
*/
|
|
var BetweenPoints = function (point1, point2)
|
|
{
|
|
return Math.atan2(point2.y - point1.y, point2.x - point1.x);
|
|
};
|
|
|
|
module.exports = BetweenPoints;
|
|
|
|
|
|
/***/ }),
|
|
/* 67 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y).
|
|
*
|
|
* The difference between this method and {@link Phaser.Math.Angle.BetweenPoints} is that this assumes the y coordinate
|
|
* travels down the screen.
|
|
*
|
|
* @function Phaser.Math.Angle.BetweenPointsY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} point1 - The first point.
|
|
* @param {Phaser.Types.Math.Vector2Like} point2 - The second point.
|
|
*
|
|
* @return {number} The angle in radians.
|
|
*/
|
|
var BetweenPointsY = function (point1, point2)
|
|
{
|
|
return Math.atan2(point2.x - point1.x, point2.y - point1.y);
|
|
};
|
|
|
|
module.exports = BetweenPointsY;
|
|
|
|
|
|
/***/ }),
|
|
/* 68 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Find the angle of a segment from (x1, y1) -> (x2, y2).
|
|
*
|
|
* The difference between this method and {@link Phaser.Math.Angle.Between} is that this assumes the y coordinate
|
|
* travels down the screen.
|
|
*
|
|
* @function Phaser.Math.Angle.BetweenY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The angle in radians.
|
|
*/
|
|
var BetweenY = function (x1, y1, x2, y2)
|
|
{
|
|
return Math.atan2(x2 - x1, y2 - y1);
|
|
};
|
|
|
|
module.exports = BetweenY;
|
|
|
|
|
|
/***/ }),
|
|
/* 69 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author @samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var FloatBetween = __webpack_require__(18);
|
|
|
|
/**
|
|
* Returns a random angle in the range [-pi, pi].
|
|
*
|
|
* @function Phaser.Math.Angle.Random
|
|
* @since 3.23.0
|
|
*
|
|
* @return {number} The angle, in radians.
|
|
*/
|
|
var Random = function ()
|
|
{
|
|
return FloatBetween(-Math.PI, Math.PI);
|
|
};
|
|
|
|
module.exports = Random;
|
|
|
|
|
|
/***/ }),
|
|
/* 70 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author @samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var FloatBetween = __webpack_require__(18);
|
|
|
|
/**
|
|
* Returns a random angle in the range [-180, 180].
|
|
*
|
|
* @function Phaser.Math.Angle.RandomDegrees
|
|
* @since 3.23.0
|
|
*
|
|
* @return {number} The angle, in degrees.
|
|
*/
|
|
var RandomDegrees = function ()
|
|
{
|
|
return FloatBetween(-180, 180);
|
|
};
|
|
|
|
module.exports = RandomDegrees;
|
|
|
|
|
|
/***/ }),
|
|
/* 71 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Normalize = __webpack_require__(29);
|
|
|
|
/**
|
|
* Reverse the given angle.
|
|
*
|
|
* @function Phaser.Math.Angle.Reverse
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle - The angle to reverse, in radians.
|
|
*
|
|
* @return {number} The reversed angle, in radians.
|
|
*/
|
|
var Reverse = function (angle)
|
|
{
|
|
return Normalize(angle + Math.PI);
|
|
};
|
|
|
|
module.exports = Reverse;
|
|
|
|
|
|
/***/ }),
|
|
/* 72 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MATH_CONST = __webpack_require__(3);
|
|
|
|
/**
|
|
* Rotates `currentAngle` towards `targetAngle`, taking the shortest rotation distance. The `lerp` argument is the amount to rotate by in this call.
|
|
*
|
|
* @function Phaser.Math.Angle.RotateTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} currentAngle - The current angle, in radians.
|
|
* @param {number} targetAngle - The target angle to rotate to, in radians.
|
|
* @param {number} [lerp=0.05] - The lerp value to add to the current angle.
|
|
*
|
|
* @return {number} The adjusted angle.
|
|
*/
|
|
var RotateTo = function (currentAngle, targetAngle, lerp)
|
|
{
|
|
if (lerp === undefined) { lerp = 0.05; }
|
|
|
|
if (currentAngle === targetAngle)
|
|
{
|
|
return currentAngle;
|
|
}
|
|
|
|
if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= (MATH_CONST.PI2 - lerp))
|
|
{
|
|
currentAngle = targetAngle;
|
|
}
|
|
else
|
|
{
|
|
if (Math.abs(targetAngle - currentAngle) > Math.PI)
|
|
{
|
|
if (targetAngle < currentAngle)
|
|
{
|
|
targetAngle += MATH_CONST.PI2;
|
|
}
|
|
else
|
|
{
|
|
targetAngle -= MATH_CONST.PI2;
|
|
}
|
|
}
|
|
|
|
if (targetAngle > currentAngle)
|
|
{
|
|
currentAngle += lerp;
|
|
}
|
|
else if (targetAngle < currentAngle)
|
|
{
|
|
currentAngle -= lerp;
|
|
}
|
|
}
|
|
|
|
return currentAngle;
|
|
};
|
|
|
|
module.exports = RotateTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 73 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Gets the shortest angle between `angle1` and `angle2`.
|
|
*
|
|
* Both angles must be in the range -180 to 180, which is the same clamped
|
|
* range that `sprite.angle` uses, so you can pass in two sprite angles to
|
|
* this method and get the shortest angle back between the two of them.
|
|
*
|
|
* The angle returned will be in the same range. If the returned angle is
|
|
* greater than 0 then it's a counter-clockwise rotation, if < 0 then it's
|
|
* a clockwise rotation.
|
|
*
|
|
* TODO: Wrap the angles in this function?
|
|
*
|
|
* @function Phaser.Math.Angle.ShortestBetween
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} angle1 - The first angle in the range -180 to 180.
|
|
* @param {number} angle2 - The second angle in the range -180 to 180.
|
|
*
|
|
* @return {number} The shortest angle, in degrees. If greater than zero it's a counter-clockwise rotation.
|
|
*/
|
|
var ShortestBetween = function (angle1, angle2)
|
|
{
|
|
var difference = angle2 - angle1;
|
|
|
|
if (difference === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var times = Math.floor((difference - (-180)) / 360);
|
|
|
|
return difference - (times * 360);
|
|
|
|
};
|
|
|
|
module.exports = ShortestBetween;
|
|
|
|
|
|
/***/ }),
|
|
/* 74 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Distance
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Between: __webpack_require__(75),
|
|
BetweenPoints: __webpack_require__(76),
|
|
BetweenPointsSquared: __webpack_require__(77),
|
|
Chebyshev: __webpack_require__(78),
|
|
Power: __webpack_require__(79),
|
|
Snake: __webpack_require__(80),
|
|
Squared: __webpack_require__(81)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 75 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the distance between two sets of coordinates (points).
|
|
*
|
|
* @function Phaser.Math.Distance.Between
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The distance between each point.
|
|
*/
|
|
var DistanceBetween = function (x1, y1, x2, y2)
|
|
{
|
|
var dx = x1 - x2;
|
|
var dy = y1 - y2;
|
|
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
};
|
|
|
|
module.exports = DistanceBetween;
|
|
|
|
|
|
/***/ }),
|
|
/* 76 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the distance between two points.
|
|
*
|
|
* @function Phaser.Math.Distance.BetweenPoints
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} a - The first point.
|
|
* @param {Phaser.Types.Math.Vector2Like} b - The second point.
|
|
*
|
|
* @return {number} The distance between the points.
|
|
*/
|
|
var DistanceBetweenPoints = function (a, b)
|
|
{
|
|
var dx = a.x - b.x;
|
|
var dy = a.y - b.y;
|
|
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
};
|
|
|
|
module.exports = DistanceBetweenPoints;
|
|
|
|
|
|
/***/ }),
|
|
/* 77 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the squared distance between two points.
|
|
*
|
|
* @function Phaser.Math.Distance.BetweenPointsSquared
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} a - The first point.
|
|
* @param {Phaser.Types.Math.Vector2Like} b - The second point.
|
|
*
|
|
* @return {number} The squared distance between the points.
|
|
*/
|
|
var DistanceBetweenPointsSquared = function (a, b)
|
|
{
|
|
var dx = a.x - b.x;
|
|
var dy = a.y - b.y;
|
|
|
|
return dx * dx + dy * dy;
|
|
};
|
|
|
|
module.exports = DistanceBetweenPointsSquared;
|
|
|
|
|
|
/***/ }),
|
|
/* 78 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the Chebyshev distance between two sets of coordinates (points).
|
|
*
|
|
* Chebyshev distance (or chessboard distance) is the maximum of the horizontal and vertical distances.
|
|
* It's the effective distance when movement can be horizontal, vertical, or diagonal.
|
|
*
|
|
* @function Phaser.Math.Distance.Chebyshev
|
|
* @since 3.22.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The distance between each point.
|
|
*/
|
|
var ChebyshevDistance = function (x1, y1, x2, y2)
|
|
{
|
|
return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
|
|
};
|
|
|
|
module.exports = ChebyshevDistance;
|
|
|
|
|
|
/***/ }),
|
|
/* 79 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the distance between two sets of coordinates (points) to the power of `pow`.
|
|
*
|
|
* @function Phaser.Math.Distance.Power
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
* @param {number} pow - The exponent.
|
|
*
|
|
* @return {number} The distance between each point.
|
|
*/
|
|
var DistancePower = function (x1, y1, x2, y2, pow)
|
|
{
|
|
if (pow === undefined) { pow = 2; }
|
|
|
|
return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow));
|
|
};
|
|
|
|
module.exports = DistancePower;
|
|
|
|
|
|
/***/ }),
|
|
/* 80 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the snake distance between two sets of coordinates (points).
|
|
*
|
|
* Snake distance (rectilinear distance, Manhattan distance) is the sum of the horizontal and vertical distances.
|
|
* It's the effective distance when movement is allowed only horizontally or vertically (but not both).
|
|
*
|
|
* @function Phaser.Math.Distance.Snake
|
|
* @since 3.22.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The distance between each point.
|
|
*/
|
|
var SnakeDistance = function (x1, y1, x2, y2)
|
|
{
|
|
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
|
|
};
|
|
|
|
module.exports = SnakeDistance;
|
|
|
|
|
|
/***/ }),
|
|
/* 81 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the distance between two sets of coordinates (points), squared.
|
|
*
|
|
* @function Phaser.Math.Distance.Squared
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x1 - The x coordinate of the first point.
|
|
* @param {number} y1 - The y coordinate of the first point.
|
|
* @param {number} x2 - The x coordinate of the second point.
|
|
* @param {number} y2 - The y coordinate of the second point.
|
|
*
|
|
* @return {number} The distance between each point, squared.
|
|
*/
|
|
var DistanceSquared = function (x1, y1, x2, y2)
|
|
{
|
|
var dx = x1 - x2;
|
|
var dy = y1 - y2;
|
|
|
|
return dx * dx + dy * dy;
|
|
};
|
|
|
|
module.exports = DistanceSquared;
|
|
|
|
|
|
/***/ }),
|
|
/* 82 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Back: __webpack_require__(83),
|
|
Bounce: __webpack_require__(87),
|
|
Circular: __webpack_require__(91),
|
|
Cubic: __webpack_require__(95),
|
|
Elastic: __webpack_require__(99),
|
|
Expo: __webpack_require__(103),
|
|
Linear: __webpack_require__(107),
|
|
Quadratic: __webpack_require__(109),
|
|
Quartic: __webpack_require__(113),
|
|
Quintic: __webpack_require__(117),
|
|
Sine: __webpack_require__(121),
|
|
Stepped: __webpack_require__(125)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 83 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Back
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(84),
|
|
Out: __webpack_require__(85),
|
|
InOut: __webpack_require__(86)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 84 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Back ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Back.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [overshoot=1.70158] - The overshoot amount.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v, overshoot)
|
|
{
|
|
if (overshoot === undefined) { overshoot = 1.70158; }
|
|
|
|
return v * v * ((overshoot + 1) * v - overshoot);
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 85 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Back ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Back.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [overshoot=1.70158] - The overshoot amount.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v, overshoot)
|
|
{
|
|
if (overshoot === undefined) { overshoot = 1.70158; }
|
|
|
|
return --v * v * ((overshoot + 1) * v + overshoot) + 1;
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 86 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Back ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Back.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [overshoot=1.70158] - The overshoot amount.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v, overshoot)
|
|
{
|
|
if (overshoot === undefined) { overshoot = 1.70158; }
|
|
|
|
var s = overshoot * 1.525;
|
|
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * (v * v * ((s + 1) * v - s));
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * ((v -= 2) * v * ((s + 1) * v + s) + 2);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 87 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Bounce
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(88),
|
|
Out: __webpack_require__(89),
|
|
InOut: __webpack_require__(90)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 88 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Bounce ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Bounce.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
v = 1 - v;
|
|
|
|
if (v < 1 / 2.75)
|
|
{
|
|
return 1 - (7.5625 * v * v);
|
|
}
|
|
else if (v < 2 / 2.75)
|
|
{
|
|
return 1 - (7.5625 * (v -= 1.5 / 2.75) * v + 0.75);
|
|
}
|
|
else if (v < 2.5 / 2.75)
|
|
{
|
|
return 1 - (7.5625 * (v -= 2.25 / 2.75) * v + 0.9375);
|
|
}
|
|
else
|
|
{
|
|
return 1 - (7.5625 * (v -= 2.625 / 2.75) * v + 0.984375);
|
|
}
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 89 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Bounce ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Bounce.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
if (v < 1 / 2.75)
|
|
{
|
|
return 7.5625 * v * v;
|
|
}
|
|
else if (v < 2 / 2.75)
|
|
{
|
|
return 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
|
|
}
|
|
else if (v < 2.5 / 2.75)
|
|
{
|
|
return 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
|
|
}
|
|
else
|
|
{
|
|
return 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
|
|
}
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 90 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Bounce ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Bounce.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
var reverse = false;
|
|
|
|
if (v < 0.5)
|
|
{
|
|
v = 1 - (v * 2);
|
|
reverse = true;
|
|
}
|
|
else
|
|
{
|
|
v = (v * 2) - 1;
|
|
}
|
|
|
|
if (v < 1 / 2.75)
|
|
{
|
|
v = 7.5625 * v * v;
|
|
}
|
|
else if (v < 2 / 2.75)
|
|
{
|
|
v = 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
|
|
}
|
|
else if (v < 2.5 / 2.75)
|
|
{
|
|
v = 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
|
|
}
|
|
else
|
|
{
|
|
v = 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
|
|
}
|
|
|
|
if (reverse)
|
|
{
|
|
return (1 - v) * 0.5;
|
|
}
|
|
else
|
|
{
|
|
return v * 0.5 + 0.5;
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 91 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Circular
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(92),
|
|
Out: __webpack_require__(93),
|
|
InOut: __webpack_require__(94)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 92 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Circular ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Circular.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return 1 - Math.sqrt(1 - v * v);
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 93 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Circular ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Circular.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return Math.sqrt(1 - (--v * v));
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 94 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Circular ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Circular.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return -0.5 * (Math.sqrt(1 - v * v) - 1);
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * (Math.sqrt(1 - (v -= 2) * v) + 1);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 95 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Cubic
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(96),
|
|
Out: __webpack_require__(97),
|
|
InOut: __webpack_require__(98)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 96 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Cubic ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Cubic.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return v * v * v;
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 97 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Cubic ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Cubic.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return --v * v * v + 1;
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 98 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Cubic ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Cubic.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * v * v * v;
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * ((v -= 2) * v * v + 2);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 99 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Elastic
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(100),
|
|
Out: __webpack_require__(101),
|
|
InOut: __webpack_require__(102)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 100 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Elastic ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Elastic.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
|
|
* @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v, amplitude, period)
|
|
{
|
|
if (amplitude === undefined) { amplitude = 0.1; }
|
|
if (period === undefined) { period = 0.1; }
|
|
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
var s = period / 4;
|
|
|
|
if (amplitude < 1)
|
|
{
|
|
amplitude = 1;
|
|
}
|
|
else
|
|
{
|
|
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
|
|
}
|
|
|
|
return -(amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
|
|
}
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 101 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Elastic ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Elastic.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
|
|
* @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v, amplitude, period)
|
|
{
|
|
if (amplitude === undefined) { amplitude = 0.1; }
|
|
if (period === undefined) { period = 0.1; }
|
|
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
var s = period / 4;
|
|
|
|
if (amplitude < 1)
|
|
{
|
|
amplitude = 1;
|
|
}
|
|
else
|
|
{
|
|
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
|
|
}
|
|
|
|
return (amplitude * Math.pow(2, -10 * v) * Math.sin((v - s) * (2 * Math.PI) / period) + 1);
|
|
}
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 102 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Elastic ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Elastic.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
|
|
* @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v, amplitude, period)
|
|
{
|
|
if (amplitude === undefined) { amplitude = 0.1; }
|
|
if (period === undefined) { period = 0.1; }
|
|
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
var s = period / 4;
|
|
|
|
if (amplitude < 1)
|
|
{
|
|
amplitude = 1;
|
|
}
|
|
else
|
|
{
|
|
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
|
|
}
|
|
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return -0.5 * (amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
|
|
}
|
|
else
|
|
{
|
|
return amplitude * Math.pow(2, -10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period) * 0.5 + 1;
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 103 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Expo
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(104),
|
|
Out: __webpack_require__(105),
|
|
InOut: __webpack_require__(106)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 104 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Exponential ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Expo.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return Math.pow(2, 10 * (v - 1)) - 0.001;
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 105 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Exponential ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Expo.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return 1 - Math.pow(2, -10 * v);
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 106 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Exponential ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Expo.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * Math.pow(2, 10 * (v - 1));
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * (2 - Math.pow(2, -10 * (v - 1)));
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 107 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
module.exports = __webpack_require__(108);
|
|
|
|
|
|
/***/ }),
|
|
/* 108 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Linear easing (no variation).
|
|
*
|
|
* @function Phaser.Math.Easing.Linear
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Linear = function (v)
|
|
{
|
|
return v;
|
|
};
|
|
|
|
module.exports = Linear;
|
|
|
|
|
|
/***/ }),
|
|
/* 109 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Quadratic
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(110),
|
|
Out: __webpack_require__(111),
|
|
InOut: __webpack_require__(112)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 110 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quadratic ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Quadratic.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return v * v;
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 111 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quadratic ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quadratic.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return v * (2 - v);
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 112 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quadratic ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quadratic.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * v * v;
|
|
}
|
|
else
|
|
{
|
|
return -0.5 * (--v * (v - 2) - 1);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 113 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Quartic
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(114),
|
|
Out: __webpack_require__(115),
|
|
InOut: __webpack_require__(116)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 114 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quartic ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Quartic.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return v * v * v * v;
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 115 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quartic ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quartic.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return 1 - (--v * v * v * v);
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 116 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quartic ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quartic.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * v * v * v * v;
|
|
}
|
|
else
|
|
{
|
|
return -0.5 * ((v -= 2) * v * v * v - 2);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 117 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Quintic
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(118),
|
|
Out: __webpack_require__(119),
|
|
InOut: __webpack_require__(120)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 118 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quintic ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Quintic.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
return v * v * v * v * v;
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 119 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quintic ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quintic.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
return --v * v * v * v * v + 1;
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 120 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Quintic ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Quintic.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if ((v *= 2) < 1)
|
|
{
|
|
return 0.5 * v * v * v * v * v;
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * ((v -= 2) * v * v * v * v + 2);
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 121 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Sine
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
In: __webpack_require__(122),
|
|
Out: __webpack_require__(123),
|
|
InOut: __webpack_require__(124)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 122 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Sinusoidal ease-in.
|
|
*
|
|
* @function Phaser.Math.Easing.Sine.In
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var In = function (v)
|
|
{
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 1 - Math.cos(v * Math.PI / 2);
|
|
}
|
|
};
|
|
|
|
module.exports = In;
|
|
|
|
|
|
/***/ }),
|
|
/* 123 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Sinusoidal ease-out.
|
|
*
|
|
* @function Phaser.Math.Easing.Sine.Out
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Out = function (v)
|
|
{
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return Math.sin(v * Math.PI / 2);
|
|
}
|
|
};
|
|
|
|
module.exports = Out;
|
|
|
|
|
|
/***/ }),
|
|
/* 124 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Sinusoidal ease-in/out.
|
|
*
|
|
* @function Phaser.Math.Easing.Sine.InOut
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var InOut = function (v)
|
|
{
|
|
if (v === 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v === 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0.5 * (1 - Math.cos(Math.PI * v));
|
|
}
|
|
};
|
|
|
|
module.exports = InOut;
|
|
|
|
|
|
/***/ }),
|
|
/* 125 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Easing.Stepped
|
|
*/
|
|
|
|
module.exports = __webpack_require__(126);
|
|
|
|
|
|
/***/ }),
|
|
/* 126 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Stepped easing.
|
|
*
|
|
* @function Phaser.Math.Easing.Stepped
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} v - The value to be tweened.
|
|
* @param {number} [steps=1] - The number of steps in the ease.
|
|
*
|
|
* @return {number} The tweened value.
|
|
*/
|
|
var Stepped = function (v, steps)
|
|
{
|
|
if (steps === undefined) { steps = 1; }
|
|
|
|
if (v <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (v >= 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return (((steps * v) | 0) + 1) * (1 / steps);
|
|
}
|
|
};
|
|
|
|
module.exports = Stepped;
|
|
|
|
|
|
/***/ }),
|
|
/* 127 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Fuzzy
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Ceil: __webpack_require__(128),
|
|
Equal: __webpack_require__(32),
|
|
Floor: __webpack_require__(129),
|
|
GreaterThan: __webpack_require__(130),
|
|
LessThan: __webpack_require__(131)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 128 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the fuzzy ceiling of the given value.
|
|
*
|
|
* @function Phaser.Math.Fuzzy.Ceil
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value.
|
|
* @param {number} [epsilon=0.0001] - The epsilon.
|
|
*
|
|
* @return {number} The fuzzy ceiling of the value.
|
|
*/
|
|
var Ceil = function (value, epsilon)
|
|
{
|
|
if (epsilon === undefined) { epsilon = 0.0001; }
|
|
|
|
return Math.ceil(value - epsilon);
|
|
};
|
|
|
|
module.exports = Ceil;
|
|
|
|
|
|
/***/ }),
|
|
/* 129 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the fuzzy floor of the given value.
|
|
*
|
|
* @function Phaser.Math.Fuzzy.Floor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value.
|
|
* @param {number} [epsilon=0.0001] - The epsilon.
|
|
*
|
|
* @return {number} The floor of the value.
|
|
*/
|
|
var Floor = function (value, epsilon)
|
|
{
|
|
if (epsilon === undefined) { epsilon = 0.0001; }
|
|
|
|
return Math.floor(value + epsilon);
|
|
};
|
|
|
|
module.exports = Floor;
|
|
|
|
|
|
/***/ }),
|
|
/* 130 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Check whether `a` is fuzzily greater than `b`.
|
|
*
|
|
* `a` is fuzzily greater than `b` if it is more than `b - epsilon`.
|
|
*
|
|
* @function Phaser.Math.Fuzzy.GreaterThan
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The first value.
|
|
* @param {number} b - The second value.
|
|
* @param {number} [epsilon=0.0001] - The epsilon.
|
|
*
|
|
* @return {boolean} `true` if `a` is fuzzily greater than than `b`, otherwise `false`.
|
|
*/
|
|
var GreaterThan = function (a, b, epsilon)
|
|
{
|
|
if (epsilon === undefined) { epsilon = 0.0001; }
|
|
|
|
return a > b - epsilon;
|
|
};
|
|
|
|
module.exports = GreaterThan;
|
|
|
|
|
|
/***/ }),
|
|
/* 131 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Check whether `a` is fuzzily less than `b`.
|
|
*
|
|
* `a` is fuzzily less than `b` if it is less than `b + epsilon`.
|
|
*
|
|
* @function Phaser.Math.Fuzzy.LessThan
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The first value.
|
|
* @param {number} b - The second value.
|
|
* @param {number} [epsilon=0.0001] - The epsilon.
|
|
*
|
|
* @return {boolean} `true` if `a` is fuzzily less than `b`, otherwise `false`.
|
|
*/
|
|
var LessThan = function (a, b, epsilon)
|
|
{
|
|
if (epsilon === undefined) { epsilon = 0.0001; }
|
|
|
|
return a < b + epsilon;
|
|
};
|
|
|
|
module.exports = LessThan;
|
|
|
|
|
|
/***/ }),
|
|
/* 132 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Interpolation
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Bezier: __webpack_require__(133),
|
|
CatmullRom: __webpack_require__(134),
|
|
CubicBezier: __webpack_require__(135),
|
|
Linear: __webpack_require__(136),
|
|
QuadraticBezier: __webpack_require__(137),
|
|
SmoothStep: __webpack_require__(138),
|
|
SmootherStep: __webpack_require__(139)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 133 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Bernstein = __webpack_require__(33);
|
|
|
|
/**
|
|
* A bezier interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.Bezier
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number[]} v - The input array of values to interpolate between.
|
|
* @param {number} k - The percentage of interpolation, between 0 and 1.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var BezierInterpolation = function (v, k)
|
|
{
|
|
var b = 0;
|
|
var n = v.length - 1;
|
|
|
|
for (var i = 0; i <= n; i++)
|
|
{
|
|
b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * Bernstein(n, i);
|
|
}
|
|
|
|
return b;
|
|
};
|
|
|
|
module.exports = BezierInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 134 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CatmullRom = __webpack_require__(35);
|
|
|
|
/**
|
|
* A Catmull-Rom interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.CatmullRom
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number[]} v - The input array of values to interpolate between.
|
|
* @param {number} k - The percentage of interpolation, between 0 and 1.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var CatmullRomInterpolation = function (v, k)
|
|
{
|
|
var m = v.length - 1;
|
|
var f = m * k;
|
|
var i = Math.floor(f);
|
|
|
|
if (v[0] === v[m])
|
|
{
|
|
if (k < 0)
|
|
{
|
|
i = Math.floor(f = m * (1 + k));
|
|
}
|
|
|
|
return CatmullRom(f - i, v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m]);
|
|
}
|
|
else
|
|
{
|
|
if (k < 0)
|
|
{
|
|
return v[0] - (CatmullRom(-f, v[0], v[0], v[1], v[1]) - v[0]);
|
|
}
|
|
|
|
if (k > 1)
|
|
{
|
|
return v[m] - (CatmullRom(f - m, v[m], v[m], v[m - 1], v[m - 1]) - v[m]);
|
|
}
|
|
|
|
return CatmullRom(f - i, v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2]);
|
|
}
|
|
};
|
|
|
|
module.exports = CatmullRomInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 135 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P0 (t, p)
|
|
{
|
|
var k = 1 - t;
|
|
|
|
return k * k * k * p;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P1 (t, p)
|
|
{
|
|
var k = 1 - t;
|
|
|
|
return 3 * k * k * t * p;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P2 (t, p)
|
|
{
|
|
return 3 * (1 - t) * t * t * p;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P3 (t, p)
|
|
{
|
|
return t * t * t * p;
|
|
}
|
|
|
|
/**
|
|
* A cubic bezier interpolation method.
|
|
*
|
|
* https://medium.com/@adrian_cooney/bezier-interpolation-13b68563313a
|
|
*
|
|
* @function Phaser.Math.Interpolation.CubicBezier
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} t - The percentage of interpolation, between 0 and 1.
|
|
* @param {number} p0 - The start point.
|
|
* @param {number} p1 - The first control point.
|
|
* @param {number} p2 - The second control point.
|
|
* @param {number} p3 - The end point.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var CubicBezierInterpolation = function (t, p0, p1, p2, p3)
|
|
{
|
|
return P0(t, p0) + P1(t, p1) + P2(t, p2) + P3(t, p3);
|
|
};
|
|
|
|
module.exports = CubicBezierInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 136 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Linear = __webpack_require__(36);
|
|
|
|
/**
|
|
* A linear interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.Linear
|
|
* @since 3.0.0
|
|
* @see {@link https://en.wikipedia.org/wiki/Linear_interpolation}
|
|
*
|
|
* @param {number[]} v - The input array of values to interpolate between.
|
|
* @param {!number} k - The percentage of interpolation, between 0 and 1.
|
|
*
|
|
* @return {!number} The interpolated value.
|
|
*/
|
|
var LinearInterpolation = function (v, k)
|
|
{
|
|
var m = v.length - 1;
|
|
var f = m * k;
|
|
var i = Math.floor(f);
|
|
|
|
if (k < 0)
|
|
{
|
|
return Linear(v[0], v[1], f);
|
|
}
|
|
else if (k > 1)
|
|
{
|
|
return Linear(v[m], v[m - 1], m - f);
|
|
}
|
|
else
|
|
{
|
|
return Linear(v[i], v[(i + 1 > m) ? m : i + 1], f - i);
|
|
}
|
|
};
|
|
|
|
module.exports = LinearInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 137 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P0 (t, p)
|
|
{
|
|
var k = 1 - t;
|
|
|
|
return k * k * p;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P1 (t, p)
|
|
{
|
|
return 2 * (1 - t) * t * p;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function P2 (t, p)
|
|
{
|
|
return t * t * p;
|
|
}
|
|
|
|
// https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js
|
|
|
|
/**
|
|
* A quadratic bezier interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.QuadraticBezier
|
|
* @since 3.2.0
|
|
*
|
|
* @param {number} t - The percentage of interpolation, between 0 and 1.
|
|
* @param {number} p0 - The start point.
|
|
* @param {number} p1 - The control point.
|
|
* @param {number} p2 - The end point.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var QuadraticBezierInterpolation = function (t, p0, p1, p2)
|
|
{
|
|
return P0(t, p0) + P1(t, p1) + P2(t, p2);
|
|
};
|
|
|
|
module.exports = QuadraticBezierInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 138 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SmoothStep = __webpack_require__(37);
|
|
|
|
/**
|
|
* A Smooth Step interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.SmoothStep
|
|
* @since 3.9.0
|
|
* @see {@link https://en.wikipedia.org/wiki/Smoothstep}
|
|
*
|
|
* @param {number} t - The percentage of interpolation, between 0 and 1.
|
|
* @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
|
|
* @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var SmoothStepInterpolation = function (t, min, max)
|
|
{
|
|
return min + (max - min) * SmoothStep(t, 0, 1);
|
|
};
|
|
|
|
module.exports = SmoothStepInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 139 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SmootherStep = __webpack_require__(38);
|
|
|
|
/**
|
|
* A Smoother Step interpolation method.
|
|
*
|
|
* @function Phaser.Math.Interpolation.SmootherStep
|
|
* @since 3.9.0
|
|
* @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
|
|
*
|
|
* @param {number} t - The percentage of interpolation, between 0 and 1.
|
|
* @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
|
|
* @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
|
|
*
|
|
* @return {number} The interpolated value.
|
|
*/
|
|
var SmootherStepInterpolation = function (t, min, max)
|
|
{
|
|
return min + (max - min) * SmootherStep(t, 0, 1);
|
|
};
|
|
|
|
module.exports = SmootherStepInterpolation;
|
|
|
|
|
|
/***/ }),
|
|
/* 140 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Pow2
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
GetNext: __webpack_require__(141),
|
|
IsSize: __webpack_require__(142),
|
|
IsValue: __webpack_require__(143)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 141 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Returns the nearest power of 2 to the given `value`.
|
|
*
|
|
* @function Phaser.Math.Pow2.GetNext
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value.
|
|
*
|
|
* @return {integer} The nearest power of 2 to `value`.
|
|
*/
|
|
var GetPowerOfTwo = function (value)
|
|
{
|
|
var index = Math.log(value) / 0.6931471805599453;
|
|
|
|
return (1 << Math.ceil(index));
|
|
};
|
|
|
|
module.exports = GetPowerOfTwo;
|
|
|
|
|
|
/***/ }),
|
|
/* 142 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Checks if the given `width` and `height` are a power of two.
|
|
* Useful for checking texture dimensions.
|
|
*
|
|
* @function Phaser.Math.Pow2.IsSize
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} width - The width.
|
|
* @param {number} height - The height.
|
|
*
|
|
* @return {boolean} `true` if `width` and `height` are a power of two, otherwise `false`.
|
|
*/
|
|
var IsSizePowerOfTwo = function (width, height)
|
|
{
|
|
return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0);
|
|
};
|
|
|
|
module.exports = IsSizePowerOfTwo;
|
|
|
|
|
|
/***/ }),
|
|
/* 143 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Tests the value and returns `true` if it is a power of two.
|
|
*
|
|
* @function Phaser.Math.Pow2.IsValue
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to check if it's a power of two.
|
|
*
|
|
* @return {boolean} Returns `true` if `value` is a power of two, otherwise `false`.
|
|
*/
|
|
var IsValuePowerOfTwo = function (value)
|
|
{
|
|
return (value > 0 && (value & (value - 1)) === 0);
|
|
};
|
|
|
|
module.exports = IsValuePowerOfTwo;
|
|
|
|
|
|
/***/ }),
|
|
/* 144 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Math.Snap
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Ceil: __webpack_require__(145),
|
|
Floor: __webpack_require__(146),
|
|
To: __webpack_require__(147)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 145 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Snap a value to nearest grid slice, using ceil.
|
|
*
|
|
* Example: if you have an interval gap of `5` and a position of `12`... you will snap to `15`.
|
|
* As will `14` snap to `15`... but `16` will snap to `20`.
|
|
*
|
|
* @function Phaser.Math.Snap.Ceil
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to snap.
|
|
* @param {number} gap - The interval gap of the grid.
|
|
* @param {number} [start=0] - Optional starting offset for gap.
|
|
* @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
|
|
*
|
|
* @return {number} The snapped value.
|
|
*/
|
|
var SnapCeil = function (value, gap, start, divide)
|
|
{
|
|
if (start === undefined) { start = 0; }
|
|
|
|
if (gap === 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
value -= start;
|
|
value = gap * Math.ceil(value / gap);
|
|
|
|
return (divide) ? (start + value) / gap : start + value;
|
|
};
|
|
|
|
module.exports = SnapCeil;
|
|
|
|
|
|
/***/ }),
|
|
/* 146 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Snap a value to nearest grid slice, using floor.
|
|
*
|
|
* Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10`.
|
|
* As will `14` snap to `10`... but `16` will snap to `15`.
|
|
*
|
|
* @function Phaser.Math.Snap.Floor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to snap.
|
|
* @param {number} gap - The interval gap of the grid.
|
|
* @param {number} [start=0] - Optional starting offset for gap.
|
|
* @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
|
|
*
|
|
* @return {number} The snapped value.
|
|
*/
|
|
var SnapFloor = function (value, gap, start, divide)
|
|
{
|
|
if (start === undefined) { start = 0; }
|
|
|
|
if (gap === 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
value -= start;
|
|
value = gap * Math.floor(value / gap);
|
|
|
|
return (divide) ? (start + value) / gap : start + value;
|
|
};
|
|
|
|
module.exports = SnapFloor;
|
|
|
|
|
|
/***/ }),
|
|
/* 147 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Snap a value to nearest grid slice, using rounding.
|
|
*
|
|
* Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10` whereas `14` will snap to `15`.
|
|
*
|
|
* @function Phaser.Math.Snap.To
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to snap.
|
|
* @param {number} gap - The interval gap of the grid.
|
|
* @param {number} [start=0] - Optional starting offset for gap.
|
|
* @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
|
|
*
|
|
* @return {number} The snapped value.
|
|
*/
|
|
var SnapTo = function (value, gap, start, divide)
|
|
{
|
|
if (start === undefined) { start = 0; }
|
|
|
|
if (gap === 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
value -= start;
|
|
value = gap * Math.round(value / gap);
|
|
|
|
return (divide) ? (start + value) / gap : start + value;
|
|
};
|
|
|
|
module.exports = SnapTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 148 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A seeded Random Data Generator.
|
|
*
|
|
* Access via `Phaser.Math.RND` which is an instance of this class pre-defined
|
|
* by Phaser. Or, create your own instance to use as you require.
|
|
*
|
|
* The `Math.RND` generator is seeded by the Game Config property value `seed`.
|
|
* If no such config property exists, a random number is used.
|
|
*
|
|
* If you create your own instance of this class you should provide a seed for it.
|
|
* If no seed is given it will use a 'random' one based on Date.now.
|
|
*
|
|
* @class RandomDataGenerator
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|string[])} [seeds] - The seeds to use for the random number generator.
|
|
*/
|
|
var RandomDataGenerator = new Class({
|
|
|
|
initialize:
|
|
|
|
function RandomDataGenerator (seeds)
|
|
{
|
|
if (seeds === undefined) { seeds = [ (Date.now() * Math.random()).toString() ]; }
|
|
|
|
/**
|
|
* Internal var.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#c
|
|
* @type {number}
|
|
* @default 1
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
this.c = 1;
|
|
|
|
/**
|
|
* Internal var.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#s0
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
this.s0 = 0;
|
|
|
|
/**
|
|
* Internal var.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#s1
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
this.s1 = 0;
|
|
|
|
/**
|
|
* Internal var.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#s2
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
this.s2 = 0;
|
|
|
|
/**
|
|
* Internal var.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#n
|
|
* @type {number}
|
|
* @default 0
|
|
* @private
|
|
* @since 3.2.0
|
|
*/
|
|
this.n = 0;
|
|
|
|
/**
|
|
* Signs to choose from.
|
|
*
|
|
* @name Phaser.Math.RandomDataGenerator#signs
|
|
* @type {number[]}
|
|
* @since 3.0.0
|
|
*/
|
|
this.signs = [ -1, 1 ];
|
|
|
|
if (seeds)
|
|
{
|
|
this.init(seeds);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Private random helper.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#rnd
|
|
* @since 3.0.0
|
|
* @private
|
|
*
|
|
* @return {number} A random number.
|
|
*/
|
|
rnd: function ()
|
|
{
|
|
var t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32
|
|
|
|
this.c = t | 0;
|
|
this.s0 = this.s1;
|
|
this.s1 = this.s2;
|
|
this.s2 = t - this.c;
|
|
|
|
return this.s2;
|
|
},
|
|
|
|
/**
|
|
* Internal method that creates a seed hash.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#hash
|
|
* @since 3.0.0
|
|
* @private
|
|
*
|
|
* @param {string} data - The value to hash.
|
|
*
|
|
* @return {number} The hashed value.
|
|
*/
|
|
hash: function (data)
|
|
{
|
|
var h;
|
|
var n = this.n;
|
|
|
|
data = data.toString();
|
|
|
|
for (var i = 0; i < data.length; i++)
|
|
{
|
|
n += data.charCodeAt(i);
|
|
h = 0.02519603282416938 * n;
|
|
n = h >>> 0;
|
|
h -= n;
|
|
h *= n;
|
|
n = h >>> 0;
|
|
h -= n;
|
|
n += h * 0x100000000;// 2^32
|
|
}
|
|
|
|
this.n = n;
|
|
|
|
return (n >>> 0) * 2.3283064365386963e-10;// 2^-32
|
|
},
|
|
|
|
/**
|
|
* Initialize the state of the random data generator.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#init
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|string[])} seeds - The seeds to initialize the random data generator with.
|
|
*/
|
|
init: function (seeds)
|
|
{
|
|
if (typeof seeds === 'string')
|
|
{
|
|
this.state(seeds);
|
|
}
|
|
else
|
|
{
|
|
this.sow(seeds);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Reset the seed of the random data generator.
|
|
*
|
|
* _Note_: the seed array is only processed up to the first `undefined` (or `null`) value, should such be present.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#sow
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string[]} seeds - The array of seeds: the `toString()` of each value is used.
|
|
*/
|
|
sow: function (seeds)
|
|
{
|
|
// Always reset to default seed
|
|
this.n = 0xefc8249d;
|
|
this.s0 = this.hash(' ');
|
|
this.s1 = this.hash(' ');
|
|
this.s2 = this.hash(' ');
|
|
this.c = 1;
|
|
|
|
if (!seeds)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Apply any seeds
|
|
for (var i = 0; i < seeds.length && (seeds[i] != null); i++)
|
|
{
|
|
var seed = seeds[i];
|
|
|
|
this.s0 -= this.hash(seed);
|
|
this.s0 += ~~(this.s0 < 0);
|
|
this.s1 -= this.hash(seed);
|
|
this.s1 += ~~(this.s1 < 0);
|
|
this.s2 -= this.hash(seed);
|
|
this.s2 += ~~(this.s2 < 0);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Returns a random integer between 0 and 2^32.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#integer
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random integer between 0 and 2^32.
|
|
*/
|
|
integer: function ()
|
|
{
|
|
// 2^32
|
|
return this.rnd() * 0x100000000;
|
|
},
|
|
|
|
/**
|
|
* Returns a random real number between 0 and 1.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#frac
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random real number between 0 and 1.
|
|
*/
|
|
frac: function ()
|
|
{
|
|
// 2^-53
|
|
return this.rnd() + (this.rnd() * 0x200000 | 0) * 1.1102230246251565e-16;
|
|
},
|
|
|
|
/**
|
|
* Returns a random real number between 0 and 2^32.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#real
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random real number between 0 and 2^32.
|
|
*/
|
|
real: function ()
|
|
{
|
|
return this.integer() + this.frac();
|
|
},
|
|
|
|
/**
|
|
* Returns a random integer between and including min and max.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#integerInRange
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} min - The minimum value in the range.
|
|
* @param {number} max - The maximum value in the range.
|
|
*
|
|
* @return {number} A random number between min and max.
|
|
*/
|
|
integerInRange: function (min, max)
|
|
{
|
|
return Math.floor(this.realInRange(0, max - min + 1) + min);
|
|
},
|
|
|
|
/**
|
|
* Returns a random integer between and including min and max.
|
|
* This method is an alias for RandomDataGenerator.integerInRange.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#between
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} min - The minimum value in the range.
|
|
* @param {number} max - The maximum value in the range.
|
|
*
|
|
* @return {number} A random number between min and max.
|
|
*/
|
|
between: function (min, max)
|
|
{
|
|
return Math.floor(this.realInRange(0, max - min + 1) + min);
|
|
},
|
|
|
|
/**
|
|
* Returns a random real number between min and max.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#realInRange
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} min - The minimum value in the range.
|
|
* @param {number} max - The maximum value in the range.
|
|
*
|
|
* @return {number} A random number between min and max.
|
|
*/
|
|
realInRange: function (min, max)
|
|
{
|
|
return this.frac() * (max - min) + min;
|
|
},
|
|
|
|
/**
|
|
* Returns a random real number between -1 and 1.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#normal
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random real number between -1 and 1.
|
|
*/
|
|
normal: function ()
|
|
{
|
|
return 1 - (2 * this.frac());
|
|
},
|
|
|
|
/**
|
|
* Returns a valid RFC4122 version4 ID hex string from https://gist.github.com/1308368
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#uuid
|
|
* @since 3.0.0
|
|
*
|
|
* @return {string} A valid RFC4122 version4 ID hex string
|
|
*/
|
|
uuid: function ()
|
|
{
|
|
var a = '';
|
|
var b = '';
|
|
|
|
for (b = a = ''; a++ < 36; b += ~a % 5 | a * 3 & 4 ? (a ^ 15 ? 8 ^ this.frac() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-')
|
|
{
|
|
// eslint-disable-next-line no-empty
|
|
}
|
|
|
|
return b;
|
|
},
|
|
|
|
/**
|
|
* Returns a random element from within the given array.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#pick
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[]} - [array]
|
|
* @genericUse {T} - [$return]
|
|
*
|
|
* @param {T[]} array - The array to pick a random element from.
|
|
*
|
|
* @return {T} A random member of the array.
|
|
*/
|
|
pick: function (array)
|
|
{
|
|
return array[this.integerInRange(0, array.length - 1)];
|
|
},
|
|
|
|
/**
|
|
* Returns a sign to be used with multiplication operator.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#sign
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} -1 or +1.
|
|
*/
|
|
sign: function ()
|
|
{
|
|
return this.pick(this.signs);
|
|
},
|
|
|
|
/**
|
|
* Returns a random element from within the given array, favoring the earlier entries.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#weightedPick
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[]} - [array]
|
|
* @genericUse {T} - [$return]
|
|
*
|
|
* @param {T[]} array - The array to pick a random element from.
|
|
*
|
|
* @return {T} A random member of the array.
|
|
*/
|
|
weightedPick: function (array)
|
|
{
|
|
return array[~~(Math.pow(this.frac(), 2) * (array.length - 1) + 0.5)];
|
|
},
|
|
|
|
/**
|
|
* Returns a random timestamp between min and max, or between the beginning of 2000 and the end of 2020 if min and max aren't specified.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#timestamp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} min - The minimum value in the range.
|
|
* @param {number} max - The maximum value in the range.
|
|
*
|
|
* @return {number} A random timestamp between min and max.
|
|
*/
|
|
timestamp: function (min, max)
|
|
{
|
|
return this.realInRange(min || 946684800000, max || 1577862000000);
|
|
},
|
|
|
|
/**
|
|
* Returns a random angle between -180 and 180.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#angle
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random number between -180 and 180.
|
|
*/
|
|
angle: function ()
|
|
{
|
|
return this.integerInRange(-180, 180);
|
|
},
|
|
|
|
/**
|
|
* Returns a random rotation in radians, between -3.141 and 3.141
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#rotation
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} A random number between -3.141 and 3.141
|
|
*/
|
|
rotation: function ()
|
|
{
|
|
return this.realInRange(-3.1415926, 3.1415926);
|
|
},
|
|
|
|
/**
|
|
* Gets or Sets the state of the generator. This allows you to retain the values
|
|
* that the generator is using between games, i.e. in a game save file.
|
|
*
|
|
* To seed this generator with a previously saved state you can pass it as the
|
|
* `seed` value in your game config, or call this method directly after Phaser has booted.
|
|
*
|
|
* Call this method with no parameters to return the current state.
|
|
*
|
|
* If providing a state it should match the same format that this method
|
|
* returns, which is a string with a header `!rnd` followed by the `c`,
|
|
* `s0`, `s1` and `s2` values respectively, each comma-delimited.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#state
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} [state] - Generator state to be set.
|
|
*
|
|
* @return {string} The current state of the generator.
|
|
*/
|
|
state: function (state)
|
|
{
|
|
if (typeof state === 'string' && state.match(/^!rnd/))
|
|
{
|
|
state = state.split(',');
|
|
|
|
this.c = parseFloat(state[1]);
|
|
this.s0 = parseFloat(state[2]);
|
|
this.s1 = parseFloat(state[3]);
|
|
this.s2 = parseFloat(state[4]);
|
|
}
|
|
|
|
return [ '!rnd', this.c, this.s0, this.s1, this.s2 ].join(',');
|
|
},
|
|
|
|
/**
|
|
* Shuffles the given array, using the current seed.
|
|
*
|
|
* @method Phaser.Math.RandomDataGenerator#shuffle
|
|
* @since 3.7.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[]} - [array,$return]
|
|
*
|
|
* @param {T[]} [array] - The array to be shuffled.
|
|
*
|
|
* @return {T[]} The shuffled array.
|
|
*/
|
|
shuffle: function (array)
|
|
{
|
|
var len = array.length - 1;
|
|
|
|
for (var i = len; i > 0; i--)
|
|
{
|
|
var randomIndex = Math.floor(this.frac() * (i + 1));
|
|
var itemAtIndex = array[randomIndex];
|
|
|
|
array[randomIndex] = array[i];
|
|
array[i] = itemAtIndex;
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = RandomDataGenerator;
|
|
|
|
|
|
/***/ }),
|
|
/* 149 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the mean average of the given values.
|
|
*
|
|
* @function Phaser.Math.Average
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number[]} values - The values to average.
|
|
*
|
|
* @return {number} The average value.
|
|
*/
|
|
var Average = function (values)
|
|
{
|
|
var sum = 0;
|
|
|
|
for (var i = 0; i < values.length; i++)
|
|
{
|
|
sum += (+values[i]);
|
|
}
|
|
|
|
return sum / values.length;
|
|
};
|
|
|
|
module.exports = Average;
|
|
|
|
|
|
/***/ }),
|
|
/* 150 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Compute a random integer between the `min` and `max` values, inclusive.
|
|
*
|
|
* @function Phaser.Math.Between
|
|
* @since 3.0.0
|
|
*
|
|
* @param {integer} min - The minimum value.
|
|
* @param {integer} max - The maximum value.
|
|
*
|
|
* @return {integer} The random integer.
|
|
*/
|
|
var Between = function (min, max)
|
|
{
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
};
|
|
|
|
module.exports = Between;
|
|
|
|
|
|
/***/ }),
|
|
/* 151 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Ceils to some place comparative to a `base`, default is 10 for decimal place.
|
|
*
|
|
* The `place` is represented by the power applied to `base` to get that place.
|
|
*
|
|
* @function Phaser.Math.CeilTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to round.
|
|
* @param {number} [place=0] - The place to round to.
|
|
* @param {integer} [base=10] - The base to round in. Default is 10 for decimal.
|
|
*
|
|
* @return {number} The rounded value.
|
|
*/
|
|
var CeilTo = function (value, place, base)
|
|
{
|
|
if (place === undefined) { place = 0; }
|
|
if (base === undefined) { base = 10; }
|
|
|
|
var p = Math.pow(base, -place);
|
|
|
|
return Math.ceil(value * p) / p;
|
|
};
|
|
|
|
module.exports = CeilTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 152 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculates the positive difference of two given numbers.
|
|
*
|
|
* @function Phaser.Math.Difference
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The first number in the calculation.
|
|
* @param {number} b - The second number in the calculation.
|
|
*
|
|
* @return {number} The positive difference of the two given numbers.
|
|
*/
|
|
var Difference = function (a, b)
|
|
{
|
|
return Math.abs(a - b);
|
|
};
|
|
|
|
module.exports = Difference;
|
|
|
|
|
|
/***/ }),
|
|
/* 153 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Clamp = __webpack_require__(4);
|
|
var Class = __webpack_require__(0);
|
|
var Matrix4 = __webpack_require__(20);
|
|
var NOOP = __webpack_require__(1);
|
|
|
|
var tempMatrix = new Matrix4();
|
|
|
|
/**
|
|
* @classdesc
|
|
*
|
|
* @class Euler
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.50.0
|
|
*
|
|
* @param {number} [x] - The x component.
|
|
* @param {number} [y] - The y component.
|
|
* @param {number} [z] - The z component.
|
|
*/
|
|
var Euler = new Class({
|
|
|
|
initialize:
|
|
|
|
function Euler (x, y, z, order)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = 0; }
|
|
if (z === undefined) { z = 0; }
|
|
if (order === undefined) { order = Euler.DefaultOrder; }
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
this._order = order;
|
|
|
|
this.onChangeCallback = NOOP;
|
|
},
|
|
|
|
x: {
|
|
get: function ()
|
|
{
|
|
return this._x;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._x = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
y: {
|
|
get: function ()
|
|
{
|
|
return this._y;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._y = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
z: {
|
|
get: function ()
|
|
{
|
|
return this._z;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._z = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
order: {
|
|
get: function ()
|
|
{
|
|
return this._order;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._order = value;
|
|
|
|
this.onChangeCallback(this);
|
|
}
|
|
},
|
|
|
|
set: function (x, y, z, order)
|
|
{
|
|
if (order === undefined) { order = this._order; }
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
this._order = order;
|
|
|
|
this.onChangeCallback(this);
|
|
|
|
return this;
|
|
},
|
|
|
|
copy: function (euler)
|
|
{
|
|
return this.set(euler.x, euler.y, euler.z, euler.order);
|
|
},
|
|
|
|
setFromQuaternion: function (quaternion, order, update)
|
|
{
|
|
if (order === undefined) { order = this._order; }
|
|
if (update === undefined) { update = false; }
|
|
|
|
tempMatrix.fromQuat(quaternion);
|
|
|
|
return this.setFromRotationMatrix(tempMatrix, order, update);
|
|
},
|
|
|
|
setFromRotationMatrix: function (matrix, order, update)
|
|
{
|
|
if (order === undefined) { order = this._order; }
|
|
if (update === undefined) { update = false; }
|
|
|
|
var elements = matrix.val;
|
|
|
|
// Upper 3x3 of matrix is un-scaled rotation matrix
|
|
var m11 = elements[0];
|
|
var m12 = elements[4];
|
|
var m13 = elements[8];
|
|
var m21 = elements[1];
|
|
var m22 = elements[5];
|
|
var m23 = elements[9];
|
|
var m31 = elements[2];
|
|
var m32 = elements[6];
|
|
var m33 = elements[10];
|
|
|
|
var x = 0;
|
|
var y = 0;
|
|
var z = 0;
|
|
var epsilon = 0.99999;
|
|
|
|
switch (order)
|
|
{
|
|
case 'XYZ':
|
|
{
|
|
y = Math.asin(Clamp(m13, -1, 1));
|
|
|
|
if (Math.abs(m13) < epsilon)
|
|
{
|
|
x = Math.atan2(-m23, m33);
|
|
z = Math.atan2(-m12, m11);
|
|
}
|
|
else
|
|
{
|
|
x = Math.atan2(m32, m22);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'YXZ':
|
|
{
|
|
x = Math.asin(-Clamp(m23, -1, 1));
|
|
|
|
if (Math.abs(m23) < epsilon)
|
|
{
|
|
y = Math.atan2(m13, m33);
|
|
z = Math.atan2(m21, m22);
|
|
}
|
|
else
|
|
{
|
|
y = Math.atan2(-m31, m11);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'ZXY':
|
|
{
|
|
x = Math.asin(Clamp(m32, -1, 1));
|
|
|
|
if (Math.abs(m32) < epsilon)
|
|
{
|
|
y = Math.atan2(-m31, m33);
|
|
z = Math.atan2(-m12, m22);
|
|
}
|
|
else
|
|
{
|
|
z = Math.atan2(m21, m11);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'ZYX':
|
|
{
|
|
y = Math.asin(-Clamp(m31, -1, 1));
|
|
|
|
if (Math.abs(m31) < epsilon)
|
|
{
|
|
x = Math.atan2(m32, m33);
|
|
z = Math.atan2(m21, m11);
|
|
}
|
|
else
|
|
{
|
|
z = Math.atan2(-m12, m22);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'YZX':
|
|
{
|
|
z = Math.asin(Clamp(m21, -1, 1));
|
|
|
|
if (Math.abs(m21) < epsilon)
|
|
{
|
|
x = Math.atan2(-m23, m22);
|
|
y = Math.atan2(-m31, m11);
|
|
}
|
|
else
|
|
{
|
|
y = Math.atan2(m13, m33);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'XZY':
|
|
{
|
|
z = Math.asin(-Clamp(m12, -1, 1));
|
|
|
|
if (Math.abs(m12) < epsilon)
|
|
{
|
|
x = Math.atan2(m32, m22);
|
|
y = Math.atan2(m13, m11);
|
|
}
|
|
else
|
|
{
|
|
x = Math.atan2(-m23, m33);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
this._order = order;
|
|
|
|
if (update)
|
|
{
|
|
this.onChangeCallback(this);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
Euler.RotationOrders = [ 'XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY' ];
|
|
|
|
Euler.DefaultOrder = 'XYZ';
|
|
|
|
module.exports = Euler;
|
|
|
|
|
|
/***/ }),
|
|
/* 154 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Floors to some place comparative to a `base`, default is 10 for decimal place.
|
|
*
|
|
* The `place` is represented by the power applied to `base` to get that place.
|
|
*
|
|
* @function Phaser.Math.FloorTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to round.
|
|
* @param {integer} [place=0] - The place to round to.
|
|
* @param {integer} [base=10] - The base to round in. Default is 10 for decimal.
|
|
*
|
|
* @return {number} The rounded value.
|
|
*/
|
|
var FloorTo = function (value, place, base)
|
|
{
|
|
if (place === undefined) { place = 0; }
|
|
if (base === undefined) { base = 10; }
|
|
|
|
var p = Math.pow(base, -place);
|
|
|
|
return Math.floor(value * p) / p;
|
|
};
|
|
|
|
module.exports = FloorTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 155 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Clamp = __webpack_require__(4);
|
|
|
|
/**
|
|
* Return a value based on the range between `min` and `max` and the percentage given.
|
|
*
|
|
* @function Phaser.Math.FromPercent
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} percent - A value between 0 and 1 representing the percentage.
|
|
* @param {number} min - The minimum value.
|
|
* @param {number} [max] - The maximum value.
|
|
*
|
|
* @return {number} The value that is `percent` percent between `min` and `max`.
|
|
*/
|
|
var FromPercent = function (percent, min, max)
|
|
{
|
|
percent = Clamp(percent, 0, 1);
|
|
|
|
return (max - min) * percent;
|
|
};
|
|
|
|
module.exports = FromPercent;
|
|
|
|
|
|
/***/ }),
|
|
/* 156 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate a per-ms speed from a distance and time (given in seconds).
|
|
*
|
|
* @function Phaser.Math.GetSpeed
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} distance - The distance.
|
|
* @param {integer} time - The time, in seconds.
|
|
*
|
|
* @return {number} The speed, in distance per ms.
|
|
*
|
|
* @example
|
|
* // 400px over 1 second is 0.4 px/ms
|
|
* Phaser.Math.GetSpeed(400, 1) // -> 0.4
|
|
*/
|
|
var GetSpeed = function (distance, time)
|
|
{
|
|
return (distance / time) / 1000;
|
|
};
|
|
|
|
module.exports = GetSpeed;
|
|
|
|
|
|
/***/ }),
|
|
/* 157 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Check if a given value is an even number.
|
|
*
|
|
* @function Phaser.Math.IsEven
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The number to perform the check with.
|
|
*
|
|
* @return {boolean} Whether the number is even or not.
|
|
*/
|
|
var IsEven = function (value)
|
|
{
|
|
// Use abstract equality == for "is number" test
|
|
|
|
// eslint-disable-next-line eqeqeq
|
|
return (value == parseFloat(value)) ? !(value % 2) : void 0;
|
|
};
|
|
|
|
module.exports = IsEven;
|
|
|
|
|
|
/***/ }),
|
|
/* 158 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Check if a given value is an even number using a strict type check.
|
|
*
|
|
* @function Phaser.Math.IsEvenStrict
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The number to perform the check with.
|
|
*
|
|
* @return {boolean} Whether the number is even or not.
|
|
*/
|
|
var IsEvenStrict = function (value)
|
|
{
|
|
// Use strict equality === for "is number" test
|
|
return (value === parseFloat(value)) ? !(value % 2) : void 0;
|
|
};
|
|
|
|
module.exports = IsEvenStrict;
|
|
|
|
|
|
/***/ }),
|
|
/* 159 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Add an `amount` to a `value`, limiting the maximum result to `max`.
|
|
*
|
|
* @function Phaser.Math.MaxAdd
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to add to.
|
|
* @param {number} amount - The amount to add.
|
|
* @param {number} max - The maximum value to return.
|
|
*
|
|
* @return {number} The resulting value.
|
|
*/
|
|
var MaxAdd = function (value, amount, max)
|
|
{
|
|
return Math.min(value + amount, max);
|
|
};
|
|
|
|
module.exports = MaxAdd;
|
|
|
|
|
|
/***/ }),
|
|
/* 160 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Subtract an `amount` from `value`, limiting the minimum result to `min`.
|
|
*
|
|
* @function Phaser.Math.MinSub
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to subtract from.
|
|
* @param {number} amount - The amount to subtract.
|
|
* @param {number} min - The minimum value to return.
|
|
*
|
|
* @return {number} The resulting value.
|
|
*/
|
|
var MinSub = function (value, amount, min)
|
|
{
|
|
return Math.max(value - amount, min);
|
|
};
|
|
|
|
module.exports = MinSub;
|
|
|
|
|
|
/***/ }),
|
|
/* 161 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Work out what percentage `value` is of the range between `min` and `max`.
|
|
* If `max` isn't given then it will return the percentage of `value` to `min`.
|
|
*
|
|
* You can optionally specify an `upperMax` value, which is a mid-way point in the range that represents 100%, after which the % starts to go down to zero again.
|
|
*
|
|
* @function Phaser.Math.Percent
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to determine the percentage of.
|
|
* @param {number} min - The minimum value.
|
|
* @param {number} [max] - The maximum value.
|
|
* @param {number} [upperMax] - The mid-way point in the range that represents 100%.
|
|
*
|
|
* @return {number} A value between 0 and 1 representing the percentage.
|
|
*/
|
|
var Percent = function (value, min, max, upperMax)
|
|
{
|
|
if (max === undefined) { max = min + 1; }
|
|
|
|
var percentage = (value - min) / (max - min);
|
|
|
|
if (percentage > 1)
|
|
{
|
|
if (upperMax !== undefined)
|
|
{
|
|
percentage = ((upperMax - value)) / (upperMax - max);
|
|
|
|
if (percentage < 0)
|
|
{
|
|
percentage = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
percentage = 1;
|
|
}
|
|
}
|
|
else if (percentage < 0)
|
|
{
|
|
percentage = 0;
|
|
}
|
|
|
|
return percentage;
|
|
};
|
|
|
|
module.exports = Percent;
|
|
|
|
|
|
/***/ }),
|
|
/* 162 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Compute a random unit vector.
|
|
*
|
|
* Computes random values for the given vector between -1 and 1 that can be used to represent a direction.
|
|
*
|
|
* Optionally accepts a scale value to scale the resulting vector by.
|
|
*
|
|
* @function Phaser.Math.RandomXY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector2} vector - The Vector to compute random values for.
|
|
* @param {number} [scale=1] - The scale of the random values.
|
|
*
|
|
* @return {Phaser.Math.Vector2} The given Vector.
|
|
*/
|
|
var RandomXY = function (vector, scale)
|
|
{
|
|
if (scale === undefined) { scale = 1; }
|
|
|
|
var r = Math.random() * 2 * Math.PI;
|
|
|
|
vector.x = Math.cos(r) * scale;
|
|
vector.y = Math.sin(r) * scale;
|
|
|
|
return vector;
|
|
};
|
|
|
|
module.exports = RandomXY;
|
|
|
|
|
|
/***/ }),
|
|
/* 163 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Compute a random position vector in a spherical area, optionally defined by the given radius.
|
|
*
|
|
* @function Phaser.Math.RandomXYZ
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} vec3 - The Vector to compute random values for.
|
|
* @param {number} [radius=1] - The radius.
|
|
*
|
|
* @return {Phaser.Math.Vector3} The given Vector.
|
|
*/
|
|
var RandomXYZ = function (vec3, radius)
|
|
{
|
|
if (radius === undefined) { radius = 1; }
|
|
|
|
var r = Math.random() * 2 * Math.PI;
|
|
var z = (Math.random() * 2) - 1;
|
|
var zScale = Math.sqrt(1 - z * z) * radius;
|
|
|
|
vec3.x = Math.cos(r) * zScale;
|
|
vec3.y = Math.sin(r) * zScale;
|
|
vec3.z = z * radius;
|
|
|
|
return vec3;
|
|
};
|
|
|
|
module.exports = RandomXYZ;
|
|
|
|
|
|
/***/ }),
|
|
/* 164 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Compute a random four-dimensional vector.
|
|
*
|
|
* @function Phaser.Math.RandomXYZW
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} vec4 - The Vector to compute random values for.
|
|
* @param {number} [scale=1] - The scale of the random values.
|
|
*
|
|
* @return {Phaser.Math.Vector4} The given Vector.
|
|
*/
|
|
var RandomXYZW = function (vec4, scale)
|
|
{
|
|
if (scale === undefined) { scale = 1; }
|
|
|
|
// TODO: Not spherical; should fix this for more uniform distribution
|
|
vec4.x = (Math.random() * 2 - 1) * scale;
|
|
vec4.y = (Math.random() * 2 - 1) * scale;
|
|
vec4.z = (Math.random() * 2 - 1) * scale;
|
|
vec4.w = (Math.random() * 2 - 1) * scale;
|
|
|
|
return vec4;
|
|
};
|
|
|
|
module.exports = RandomXYZW;
|
|
|
|
|
|
/***/ }),
|
|
/* 165 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Rotate a given point by a given angle around the origin (0, 0), in an anti-clockwise direction.
|
|
*
|
|
* @function Phaser.Math.Rotate
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
|
|
* @param {number} angle - The angle to be rotated by in an anticlockwise direction.
|
|
*
|
|
* @return {Phaser.Geom.Point} The given point, rotated by the given angle in an anticlockwise direction.
|
|
*/
|
|
var Rotate = function (point, angle)
|
|
{
|
|
var x = point.x;
|
|
var y = point.y;
|
|
|
|
point.x = (x * Math.cos(angle)) - (y * Math.sin(angle));
|
|
point.y = (x * Math.sin(angle)) + (y * Math.cos(angle));
|
|
|
|
return point;
|
|
};
|
|
|
|
module.exports = Rotate;
|
|
|
|
|
|
/***/ }),
|
|
/* 166 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Rotate a `point` around `x` and `y` by the given `angle` and `distance`.
|
|
*
|
|
* In polar notation, this maps a point from (r, t) to (distance, t + angle), vs. the origin (x, y).
|
|
*
|
|
* @function Phaser.Math.RotateAroundDistance
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
|
|
*
|
|
* @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
|
|
* @param {number} x - The horizontal coordinate to rotate around.
|
|
* @param {number} y - The vertical coordinate to rotate around.
|
|
* @param {number} angle - The angle of rotation in radians.
|
|
* @param {number} distance - The distance from (x, y) to place the point at.
|
|
*
|
|
* @return {Phaser.Types.Math.Vector2Like} The given point.
|
|
*/
|
|
var RotateAroundDistance = function (point, x, y, angle, distance)
|
|
{
|
|
var t = angle + Math.atan2(point.y - y, point.x - x);
|
|
|
|
point.x = x + (distance * Math.cos(t));
|
|
point.y = y + (distance * Math.sin(t));
|
|
|
|
return point;
|
|
};
|
|
|
|
module.exports = RotateAroundDistance;
|
|
|
|
|
|
/***/ }),
|
|
/* 167 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author samme
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Position a `point` at the given `angle` and `distance` to (`x`, `y`).
|
|
*
|
|
* @function Phaser.Math.RotateTo
|
|
* @since 3.24.0
|
|
*
|
|
* @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
|
|
*
|
|
* @param {Phaser.Types.Math.Vector2Like} point - The point to be positioned.
|
|
* @param {number} x - The horizontal coordinate to position from.
|
|
* @param {number} y - The vertical coordinate to position from.
|
|
* @param {number} angle - The angle of rotation in radians.
|
|
* @param {number} distance - The distance from (x, y) to place the point at.
|
|
*
|
|
* @return {Phaser.Types.Math.Vector2Like} The given point.
|
|
*/
|
|
var RotateTo = function (point, x, y, angle, distance)
|
|
{
|
|
point.x = x + (distance * Math.cos(angle));
|
|
point.y = y + (distance * Math.sin(angle));
|
|
|
|
return point;
|
|
};
|
|
|
|
module.exports = RotateTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 168 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Round a value to the given precision.
|
|
*
|
|
* For example:
|
|
*
|
|
* ```javascript
|
|
* RoundTo(123.456, 0) = 123
|
|
* RoundTo(123.456, 1) = 120
|
|
* RoundTo(123.456, 2) = 100
|
|
* ```
|
|
*
|
|
* To round the decimal, i.e. to round to precision, pass in a negative `place`:
|
|
*
|
|
* ```javascript
|
|
* RoundTo(123.456789, 0) = 123
|
|
* RoundTo(123.456789, -1) = 123.5
|
|
* RoundTo(123.456789, -2) = 123.46
|
|
* RoundTo(123.456789, -3) = 123.457
|
|
* ```
|
|
*
|
|
* @function Phaser.Math.RoundTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to round.
|
|
* @param {integer} [place=0] - The place to round to. Positive to round the units, negative to round the decimal.
|
|
* @param {integer} [base=10] - The base to round in. Default is 10 for decimal.
|
|
*
|
|
* @return {number} The rounded value.
|
|
*/
|
|
var RoundTo = function (value, place, base)
|
|
{
|
|
if (place === undefined) { place = 0; }
|
|
if (base === undefined) { base = 10; }
|
|
|
|
var p = Math.pow(base, -place);
|
|
|
|
return Math.round(value * p) / p;
|
|
};
|
|
|
|
module.exports = RoundTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 169 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Generate a series of sine and cosine values.
|
|
*
|
|
* @function Phaser.Math.SinCosTableGenerator
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} length - The number of values to generate.
|
|
* @param {number} [sinAmp=1] - The sine value amplitude.
|
|
* @param {number} [cosAmp=1] - The cosine value amplitude.
|
|
* @param {number} [frequency=1] - The frequency of the values.
|
|
*
|
|
* @return {Phaser.Types.Math.SinCosTable} The generated values.
|
|
*/
|
|
var SinCosTableGenerator = function (length, sinAmp, cosAmp, frequency)
|
|
{
|
|
if (sinAmp === undefined) { sinAmp = 1; }
|
|
if (cosAmp === undefined) { cosAmp = 1; }
|
|
if (frequency === undefined) { frequency = 1; }
|
|
|
|
frequency *= Math.PI / length;
|
|
|
|
var cos = [];
|
|
var sin = [];
|
|
|
|
for (var c = 0; c < length; c++)
|
|
{
|
|
cosAmp -= sinAmp * frequency;
|
|
sinAmp += cosAmp * frequency;
|
|
|
|
cos[c] = cosAmp;
|
|
sin[c] = sinAmp;
|
|
}
|
|
|
|
return {
|
|
sin: sin,
|
|
cos: cos,
|
|
length: length
|
|
};
|
|
};
|
|
|
|
module.exports = SinCosTableGenerator;
|
|
|
|
|
|
/***/ }),
|
|
/* 170 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* Returns a Vector2 containing the x and y position of the given index in a `width` x `height` sized grid.
|
|
*
|
|
* For example, in a 6 x 4 grid, index 16 would equal x: 4 y: 2.
|
|
*
|
|
* If the given index is out of range an empty Vector2 is returned.
|
|
*
|
|
* @function Phaser.Math.ToXY
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} index - The position within the grid to get the x/y value for.
|
|
* @param {integer} width - The width of the grid.
|
|
* @param {integer} height - The height of the grid.
|
|
* @param {Phaser.Math.Vector2} [out] - An optional Vector2 to store the result in. If not given, a new Vector2 instance will be created.
|
|
*
|
|
* @return {Phaser.Math.Vector2} A Vector2 where the x and y properties contain the given grid index.
|
|
*/
|
|
var ToXY = function (index, width, height, out)
|
|
{
|
|
if (out === undefined) { out = new Vector2(); }
|
|
|
|
var x = 0;
|
|
var y = 0;
|
|
var total = width * height;
|
|
|
|
if (index > 0 && index <= total)
|
|
{
|
|
if (index > width - 1)
|
|
{
|
|
y = Math.floor(index / width);
|
|
x = index - (y * width);
|
|
}
|
|
else
|
|
{
|
|
x = index;
|
|
}
|
|
|
|
out.set(x, y);
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = ToXY;
|
|
|
|
|
|
/***/ }),
|
|
/* 171 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Checks if the two values are within the given `tolerance` of each other.
|
|
*
|
|
* @function Phaser.Math.Within
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} a - The first value to use in the calculation.
|
|
* @param {number} b - The second value to use in the calculation.
|
|
* @param {number} tolerance - The tolerance. Anything equal to or less than this value is considered as being within range.
|
|
*
|
|
* @return {boolean} Returns `true` if `a` is less than or equal to the tolerance of `b`.
|
|
*/
|
|
var Within = function (a, b, tolerance)
|
|
{
|
|
return (Math.abs(a - b) <= tolerance);
|
|
};
|
|
|
|
module.exports = Within;
|
|
|
|
|
|
/***/ }),
|
|
/* 172 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
|
|
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A representation of a vector in 4D space.
|
|
*
|
|
* A four-component vector.
|
|
*
|
|
* @class Vector4
|
|
* @memberof Phaser.Math
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x] - The x component.
|
|
* @param {number} [y] - The y component.
|
|
* @param {number} [z] - The z component.
|
|
* @param {number} [w] - The w component.
|
|
*/
|
|
var Vector4 = new Class({
|
|
|
|
initialize:
|
|
|
|
function Vector4 (x, y, z, w)
|
|
{
|
|
/**
|
|
* The x component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector4#x
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.x = 0;
|
|
|
|
/**
|
|
* The y component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector4#y
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.y = 0;
|
|
|
|
/**
|
|
* The z component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector4#z
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.z = 0;
|
|
|
|
/**
|
|
* The w component of this Vector.
|
|
*
|
|
* @name Phaser.Math.Vector4#w
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
this.w = 0;
|
|
|
|
if (typeof x === 'object')
|
|
{
|
|
this.x = x.x || 0;
|
|
this.y = x.y || 0;
|
|
this.z = x.z || 0;
|
|
this.w = x.w || 0;
|
|
}
|
|
else
|
|
{
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
this.w = w || 0;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Make a clone of this Vector4.
|
|
*
|
|
* @method Phaser.Math.Vector4#clone
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector4} A clone of this Vector4.
|
|
*/
|
|
clone: function ()
|
|
{
|
|
return new Vector4(this.x, this.y, this.z, this.w);
|
|
},
|
|
|
|
/**
|
|
* Copy the components of a given Vector into this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#copy
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} src - The Vector to copy the components from.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
copy: function (src)
|
|
{
|
|
this.x = src.x;
|
|
this.y = src.y;
|
|
this.z = src.z || 0;
|
|
this.w = src.w || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Check whether this Vector is equal to a given Vector.
|
|
*
|
|
* Performs a strict quality check against each Vector's components.
|
|
*
|
|
* @method Phaser.Math.Vector4#equals
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} v - The vector to check equality with.
|
|
*
|
|
* @return {boolean} A boolean indicating whether the two Vectors are equal or not.
|
|
*/
|
|
equals: function (v)
|
|
{
|
|
return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z) && (this.w === v.w));
|
|
},
|
|
|
|
/**
|
|
* Set the `x`, `y`, `z` and `w` components of the this Vector to the given `x`, `y`, `z` and `w` values.
|
|
*
|
|
* @method Phaser.Math.Vector4#set
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y, z and w components.
|
|
* @param {number} y - The y value to set for this Vector.
|
|
* @param {number} z - The z value to set for this Vector.
|
|
* @param {number} w - The z value to set for this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
set: function (x, y, z, w)
|
|
{
|
|
if (typeof x === 'object')
|
|
{
|
|
this.x = x.x || 0;
|
|
this.y = x.y || 0;
|
|
this.z = x.z || 0;
|
|
this.w = x.w || 0;
|
|
}
|
|
else
|
|
{
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
this.w = w || 0;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Add a given Vector to this Vector. Addition is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector4#add
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to add to this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
add: function (v)
|
|
{
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z || 0;
|
|
this.w += v.w || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Subtract the given Vector from this Vector. Subtraction is component-wise.
|
|
*
|
|
* @method Phaser.Math.Vector4#subtract
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to subtract from this Vector.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
subtract: function (v)
|
|
{
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
this.z -= v.z || 0;
|
|
this.w -= v.w || 0;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Scale this Vector by the given value.
|
|
*
|
|
* @method Phaser.Math.Vector4#scale
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} scale - The value to scale this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
scale: function (scale)
|
|
{
|
|
this.x *= scale;
|
|
this.y *= scale;
|
|
this.z *= scale;
|
|
this.w *= scale;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the length (or magnitude) of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#length
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector.
|
|
*/
|
|
length: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
|
|
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
},
|
|
|
|
/**
|
|
* Calculate the length of this Vector squared.
|
|
*
|
|
* @method Phaser.Math.Vector4#lengthSq
|
|
* @since 3.0.0
|
|
*
|
|
* @return {number} The length of this Vector, squared.
|
|
*/
|
|
lengthSq: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
|
|
return x * x + y * y + z * z + w * w;
|
|
},
|
|
|
|
/**
|
|
* Normalize this Vector.
|
|
*
|
|
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
|
|
*
|
|
* @method Phaser.Math.Vector4#normalize
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
normalize: function ()
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
var len = x * x + y * y + z * z + w * w;
|
|
|
|
if (len > 0)
|
|
{
|
|
len = 1 / Math.sqrt(len);
|
|
|
|
this.x = x * len;
|
|
this.y = y * len;
|
|
this.z = z * len;
|
|
this.w = w * len;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the dot product of this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#dot
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} v - The Vector4 to dot product with this Vector4.
|
|
*
|
|
* @return {number} The dot product of this Vector and the given Vector.
|
|
*/
|
|
dot: function (v)
|
|
{
|
|
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
|
|
},
|
|
|
|
/**
|
|
* Linearly interpolate between this Vector and the given Vector.
|
|
*
|
|
* Interpolates this Vector towards the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#lerp
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector4} v - The Vector4 to interpolate towards.
|
|
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
lerp: function (v, t)
|
|
{
|
|
if (t === undefined) { t = 0; }
|
|
|
|
var ax = this.x;
|
|
var ay = this.y;
|
|
var az = this.z;
|
|
var aw = this.w;
|
|
|
|
this.x = ax + t * (v.x - ax);
|
|
this.y = ay + t * (v.y - ay);
|
|
this.z = az + t * (v.z - az);
|
|
this.w = aw + t * (v.w - aw);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise multiplication between this Vector and the given Vector.
|
|
*
|
|
* Multiplies this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#multiply
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to multiply this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
multiply: function (v)
|
|
{
|
|
this.x *= v.x;
|
|
this.y *= v.y;
|
|
this.z *= v.z || 1;
|
|
this.w *= v.w || 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Perform a component-wise division between this Vector and the given Vector.
|
|
*
|
|
* Divides this Vector by the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#divide
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to divide this Vector by.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
divide: function (v)
|
|
{
|
|
this.x /= v.x;
|
|
this.y /= v.y;
|
|
this.z /= v.z || 1;
|
|
this.w /= v.w || 1;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#distance
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector.
|
|
*/
|
|
distance: function (v)
|
|
{
|
|
var dx = v.x - this.x;
|
|
var dy = v.y - this.y;
|
|
var dz = v.z - this.z || 0;
|
|
var dw = v.w - this.w || 0;
|
|
|
|
return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
|
|
},
|
|
|
|
/**
|
|
* Calculate the distance between this Vector and the given Vector, squared.
|
|
*
|
|
* @method Phaser.Math.Vector4#distanceSq
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
|
|
*
|
|
* @return {number} The distance from this Vector to the given Vector, squared.
|
|
*/
|
|
distanceSq: function (v)
|
|
{
|
|
var dx = v.x - this.x;
|
|
var dy = v.y - this.y;
|
|
var dz = v.z - this.z || 0;
|
|
var dw = v.w - this.w || 0;
|
|
|
|
return dx * dx + dy * dy + dz * dz + dw * dw;
|
|
},
|
|
|
|
/**
|
|
* Negate the `x`, `y`, `z` and `w` components of this Vector.
|
|
*
|
|
* @method Phaser.Math.Vector4#negate
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
negate: function ()
|
|
{
|
|
this.x = -this.x;
|
|
this.y = -this.y;
|
|
this.z = -this.z;
|
|
this.w = -this.w;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Matrix.
|
|
*
|
|
* @method Phaser.Math.Vector4#transformMat4
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector4 with.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
transformMat4: function (mat)
|
|
{
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var w = this.w;
|
|
var m = mat.val;
|
|
|
|
this.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
this.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
this.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
this.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Transform this Vector with the given Quaternion.
|
|
*
|
|
* @method Phaser.Math.Vector4#transformQuat
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
transformQuat: function (q)
|
|
{
|
|
// TODO: is this really the same as Vector3?
|
|
// Also, what about this: http://molecularmusings.wordpress.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
|
// benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
|
|
var x = this.x;
|
|
var y = this.y;
|
|
var z = this.z;
|
|
var qx = q.x;
|
|
var qy = q.y;
|
|
var qz = q.z;
|
|
var qw = q.w;
|
|
|
|
// calculate quat * vec
|
|
var ix = qw * x + qy * z - qz * y;
|
|
var iy = qw * y + qz * x - qx * z;
|
|
var iz = qw * z + qx * y - qy * x;
|
|
var iw = -qx * x - qy * y - qz * z;
|
|
|
|
// calculate result * inverse quat
|
|
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
|
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
|
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Make this Vector the zero vector (0, 0, 0, 0).
|
|
*
|
|
* @method Phaser.Math.Vector4#reset
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Math.Vector4} This Vector4.
|
|
*/
|
|
reset: function ()
|
|
{
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
this.w = 0;
|
|
|
|
return this;
|
|
}
|
|
|
|
});
|
|
|
|
// TODO: Check if these are required internally, if not, remove.
|
|
Vector4.prototype.sub = Vector4.prototype.subtract;
|
|
Vector4.prototype.mul = Vector4.prototype.multiply;
|
|
Vector4.prototype.div = Vector4.prototype.divide;
|
|
Vector4.prototype.dist = Vector4.prototype.distance;
|
|
Vector4.prototype.distSq = Vector4.prototype.distanceSq;
|
|
Vector4.prototype.len = Vector4.prototype.length;
|
|
Vector4.prototype.lenSq = Vector4.prototype.lengthSq;
|
|
|
|
module.exports = Vector4;
|
|
|
|
|
|
/***/ }),
|
|
/* 173 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Vector3 = __webpack_require__(13);
|
|
var Matrix4 = __webpack_require__(20);
|
|
var Quaternion = __webpack_require__(43);
|
|
|
|
var tmpMat4 = new Matrix4();
|
|
var tmpQuat = new Quaternion();
|
|
var tmpVec3 = new Vector3();
|
|
|
|
/**
|
|
* Rotates a vector in place by axis angle.
|
|
*
|
|
* This is the same as transforming a point by an
|
|
* axis-angle quaternion, but it has higher precision.
|
|
*
|
|
* @function Phaser.Math.RotateVec3
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Math.Vector3} vec - The vector to be rotated.
|
|
* @param {Phaser.Math.Vector3} axis - The axis to rotate around.
|
|
* @param {number} radians - The angle of rotation in radians.
|
|
*
|
|
* @return {Phaser.Math.Vector3} The given vector.
|
|
*/
|
|
var RotateVec3 = function (vec, axis, radians)
|
|
{
|
|
// Set the quaternion to our axis angle
|
|
tmpQuat.setAxisAngle(axis, radians);
|
|
|
|
// Create a rotation matrix from the axis angle
|
|
tmpMat4.fromRotationTranslation(tmpQuat, tmpVec3.set(0, 0, 0));
|
|
|
|
// Multiply our vector by the rotation matrix
|
|
return vec.transformMat4(tmpMat4);
|
|
};
|
|
|
|
module.exports = RotateVec3;
|
|
|
|
|
|
/***/ }),
|
|
/* 174 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scale Manager Resize Event.
|
|
*
|
|
* This event is dispatched whenever the Scale Manager detects a resize event from the browser.
|
|
* It sends three parameters to the callback, each of them being Size components. You can read
|
|
* the `width`, `height`, `aspectRatio` and other properties of these components to help with
|
|
* scaling your own game content.
|
|
*
|
|
* @event Phaser.Scale.Events#RESIZE
|
|
* @since 3.16.1
|
|
*
|
|
* @param {Phaser.Structs.Size} gameSize - A reference to the Game Size component. This is the un-scaled size of your game canvas.
|
|
* @param {Phaser.Structs.Size} baseSize - A reference to the Base Size component. This is the game size.
|
|
* @param {Phaser.Structs.Size} displaySize - A reference to the Display Size component. This is the scaled canvas size, after applying zoom and scale mode.
|
|
* @param {number} previousWidth - If the `gameSize` has changed, this value contains its previous width, otherwise it contains the current width.
|
|
* @param {number} previousHeight - If the `gameSize` has changed, this value contains its previous height, otherwise it contains the current height.
|
|
*/
|
|
module.exports = 'resize';
|
|
|
|
|
|
/***/ }),
|
|
/* 175 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
|
|
*/
|
|
|
|
var BasePlugin = __webpack_require__(176);
|
|
var Class = __webpack_require__(0);
|
|
var SceneEvents = __webpack_require__(177);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Scene Level Plugin is installed into every Scene and belongs to that Scene.
|
|
* It can listen for Scene events and respond to them.
|
|
* It can map itself to a Scene property, or into the Scene Systems, or both.
|
|
*
|
|
* @class ScenePlugin
|
|
* @memberof Phaser.Plugins
|
|
* @extends Phaser.Plugins.BasePlugin
|
|
* @constructor
|
|
* @since 3.8.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
|
|
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager.
|
|
*/
|
|
var ScenePlugin = new Class({
|
|
|
|
Extends: BasePlugin,
|
|
|
|
initialize:
|
|
|
|
function ScenePlugin (scene, pluginManager)
|
|
{
|
|
BasePlugin.call(this, pluginManager);
|
|
|
|
/**
|
|
* A reference to the Scene that has installed this plugin.
|
|
* Only set if it's a Scene Plugin, otherwise `null`.
|
|
* This property is only set when the plugin is instantiated and added to the Scene, not before.
|
|
* You can use it during the `boot` method.
|
|
*
|
|
* @name Phaser.Plugins.ScenePlugin#scene
|
|
* @type {?Phaser.Scene}
|
|
* @protected
|
|
* @since 3.8.0
|
|
*/
|
|
this.scene = scene;
|
|
|
|
/**
|
|
* A reference to the Scene Systems of the Scene that has installed this plugin.
|
|
* Only set if it's a Scene Plugin, otherwise `null`.
|
|
* This property is only set when the plugin is instantiated and added to the Scene, not before.
|
|
* You can use it during the `boot` method.
|
|
*
|
|
* @name Phaser.Plugins.ScenePlugin#systems
|
|
* @type {?Phaser.Scenes.Systems}
|
|
* @protected
|
|
* @since 3.8.0
|
|
*/
|
|
this.systems = scene.sys;
|
|
|
|
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
|
|
},
|
|
|
|
/**
|
|
* This method is called when the Scene boots. It is only ever called once.
|
|
*
|
|
* By this point the plugin properties `scene` and `systems` will have already been set.
|
|
*
|
|
* In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run.
|
|
* Here are the Scene events you can listen to:
|
|
*
|
|
* - start
|
|
* - ready
|
|
* - preupdate
|
|
* - update
|
|
* - postupdate
|
|
* - resize
|
|
* - pause
|
|
* - resume
|
|
* - sleep
|
|
* - wake
|
|
* - transitioninit
|
|
* - transitionstart
|
|
* - transitioncomplete
|
|
* - transitionout
|
|
* - shutdown
|
|
* - destroy
|
|
*
|
|
* At the very least you should offer a destroy handler for when the Scene closes down, i.e:
|
|
*
|
|
* ```javascript
|
|
* var eventEmitter = this.systems.events;
|
|
* eventEmitter.once('destroy', this.sceneDestroy, this);
|
|
* ```
|
|
*
|
|
* @method Phaser.Plugins.ScenePlugin#boot
|
|
* @since 3.8.0
|
|
*/
|
|
boot: function ()
|
|
{
|
|
},
|
|
|
|
/**
|
|
* Game instance has been destroyed.
|
|
*
|
|
* You must release everything in here, all references, all objects, free it all up.
|
|
*
|
|
* @method Phaser.Plugins.ScenePlugin#destroy
|
|
* @since 3.8.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.pluginManager = null;
|
|
this.game = null;
|
|
this.scene = null;
|
|
this.systems = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = ScenePlugin;
|
|
|
|
|
|
/***/ }),
|
|
/* 176 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Global Plugin is installed just once into the Game owned Plugin Manager.
|
|
* It can listen for Game events and respond to them.
|
|
*
|
|
* @class BasePlugin
|
|
* @memberof Phaser.Plugins
|
|
* @constructor
|
|
* @since 3.8.0
|
|
*
|
|
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager.
|
|
*/
|
|
var BasePlugin = new Class({
|
|
|
|
initialize:
|
|
|
|
function BasePlugin (pluginManager)
|
|
{
|
|
/**
|
|
* A handy reference to the Plugin Manager that is responsible for this plugin.
|
|
* Can be used as a route to gain access to game systems and events.
|
|
*
|
|
* @name Phaser.Plugins.BasePlugin#pluginManager
|
|
* @type {Phaser.Plugins.PluginManager}
|
|
* @protected
|
|
* @since 3.8.0
|
|
*/
|
|
this.pluginManager = pluginManager;
|
|
|
|
/**
|
|
* A reference to the Game instance this plugin is running under.
|
|
*
|
|
* @name Phaser.Plugins.BasePlugin#game
|
|
* @type {Phaser.Game}
|
|
* @protected
|
|
* @since 3.8.0
|
|
*/
|
|
this.game = pluginManager.game;
|
|
},
|
|
|
|
/**
|
|
* The PluginManager calls this method on a Global Plugin when the plugin is first instantiated.
|
|
* It will never be called again on this instance.
|
|
* In here you can set-up whatever you need for this plugin to run.
|
|
* If a plugin is set to automatically start then `BasePlugin.start` will be called immediately after this.
|
|
* On a Scene Plugin, this method is never called. Use {@link Phaser.Plugins.ScenePlugin#boot} instead.
|
|
*
|
|
* @method Phaser.Plugins.BasePlugin#init
|
|
* @since 3.8.0
|
|
*
|
|
* @param {?any} [data] - A value specified by the user, if any, from the `data` property of the plugin's configuration object (if started at game boot) or passed in the PluginManager's `install` method (if started manually).
|
|
*/
|
|
init: function ()
|
|
{
|
|
},
|
|
|
|
/**
|
|
* The PluginManager calls this method on a Global Plugin when the plugin is started.
|
|
* If a plugin is stopped, and then started again, this will get called again.
|
|
* Typically called immediately after `BasePlugin.init`.
|
|
* On a Scene Plugin, this method is never called.
|
|
*
|
|
* @method Phaser.Plugins.BasePlugin#start
|
|
* @since 3.8.0
|
|
*/
|
|
start: function ()
|
|
{
|
|
// Here are the game-level events you can listen to.
|
|
// At the very least you should offer a destroy handler for when the game closes down.
|
|
|
|
// var eventEmitter = this.game.events;
|
|
|
|
// eventEmitter.once('destroy', this.gameDestroy, this);
|
|
// eventEmitter.on('pause', this.gamePause, this);
|
|
// eventEmitter.on('resume', this.gameResume, this);
|
|
// eventEmitter.on('resize', this.gameResize, this);
|
|
// eventEmitter.on('prestep', this.gamePreStep, this);
|
|
// eventEmitter.on('step', this.gameStep, this);
|
|
// eventEmitter.on('poststep', this.gamePostStep, this);
|
|
// eventEmitter.on('prerender', this.gamePreRender, this);
|
|
// eventEmitter.on('postrender', this.gamePostRender, this);
|
|
},
|
|
|
|
/**
|
|
* The PluginManager calls this method on a Global Plugin when the plugin is stopped.
|
|
* The game code has requested that your plugin stop doing whatever it does.
|
|
* It is now considered as 'inactive' by the PluginManager.
|
|
* Handle that process here (i.e. stop listening for events, etc)
|
|
* If the plugin is started again then `BasePlugin.start` will be called again.
|
|
* On a Scene Plugin, this method is never called.
|
|
*
|
|
* @method Phaser.Plugins.BasePlugin#stop
|
|
* @since 3.8.0
|
|
*/
|
|
stop: function ()
|
|
{
|
|
},
|
|
|
|
/**
|
|
* Game instance has been destroyed.
|
|
* You must release everything in here, all references, all objects, free it all up.
|
|
*
|
|
* @method Phaser.Plugins.BasePlugin#destroy
|
|
* @since 3.8.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.pluginManager = null;
|
|
this.game = null;
|
|
this.scene = null;
|
|
this.systems = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = BasePlugin;
|
|
|
|
|
|
/***/ }),
|
|
/* 177 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Scenes.Events
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
ADDED_TO_SCENE: __webpack_require__(178),
|
|
BOOT: __webpack_require__(179),
|
|
CREATE: __webpack_require__(180),
|
|
DESTROY: __webpack_require__(181),
|
|
PAUSE: __webpack_require__(182),
|
|
POST_UPDATE: __webpack_require__(183),
|
|
PRE_UPDATE: __webpack_require__(184),
|
|
READY: __webpack_require__(185),
|
|
REMOVED_FROM_SCENE: __webpack_require__(186),
|
|
RENDER: __webpack_require__(187),
|
|
RESUME: __webpack_require__(188),
|
|
SHUTDOWN: __webpack_require__(189),
|
|
SLEEP: __webpack_require__(190),
|
|
START: __webpack_require__(191),
|
|
TRANSITION_COMPLETE: __webpack_require__(192),
|
|
TRANSITION_INIT: __webpack_require__(193),
|
|
TRANSITION_OUT: __webpack_require__(194),
|
|
TRANSITION_START: __webpack_require__(195),
|
|
TRANSITION_WAKE: __webpack_require__(196),
|
|
UPDATE: __webpack_require__(197),
|
|
WAKE: __webpack_require__(198)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 178 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Object Added to Scene Event.
|
|
*
|
|
* This event is dispatched when a Game Object is added to a Scene.
|
|
*
|
|
* Listen for it from a Scene using `this.scene.events.on('addedtoscene', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#ADDED_TO_SCENE
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene.
|
|
* @param {Phaser.Scene} scene - The Scene to which the Game Object was added.
|
|
*/
|
|
module.exports = 'addedtoscene';
|
|
|
|
|
|
/***/ }),
|
|
/* 179 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Boot Event.
|
|
*
|
|
* This event is dispatched by a Scene during the Scene Systems boot process. Primarily used by Scene Plugins.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('boot', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#BOOT
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
*/
|
|
module.exports = 'boot';
|
|
|
|
|
|
/***/ }),
|
|
/* 180 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Create Event.
|
|
*
|
|
* This event is dispatched by a Scene after it has been created by the Scene Manager.
|
|
*
|
|
* If a Scene has a `create` method then this event is emitted _after_ that has run.
|
|
*
|
|
* If there is a transition, this event will be fired after the `TRANSITION_START` event.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('create', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#CREATE
|
|
* @since 3.17.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that emitted this event.
|
|
*/
|
|
module.exports = 'create';
|
|
|
|
|
|
/***/ }),
|
|
/* 181 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Destroy Event.
|
|
*
|
|
* This event is dispatched by a Scene during the Scene Systems destroy process.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('destroy', listener)`.
|
|
*
|
|
* You should destroy any resources that may be in use by your Scene in this event handler.
|
|
*
|
|
* @event Phaser.Scenes.Events#DESTROY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
*/
|
|
module.exports = 'destroy';
|
|
|
|
|
|
/***/ }),
|
|
/* 182 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Pause Event.
|
|
*
|
|
* This event is dispatched by a Scene when it is paused, either directly via the `pause` method, or as an
|
|
* action from another Scene.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('pause', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#PAUSE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was paused.
|
|
*/
|
|
module.exports = 'pause';
|
|
|
|
|
|
/***/ }),
|
|
/* 183 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Post Update Event.
|
|
*
|
|
* This event is dispatched by a Scene during the main game loop step.
|
|
*
|
|
* The event flow for a single step of a Scene is as follows:
|
|
*
|
|
* 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
|
|
* 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
|
|
* 3. The `Scene.update` method is called, if it exists
|
|
* 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
|
|
* 5. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('postupdate', listener)`.
|
|
*
|
|
* A Scene will only run its step if it is active.
|
|
*
|
|
* @event Phaser.Scenes.Events#POST_UPDATE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'postupdate';
|
|
|
|
|
|
/***/ }),
|
|
/* 184 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Pre Update Event.
|
|
*
|
|
* This event is dispatched by a Scene during the main game loop step.
|
|
*
|
|
* The event flow for a single step of a Scene is as follows:
|
|
*
|
|
* 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
|
|
* 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
|
|
* 3. The `Scene.update` method is called, if it exists
|
|
* 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
|
|
* 5. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('preupdate', listener)`.
|
|
*
|
|
* A Scene will only run its step if it is active.
|
|
*
|
|
* @event Phaser.Scenes.Events#PRE_UPDATE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'preupdate';
|
|
|
|
|
|
/***/ }),
|
|
/* 185 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Ready Event.
|
|
*
|
|
* This event is dispatched by a Scene during the Scene Systems start process.
|
|
* By this point in the process the Scene is now fully active and rendering.
|
|
* This event is meant for your game code to use, as all plugins have responded to the earlier 'start' event.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('ready', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#READY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was started.
|
|
*/
|
|
module.exports = 'ready';
|
|
|
|
|
|
/***/ }),
|
|
/* 186 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Object Removed from Scene Event.
|
|
*
|
|
* This event is dispatched when a Game Object is removed from a Scene.
|
|
*
|
|
* Listen for it from a Scene using `this.scene.events.on('removedfromscene', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#REMOVED_FROM_SCENE
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene.
|
|
* @param {Phaser.Scene} scene - The Scene from which the Game Object was removed.
|
|
*/
|
|
module.exports = 'removedfromscene';
|
|
|
|
|
|
/***/ }),
|
|
/* 187 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Render Event.
|
|
*
|
|
* This event is dispatched by a Scene during the main game loop step.
|
|
*
|
|
* The event flow for a single step of a Scene is as follows:
|
|
*
|
|
* 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
|
|
* 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
|
|
* 3. The `Scene.update` method is called, if it exists
|
|
* 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
|
|
* 5. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('render', listener)`.
|
|
*
|
|
* A Scene will only render if it is visible and active.
|
|
* By the time this event is dispatched, the Scene will have already been rendered.
|
|
*
|
|
* @event Phaser.Scenes.Events#RENDER
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene.
|
|
*/
|
|
module.exports = 'render';
|
|
|
|
|
|
/***/ }),
|
|
/* 188 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Resume Event.
|
|
*
|
|
* This event is dispatched by a Scene when it is resumed from a paused state, either directly via the `resume` method,
|
|
* or as an action from another Scene.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('resume', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#RESUME
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was resumed.
|
|
*/
|
|
module.exports = 'resume';
|
|
|
|
|
|
/***/ }),
|
|
/* 189 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Shutdown Event.
|
|
*
|
|
* This event is dispatched by a Scene during the Scene Systems shutdown process.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('shutdown', listener)`.
|
|
*
|
|
* You should free-up any resources that may be in use by your Scene in this event handler, on the understanding
|
|
* that the Scene may, at any time, become active again. A shutdown Scene is not 'destroyed', it's simply not
|
|
* currently active. Use the [DESTROY]{@linkcode Phaser.Scenes.Events#event:DESTROY} event to completely clear resources.
|
|
*
|
|
* @event Phaser.Scenes.Events#SHUTDOWN
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was shutdown.
|
|
*/
|
|
module.exports = 'shutdown';
|
|
|
|
|
|
/***/ }),
|
|
/* 190 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Sleep Event.
|
|
*
|
|
* This event is dispatched by a Scene when it is sent to sleep, either directly via the `sleep` method,
|
|
* or as an action from another Scene.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('sleep', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#SLEEP
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was sent to sleep.
|
|
*/
|
|
module.exports = 'sleep';
|
|
|
|
|
|
/***/ }),
|
|
/* 191 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Start Event.
|
|
*
|
|
* This event is dispatched by a Scene during the Scene Systems start process. Primarily used by Scene Plugins.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('start', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#START
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
*/
|
|
module.exports = 'start';
|
|
|
|
|
|
/***/ }),
|
|
/* 192 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Transition Complete Event.
|
|
*
|
|
* This event is dispatched by the Target Scene of a transition.
|
|
*
|
|
* It happens when the transition process has completed. This occurs when the duration timer equals or exceeds the duration
|
|
* of the transition.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('transitioncomplete', listener)`.
|
|
*
|
|
* The Scene Transition event flow is as follows:
|
|
*
|
|
* 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
|
|
* 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
|
|
* 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
|
|
* 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
|
|
* 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
|
|
*
|
|
* @event Phaser.Scenes.Events#TRANSITION_COMPLETE
|
|
* @since 3.5.0
|
|
*
|
|
* @param {Phaser.Scene} scene -The Scene on which the transitioned completed.
|
|
*/
|
|
module.exports = 'transitioncomplete';
|
|
|
|
|
|
/***/ }),
|
|
/* 193 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Transition Init Event.
|
|
*
|
|
* This event is dispatched by the Target Scene of a transition.
|
|
*
|
|
* It happens immediately after the `Scene.init` method is called. If the Scene does not have an `init` method,
|
|
* this event is not dispatched.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('transitioninit', listener)`.
|
|
*
|
|
* The Scene Transition event flow is as follows:
|
|
*
|
|
* 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
|
|
* 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
|
|
* 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
|
|
* 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
|
|
* 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
|
|
*
|
|
* @event Phaser.Scenes.Events#TRANSITION_INIT
|
|
* @since 3.5.0
|
|
*
|
|
* @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
|
|
* @param {number} duration - The duration of the transition in ms.
|
|
*/
|
|
module.exports = 'transitioninit';
|
|
|
|
|
|
/***/ }),
|
|
/* 194 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Transition Out Event.
|
|
*
|
|
* This event is dispatched by a Scene when it initiates a transition to another Scene.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('transitionout', listener)`.
|
|
*
|
|
* The Scene Transition event flow is as follows:
|
|
*
|
|
* 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
|
|
* 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
|
|
* 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
|
|
* 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
|
|
* 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
|
|
*
|
|
* @event Phaser.Scenes.Events#TRANSITION_OUT
|
|
* @since 3.5.0
|
|
*
|
|
* @param {Phaser.Scene} target - A reference to the Scene that is being transitioned to.
|
|
* @param {number} duration - The duration of the transition in ms.
|
|
*/
|
|
module.exports = 'transitionout';
|
|
|
|
|
|
/***/ }),
|
|
/* 195 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Transition Start Event.
|
|
*
|
|
* This event is dispatched by the Target Scene of a transition, only if that Scene was not asleep.
|
|
*
|
|
* It happens immediately after the `Scene.create` method is called. If the Scene does not have a `create` method,
|
|
* this event is dispatched anyway.
|
|
*
|
|
* If the Target Scene was sleeping then the [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} event is
|
|
* dispatched instead of this event.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('transitionstart', listener)`.
|
|
*
|
|
* The Scene Transition event flow is as follows:
|
|
*
|
|
* 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
|
|
* 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
|
|
* 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
|
|
* 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
|
|
* 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
|
|
*
|
|
* @event Phaser.Scenes.Events#TRANSITION_START
|
|
* @since 3.5.0
|
|
*
|
|
* @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
|
|
* @param {number} duration - The duration of the transition in ms.
|
|
*/
|
|
module.exports = 'transitionstart';
|
|
|
|
|
|
/***/ }),
|
|
/* 196 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Transition Wake Event.
|
|
*
|
|
* This event is dispatched by the Target Scene of a transition, only if that Scene was asleep before
|
|
* the transition began. If the Scene was not asleep the [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} event is dispatched instead.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('transitionwake', listener)`.
|
|
*
|
|
* The Scene Transition event flow is as follows:
|
|
*
|
|
* 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
|
|
* 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
|
|
* 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
|
|
* 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
|
|
* 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
|
|
*
|
|
* @event Phaser.Scenes.Events#TRANSITION_WAKE
|
|
* @since 3.5.0
|
|
*
|
|
* @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
|
|
* @param {number} duration - The duration of the transition in ms.
|
|
*/
|
|
module.exports = 'transitionwake';
|
|
|
|
|
|
/***/ }),
|
|
/* 197 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Update Event.
|
|
*
|
|
* This event is dispatched by a Scene during the main game loop step.
|
|
*
|
|
* The event flow for a single step of a Scene is as follows:
|
|
*
|
|
* 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
|
|
* 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
|
|
* 3. The `Scene.update` method is called, if it exists
|
|
* 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
|
|
* 5. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('update', listener)`.
|
|
*
|
|
* A Scene will only run its step if it is active.
|
|
*
|
|
* @event Phaser.Scenes.Events#UPDATE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'update';
|
|
|
|
|
|
/***/ }),
|
|
/* 198 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Scene Systems Wake Event.
|
|
*
|
|
* This event is dispatched by a Scene when it is woken from sleep, either directly via the `wake` method,
|
|
* or as an action from another Scene.
|
|
*
|
|
* Listen to it from a Scene using `this.scene.events.on('wake', listener)`.
|
|
*
|
|
* @event Phaser.Scenes.Events#WAKE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
|
|
* @param {any} [data] - An optional data object that was passed to this Scene when it was woken up.
|
|
*/
|
|
module.exports = 'wake';
|
|
|
|
|
|
/***/ }),
|
|
/* 199 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/*** IMPORTS FROM imports-loader ***/
|
|
|
|
(function() {
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
var spine;
|
|
(function (spine) {
|
|
var Animation = (function () {
|
|
function Animation(name, timelines, duration) {
|
|
if (name == null)
|
|
throw new Error("name cannot be null.");
|
|
if (timelines == null)
|
|
throw new Error("timelines cannot be null.");
|
|
this.name = name;
|
|
this.timelines = timelines;
|
|
this.timelineIds = [];
|
|
for (var i = 0; i < timelines.length; i++)
|
|
this.timelineIds[timelines[i].getPropertyId()] = true;
|
|
this.duration = duration;
|
|
}
|
|
Animation.prototype.hasTimeline = function (id) {
|
|
return this.timelineIds[id] == true;
|
|
};
|
|
Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) {
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
if (loop && this.duration != 0) {
|
|
time %= this.duration;
|
|
if (lastTime > 0)
|
|
lastTime %= this.duration;
|
|
}
|
|
var timelines = this.timelines;
|
|
for (var i = 0, n = timelines.length; i < n; i++)
|
|
timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction);
|
|
};
|
|
Animation.binarySearch = function (values, target, step) {
|
|
if (step === void 0) { step = 1; }
|
|
var low = 0;
|
|
var high = values.length / step - 2;
|
|
if (high == 0)
|
|
return step;
|
|
var current = high >>> 1;
|
|
while (true) {
|
|
if (values[(current + 1) * step] <= target)
|
|
low = current + 1;
|
|
else
|
|
high = current;
|
|
if (low == high)
|
|
return (low + 1) * step;
|
|
current = (low + high) >>> 1;
|
|
}
|
|
};
|
|
Animation.linearSearch = function (values, target, step) {
|
|
for (var i = 0, last = values.length - step; i <= last; i += step)
|
|
if (values[i] > target)
|
|
return i;
|
|
return -1;
|
|
};
|
|
return Animation;
|
|
}());
|
|
spine.Animation = Animation;
|
|
var MixBlend;
|
|
(function (MixBlend) {
|
|
MixBlend[MixBlend["setup"] = 0] = "setup";
|
|
MixBlend[MixBlend["first"] = 1] = "first";
|
|
MixBlend[MixBlend["replace"] = 2] = "replace";
|
|
MixBlend[MixBlend["add"] = 3] = "add";
|
|
})(MixBlend = spine.MixBlend || (spine.MixBlend = {}));
|
|
var MixDirection;
|
|
(function (MixDirection) {
|
|
MixDirection[MixDirection["mixIn"] = 0] = "mixIn";
|
|
MixDirection[MixDirection["mixOut"] = 1] = "mixOut";
|
|
})(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
|
|
var TimelineType;
|
|
(function (TimelineType) {
|
|
TimelineType[TimelineType["rotate"] = 0] = "rotate";
|
|
TimelineType[TimelineType["translate"] = 1] = "translate";
|
|
TimelineType[TimelineType["scale"] = 2] = "scale";
|
|
TimelineType[TimelineType["shear"] = 3] = "shear";
|
|
TimelineType[TimelineType["attachment"] = 4] = "attachment";
|
|
TimelineType[TimelineType["color"] = 5] = "color";
|
|
TimelineType[TimelineType["deform"] = 6] = "deform";
|
|
TimelineType[TimelineType["event"] = 7] = "event";
|
|
TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder";
|
|
TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint";
|
|
TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint";
|
|
TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition";
|
|
TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing";
|
|
TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix";
|
|
TimelineType[TimelineType["twoColor"] = 14] = "twoColor";
|
|
})(TimelineType = spine.TimelineType || (spine.TimelineType = {}));
|
|
var CurveTimeline = (function () {
|
|
function CurveTimeline(frameCount) {
|
|
if (frameCount <= 0)
|
|
throw new Error("frameCount must be > 0: " + frameCount);
|
|
this.curves = spine.Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
|
|
}
|
|
CurveTimeline.prototype.getFrameCount = function () {
|
|
return this.curves.length / CurveTimeline.BEZIER_SIZE + 1;
|
|
};
|
|
CurveTimeline.prototype.setLinear = function (frameIndex) {
|
|
this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR;
|
|
};
|
|
CurveTimeline.prototype.setStepped = function (frameIndex) {
|
|
this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED;
|
|
};
|
|
CurveTimeline.prototype.getCurveType = function (frameIndex) {
|
|
var index = frameIndex * CurveTimeline.BEZIER_SIZE;
|
|
if (index == this.curves.length)
|
|
return CurveTimeline.LINEAR;
|
|
var type = this.curves[index];
|
|
if (type == CurveTimeline.LINEAR)
|
|
return CurveTimeline.LINEAR;
|
|
if (type == CurveTimeline.STEPPED)
|
|
return CurveTimeline.STEPPED;
|
|
return CurveTimeline.BEZIER;
|
|
};
|
|
CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) {
|
|
var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03;
|
|
var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006;
|
|
var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
|
|
var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667;
|
|
var i = frameIndex * CurveTimeline.BEZIER_SIZE;
|
|
var curves = this.curves;
|
|
curves[i++] = CurveTimeline.BEZIER;
|
|
var x = dfx, y = dfy;
|
|
for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
|
|
curves[i] = x;
|
|
curves[i + 1] = y;
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
ddfx += dddfx;
|
|
ddfy += dddfy;
|
|
x += dfx;
|
|
y += dfy;
|
|
}
|
|
};
|
|
CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) {
|
|
percent = spine.MathUtils.clamp(percent, 0, 1);
|
|
var curves = this.curves;
|
|
var i = frameIndex * CurveTimeline.BEZIER_SIZE;
|
|
var type = curves[i];
|
|
if (type == CurveTimeline.LINEAR)
|
|
return percent;
|
|
if (type == CurveTimeline.STEPPED)
|
|
return 0;
|
|
i++;
|
|
var x = 0;
|
|
for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
|
|
x = curves[i];
|
|
if (x >= percent) {
|
|
var prevX = void 0, prevY = void 0;
|
|
if (i == start) {
|
|
prevX = 0;
|
|
prevY = 0;
|
|
}
|
|
else {
|
|
prevX = curves[i - 2];
|
|
prevY = curves[i - 1];
|
|
}
|
|
return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
|
|
}
|
|
}
|
|
var y = curves[i - 1];
|
|
return y + (1 - y) * (percent - x) / (1 - x);
|
|
};
|
|
CurveTimeline.LINEAR = 0;
|
|
CurveTimeline.STEPPED = 1;
|
|
CurveTimeline.BEZIER = 2;
|
|
CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
|
|
return CurveTimeline;
|
|
}());
|
|
spine.CurveTimeline = CurveTimeline;
|
|
var RotateTimeline = (function (_super) {
|
|
__extends(RotateTimeline, _super);
|
|
function RotateTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount << 1);
|
|
return _this;
|
|
}
|
|
RotateTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.rotate << 24) + this.boneIndex;
|
|
};
|
|
RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) {
|
|
frameIndex <<= 1;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
|
|
};
|
|
RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var bone = skeleton.bones[this.boneIndex];
|
|
if (!bone.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.rotation = bone.data.rotation;
|
|
return;
|
|
case MixBlend.first:
|
|
var r_1 = bone.data.rotation - bone.rotation;
|
|
bone.rotation += (r_1 - (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) {
|
|
var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION];
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.rotation = bone.data.rotation + r_2 * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
r_2 += bone.data.rotation - bone.rotation;
|
|
r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
|
|
case MixBlend.add:
|
|
bone.rotation += r_2 * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES);
|
|
var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
|
|
var r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
|
|
r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent;
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
r += bone.data.rotation - bone.rotation;
|
|
case MixBlend.add:
|
|
bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
|
|
}
|
|
};
|
|
RotateTimeline.ENTRIES = 2;
|
|
RotateTimeline.PREV_TIME = -2;
|
|
RotateTimeline.PREV_ROTATION = -1;
|
|
RotateTimeline.ROTATION = 1;
|
|
return RotateTimeline;
|
|
}(CurveTimeline));
|
|
spine.RotateTimeline = RotateTimeline;
|
|
var TranslateTimeline = (function (_super) {
|
|
__extends(TranslateTimeline, _super);
|
|
function TranslateTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
TranslateTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.translate << 24) + this.boneIndex;
|
|
};
|
|
TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) {
|
|
frameIndex *= TranslateTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + TranslateTimeline.X] = x;
|
|
this.frames[frameIndex + TranslateTimeline.Y] = y;
|
|
};
|
|
TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var bone = skeleton.bones[this.boneIndex];
|
|
if (!bone.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.x = bone.data.x;
|
|
bone.y = bone.data.y;
|
|
return;
|
|
case MixBlend.first:
|
|
bone.x += (bone.data.x - bone.x) * alpha;
|
|
bone.y += (bone.data.y - bone.y) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var x = 0, y = 0;
|
|
if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) {
|
|
x = frames[frames.length + TranslateTimeline.PREV_X];
|
|
y = frames[frames.length + TranslateTimeline.PREV_Y];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES);
|
|
x = frames[frame + TranslateTimeline.PREV_X];
|
|
y = frames[frame + TranslateTimeline.PREV_Y];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime));
|
|
x += (frames[frame + TranslateTimeline.X] - x) * percent;
|
|
y += (frames[frame + TranslateTimeline.Y] - y) * percent;
|
|
}
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.x = bone.data.x + x * alpha;
|
|
bone.y = bone.data.y + y * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
bone.x += (bone.data.x + x - bone.x) * alpha;
|
|
bone.y += (bone.data.y + y - bone.y) * alpha;
|
|
break;
|
|
case MixBlend.add:
|
|
bone.x += x * alpha;
|
|
bone.y += y * alpha;
|
|
}
|
|
};
|
|
TranslateTimeline.ENTRIES = 3;
|
|
TranslateTimeline.PREV_TIME = -3;
|
|
TranslateTimeline.PREV_X = -2;
|
|
TranslateTimeline.PREV_Y = -1;
|
|
TranslateTimeline.X = 1;
|
|
TranslateTimeline.Y = 2;
|
|
return TranslateTimeline;
|
|
}(CurveTimeline));
|
|
spine.TranslateTimeline = TranslateTimeline;
|
|
var ScaleTimeline = (function (_super) {
|
|
__extends(ScaleTimeline, _super);
|
|
function ScaleTimeline(frameCount) {
|
|
return _super.call(this, frameCount) || this;
|
|
}
|
|
ScaleTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.scale << 24) + this.boneIndex;
|
|
};
|
|
ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var bone = skeleton.bones[this.boneIndex];
|
|
if (!bone.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.scaleX = bone.data.scaleX;
|
|
bone.scaleY = bone.data.scaleY;
|
|
return;
|
|
case MixBlend.first:
|
|
bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
|
|
bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var x = 0, y = 0;
|
|
if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) {
|
|
x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX;
|
|
y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY;
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES);
|
|
x = frames[frame + ScaleTimeline.PREV_X];
|
|
y = frames[frame + ScaleTimeline.PREV_Y];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime));
|
|
x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX;
|
|
y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY;
|
|
}
|
|
if (alpha == 1) {
|
|
if (blend == MixBlend.add) {
|
|
bone.scaleX += x - bone.data.scaleX;
|
|
bone.scaleY += y - bone.data.scaleY;
|
|
}
|
|
else {
|
|
bone.scaleX = x;
|
|
bone.scaleY = y;
|
|
}
|
|
}
|
|
else {
|
|
var bx = 0, by = 0;
|
|
if (direction == MixDirection.mixOut) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bx = bone.data.scaleX;
|
|
by = bone.data.scaleY;
|
|
bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha;
|
|
bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
bx = bone.scaleX;
|
|
by = bone.scaleY;
|
|
bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha;
|
|
bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha;
|
|
break;
|
|
case MixBlend.add:
|
|
bx = bone.scaleX;
|
|
by = bone.scaleY;
|
|
bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bone.data.scaleX) * alpha;
|
|
bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - bone.data.scaleY) * alpha;
|
|
}
|
|
}
|
|
else {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bx = Math.abs(bone.data.scaleX) * spine.MathUtils.signum(x);
|
|
by = Math.abs(bone.data.scaleY) * spine.MathUtils.signum(y);
|
|
bone.scaleX = bx + (x - bx) * alpha;
|
|
bone.scaleY = by + (y - by) * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
bx = Math.abs(bone.scaleX) * spine.MathUtils.signum(x);
|
|
by = Math.abs(bone.scaleY) * spine.MathUtils.signum(y);
|
|
bone.scaleX = bx + (x - bx) * alpha;
|
|
bone.scaleY = by + (y - by) * alpha;
|
|
break;
|
|
case MixBlend.add:
|
|
bx = spine.MathUtils.signum(x);
|
|
by = spine.MathUtils.signum(y);
|
|
bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha;
|
|
bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
return ScaleTimeline;
|
|
}(TranslateTimeline));
|
|
spine.ScaleTimeline = ScaleTimeline;
|
|
var ShearTimeline = (function (_super) {
|
|
__extends(ShearTimeline, _super);
|
|
function ShearTimeline(frameCount) {
|
|
return _super.call(this, frameCount) || this;
|
|
}
|
|
ShearTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.shear << 24) + this.boneIndex;
|
|
};
|
|
ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var bone = skeleton.bones[this.boneIndex];
|
|
if (!bone.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.shearX = bone.data.shearX;
|
|
bone.shearY = bone.data.shearY;
|
|
return;
|
|
case MixBlend.first:
|
|
bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
|
|
bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var x = 0, y = 0;
|
|
if (time >= frames[frames.length - ShearTimeline.ENTRIES]) {
|
|
x = frames[frames.length + ShearTimeline.PREV_X];
|
|
y = frames[frames.length + ShearTimeline.PREV_Y];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES);
|
|
x = frames[frame + ShearTimeline.PREV_X];
|
|
y = frames[frame + ShearTimeline.PREV_Y];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime));
|
|
x = x + (frames[frame + ShearTimeline.X] - x) * percent;
|
|
y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
|
|
}
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
bone.shearX = bone.data.shearX + x * alpha;
|
|
bone.shearY = bone.data.shearY + y * alpha;
|
|
break;
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
|
|
bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
|
|
break;
|
|
case MixBlend.add:
|
|
bone.shearX += x * alpha;
|
|
bone.shearY += y * alpha;
|
|
}
|
|
};
|
|
return ShearTimeline;
|
|
}(TranslateTimeline));
|
|
spine.ShearTimeline = ShearTimeline;
|
|
var ColorTimeline = (function (_super) {
|
|
__extends(ColorTimeline, _super);
|
|
function ColorTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
ColorTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.color << 24) + this.slotIndex;
|
|
};
|
|
ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) {
|
|
frameIndex *= ColorTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + ColorTimeline.R] = r;
|
|
this.frames[frameIndex + ColorTimeline.G] = g;
|
|
this.frames[frameIndex + ColorTimeline.B] = b;
|
|
this.frames[frameIndex + ColorTimeline.A] = a;
|
|
};
|
|
ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var slot = skeleton.slots[this.slotIndex];
|
|
if (!slot.bone.active)
|
|
return;
|
|
var frames = this.frames;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
slot.color.setFromColor(slot.data.color);
|
|
return;
|
|
case MixBlend.first:
|
|
var color = slot.color, setup = slot.data.color;
|
|
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);
|
|
}
|
|
return;
|
|
}
|
|
var r = 0, g = 0, b = 0, a = 0;
|
|
if (time >= frames[frames.length - ColorTimeline.ENTRIES]) {
|
|
var i = frames.length;
|
|
r = frames[i + ColorTimeline.PREV_R];
|
|
g = frames[i + ColorTimeline.PREV_G];
|
|
b = frames[i + ColorTimeline.PREV_B];
|
|
a = frames[i + ColorTimeline.PREV_A];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, ColorTimeline.ENTRIES);
|
|
r = frames[frame + ColorTimeline.PREV_R];
|
|
g = frames[frame + ColorTimeline.PREV_G];
|
|
b = frames[frame + ColorTimeline.PREV_B];
|
|
a = frames[frame + ColorTimeline.PREV_A];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime));
|
|
r += (frames[frame + ColorTimeline.R] - r) * percent;
|
|
g += (frames[frame + ColorTimeline.G] - g) * percent;
|
|
b += (frames[frame + ColorTimeline.B] - b) * percent;
|
|
a += (frames[frame + ColorTimeline.A] - a) * percent;
|
|
}
|
|
if (alpha == 1)
|
|
slot.color.set(r, g, b, a);
|
|
else {
|
|
var color = slot.color;
|
|
if (blend == MixBlend.setup)
|
|
color.setFromColor(slot.data.color);
|
|
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
|
|
}
|
|
};
|
|
ColorTimeline.ENTRIES = 5;
|
|
ColorTimeline.PREV_TIME = -5;
|
|
ColorTimeline.PREV_R = -4;
|
|
ColorTimeline.PREV_G = -3;
|
|
ColorTimeline.PREV_B = -2;
|
|
ColorTimeline.PREV_A = -1;
|
|
ColorTimeline.R = 1;
|
|
ColorTimeline.G = 2;
|
|
ColorTimeline.B = 3;
|
|
ColorTimeline.A = 4;
|
|
return ColorTimeline;
|
|
}(CurveTimeline));
|
|
spine.ColorTimeline = ColorTimeline;
|
|
var TwoColorTimeline = (function (_super) {
|
|
__extends(TwoColorTimeline, _super);
|
|
function TwoColorTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
TwoColorTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.twoColor << 24) + this.slotIndex;
|
|
};
|
|
TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) {
|
|
frameIndex *= TwoColorTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + TwoColorTimeline.R] = r;
|
|
this.frames[frameIndex + TwoColorTimeline.G] = g;
|
|
this.frames[frameIndex + TwoColorTimeline.B] = b;
|
|
this.frames[frameIndex + TwoColorTimeline.A] = a;
|
|
this.frames[frameIndex + TwoColorTimeline.R2] = r2;
|
|
this.frames[frameIndex + TwoColorTimeline.G2] = g2;
|
|
this.frames[frameIndex + TwoColorTimeline.B2] = b2;
|
|
};
|
|
TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var slot = skeleton.slots[this.slotIndex];
|
|
if (!slot.bone.active)
|
|
return;
|
|
var frames = this.frames;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
slot.color.setFromColor(slot.data.color);
|
|
slot.darkColor.setFromColor(slot.data.darkColor);
|
|
return;
|
|
case MixBlend.first:
|
|
var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
|
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);
|
|
dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
|
|
}
|
|
return;
|
|
}
|
|
var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
|
|
if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) {
|
|
var i = frames.length;
|
|
r = frames[i + TwoColorTimeline.PREV_R];
|
|
g = frames[i + TwoColorTimeline.PREV_G];
|
|
b = frames[i + TwoColorTimeline.PREV_B];
|
|
a = frames[i + TwoColorTimeline.PREV_A];
|
|
r2 = frames[i + TwoColorTimeline.PREV_R2];
|
|
g2 = frames[i + TwoColorTimeline.PREV_G2];
|
|
b2 = frames[i + TwoColorTimeline.PREV_B2];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES);
|
|
r = frames[frame + TwoColorTimeline.PREV_R];
|
|
g = frames[frame + TwoColorTimeline.PREV_G];
|
|
b = frames[frame + TwoColorTimeline.PREV_B];
|
|
a = frames[frame + TwoColorTimeline.PREV_A];
|
|
r2 = frames[frame + TwoColorTimeline.PREV_R2];
|
|
g2 = frames[frame + TwoColorTimeline.PREV_G2];
|
|
b2 = frames[frame + TwoColorTimeline.PREV_B2];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime));
|
|
r += (frames[frame + TwoColorTimeline.R] - r) * percent;
|
|
g += (frames[frame + TwoColorTimeline.G] - g) * percent;
|
|
b += (frames[frame + TwoColorTimeline.B] - b) * percent;
|
|
a += (frames[frame + TwoColorTimeline.A] - a) * percent;
|
|
r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent;
|
|
g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent;
|
|
b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent;
|
|
}
|
|
if (alpha == 1) {
|
|
slot.color.set(r, g, b, a);
|
|
slot.darkColor.set(r2, g2, b2, 1);
|
|
}
|
|
else {
|
|
var light = slot.color, dark = slot.darkColor;
|
|
if (blend == MixBlend.setup) {
|
|
light.setFromColor(slot.data.color);
|
|
dark.setFromColor(slot.data.darkColor);
|
|
}
|
|
light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
|
|
dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
|
|
}
|
|
};
|
|
TwoColorTimeline.ENTRIES = 8;
|
|
TwoColorTimeline.PREV_TIME = -8;
|
|
TwoColorTimeline.PREV_R = -7;
|
|
TwoColorTimeline.PREV_G = -6;
|
|
TwoColorTimeline.PREV_B = -5;
|
|
TwoColorTimeline.PREV_A = -4;
|
|
TwoColorTimeline.PREV_R2 = -3;
|
|
TwoColorTimeline.PREV_G2 = -2;
|
|
TwoColorTimeline.PREV_B2 = -1;
|
|
TwoColorTimeline.R = 1;
|
|
TwoColorTimeline.G = 2;
|
|
TwoColorTimeline.B = 3;
|
|
TwoColorTimeline.A = 4;
|
|
TwoColorTimeline.R2 = 5;
|
|
TwoColorTimeline.G2 = 6;
|
|
TwoColorTimeline.B2 = 7;
|
|
return TwoColorTimeline;
|
|
}(CurveTimeline));
|
|
spine.TwoColorTimeline = TwoColorTimeline;
|
|
var AttachmentTimeline = (function () {
|
|
function AttachmentTimeline(frameCount) {
|
|
this.frames = spine.Utils.newFloatArray(frameCount);
|
|
this.attachmentNames = new Array(frameCount);
|
|
}
|
|
AttachmentTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.attachment << 24) + this.slotIndex;
|
|
};
|
|
AttachmentTimeline.prototype.getFrameCount = function () {
|
|
return this.frames.length;
|
|
};
|
|
AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) {
|
|
this.frames[frameIndex] = time;
|
|
this.attachmentNames[frameIndex] = attachmentName;
|
|
};
|
|
AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
|
|
var slot = skeleton.slots[this.slotIndex];
|
|
if (!slot.bone.active)
|
|
return;
|
|
if (direction == MixDirection.mixOut) {
|
|
if (blend == MixBlend.setup)
|
|
this.setAttachment(skeleton, slot, slot.data.attachmentName);
|
|
return;
|
|
}
|
|
var frames = this.frames;
|
|
if (time < frames[0]) {
|
|
if (blend == MixBlend.setup || blend == MixBlend.first)
|
|
this.setAttachment(skeleton, slot, slot.data.attachmentName);
|
|
return;
|
|
}
|
|
var frameIndex = 0;
|
|
if (time >= frames[frames.length - 1])
|
|
frameIndex = frames.length - 1;
|
|
else
|
|
frameIndex = Animation.binarySearch(frames, time, 1) - 1;
|
|
var attachmentName = this.attachmentNames[frameIndex];
|
|
skeleton.slots[this.slotIndex]
|
|
.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
|
|
};
|
|
AttachmentTimeline.prototype.setAttachment = function (skeleton, slot, attachmentName) {
|
|
slot.attachment = attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName);
|
|
};
|
|
return AttachmentTimeline;
|
|
}());
|
|
spine.AttachmentTimeline = AttachmentTimeline;
|
|
var zeros = null;
|
|
var DeformTimeline = (function (_super) {
|
|
__extends(DeformTimeline, _super);
|
|
function DeformTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount);
|
|
_this.frameVertices = new Array(frameCount);
|
|
if (zeros == null)
|
|
zeros = spine.Utils.newFloatArray(64);
|
|
return _this;
|
|
}
|
|
DeformTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
|
|
};
|
|
DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) {
|
|
this.frames[frameIndex] = time;
|
|
this.frameVertices[frameIndex] = vertices;
|
|
};
|
|
DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var slot = skeleton.slots[this.slotIndex];
|
|
if (!slot.bone.active)
|
|
return;
|
|
var slotAttachment = slot.getAttachment();
|
|
if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
|
|
return;
|
|
var deformArray = slot.deform;
|
|
if (deformArray.length == 0)
|
|
blend = MixBlend.setup;
|
|
var frameVertices = this.frameVertices;
|
|
var vertexCount = frameVertices[0].length;
|
|
var frames = this.frames;
|
|
if (time < frames[0]) {
|
|
var vertexAttachment = slotAttachment;
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
deformArray.length = 0;
|
|
return;
|
|
case MixBlend.first:
|
|
if (alpha == 1) {
|
|
deformArray.length = 0;
|
|
break;
|
|
}
|
|
var deform_1 = spine.Utils.setArraySize(deformArray, vertexCount);
|
|
if (vertexAttachment.bones == null) {
|
|
var setupVertices = vertexAttachment.vertices;
|
|
for (var i = 0; i < vertexCount; i++)
|
|
deform_1[i] += (setupVertices[i] - deform_1[i]) * alpha;
|
|
}
|
|
else {
|
|
alpha = 1 - alpha;
|
|
for (var i = 0; i < vertexCount; i++)
|
|
deform_1[i] *= alpha;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
var deform = spine.Utils.setArraySize(deformArray, vertexCount);
|
|
if (time >= frames[frames.length - 1]) {
|
|
var lastVertices = frameVertices[frames.length - 1];
|
|
if (alpha == 1) {
|
|
if (blend == MixBlend.add) {
|
|
var vertexAttachment = slotAttachment;
|
|
if (vertexAttachment.bones == null) {
|
|
var setupVertices = vertexAttachment.vertices;
|
|
for (var i_1 = 0; i_1 < vertexCount; i_1++) {
|
|
deform[i_1] += lastVertices[i_1] - setupVertices[i_1];
|
|
}
|
|
}
|
|
else {
|
|
for (var i_2 = 0; i_2 < vertexCount; i_2++)
|
|
deform[i_2] += lastVertices[i_2];
|
|
}
|
|
}
|
|
else {
|
|
spine.Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount);
|
|
}
|
|
}
|
|
else {
|
|
switch (blend) {
|
|
case MixBlend.setup: {
|
|
var vertexAttachment_1 = slotAttachment;
|
|
if (vertexAttachment_1.bones == null) {
|
|
var setupVertices = vertexAttachment_1.vertices;
|
|
for (var i_3 = 0; i_3 < vertexCount; i_3++) {
|
|
var setup = setupVertices[i_3];
|
|
deform[i_3] = setup + (lastVertices[i_3] - setup) * alpha;
|
|
}
|
|
}
|
|
else {
|
|
for (var i_4 = 0; i_4 < vertexCount; i_4++)
|
|
deform[i_4] = lastVertices[i_4] * alpha;
|
|
}
|
|
break;
|
|
}
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
for (var i_5 = 0; i_5 < vertexCount; i_5++)
|
|
deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha;
|
|
break;
|
|
case MixBlend.add:
|
|
var vertexAttachment = slotAttachment;
|
|
if (vertexAttachment.bones == null) {
|
|
var setupVertices = vertexAttachment.vertices;
|
|
for (var i_6 = 0; i_6 < vertexCount; i_6++) {
|
|
deform[i_6] += (lastVertices[i_6] - setupVertices[i_6]) * alpha;
|
|
}
|
|
}
|
|
else {
|
|
for (var i_7 = 0; i_7 < vertexCount; i_7++)
|
|
deform[i_7] += lastVertices[i_7] * alpha;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
var frame = Animation.binarySearch(frames, time);
|
|
var prevVertices = frameVertices[frame - 1];
|
|
var nextVertices = frameVertices[frame];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
|
|
if (alpha == 1) {
|
|
if (blend == MixBlend.add) {
|
|
var vertexAttachment = slotAttachment;
|
|
if (vertexAttachment.bones == null) {
|
|
var setupVertices = vertexAttachment.vertices;
|
|
for (var i_8 = 0; i_8 < vertexCount; i_8++) {
|
|
var prev = prevVertices[i_8];
|
|
deform[i_8] += prev + (nextVertices[i_8] - prev) * percent - setupVertices[i_8];
|
|
}
|
|
}
|
|
else {
|
|
for (var i_9 = 0; i_9 < vertexCount; i_9++) {
|
|
var prev = prevVertices[i_9];
|
|
deform[i_9] += prev + (nextVertices[i_9] - prev) * percent;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (var i_10 = 0; i_10 < vertexCount; i_10++) {
|
|
var prev = prevVertices[i_10];
|
|
deform[i_10] = prev + (nextVertices[i_10] - prev) * percent;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
switch (blend) {
|
|
case MixBlend.setup: {
|
|
var vertexAttachment_2 = slotAttachment;
|
|
if (vertexAttachment_2.bones == null) {
|
|
var setupVertices = vertexAttachment_2.vertices;
|
|
for (var i_11 = 0; i_11 < vertexCount; i_11++) {
|
|
var prev = prevVertices[i_11], setup = setupVertices[i_11];
|
|
deform[i_11] = setup + (prev + (nextVertices[i_11] - prev) * percent - setup) * alpha;
|
|
}
|
|
}
|
|
else {
|
|
for (var i_12 = 0; i_12 < vertexCount; i_12++) {
|
|
var prev = prevVertices[i_12];
|
|
deform[i_12] = (prev + (nextVertices[i_12] - prev) * percent) * alpha;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case MixBlend.first:
|
|
case MixBlend.replace:
|
|
for (var i_13 = 0; i_13 < vertexCount; i_13++) {
|
|
var prev = prevVertices[i_13];
|
|
deform[i_13] += (prev + (nextVertices[i_13] - prev) * percent - deform[i_13]) * alpha;
|
|
}
|
|
break;
|
|
case MixBlend.add:
|
|
var vertexAttachment = slotAttachment;
|
|
if (vertexAttachment.bones == null) {
|
|
var setupVertices = vertexAttachment.vertices;
|
|
for (var i_14 = 0; i_14 < vertexCount; i_14++) {
|
|
var prev = prevVertices[i_14];
|
|
deform[i_14] += (prev + (nextVertices[i_14] - prev) * percent - setupVertices[i_14]) * alpha;
|
|
}
|
|
}
|
|
else {
|
|
for (var i_15 = 0; i_15 < vertexCount; i_15++) {
|
|
var prev = prevVertices[i_15];
|
|
deform[i_15] += (prev + (nextVertices[i_15] - prev) * percent) * alpha;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
return DeformTimeline;
|
|
}(CurveTimeline));
|
|
spine.DeformTimeline = DeformTimeline;
|
|
var EventTimeline = (function () {
|
|
function EventTimeline(frameCount) {
|
|
this.frames = spine.Utils.newFloatArray(frameCount);
|
|
this.events = new Array(frameCount);
|
|
}
|
|
EventTimeline.prototype.getPropertyId = function () {
|
|
return TimelineType.event << 24;
|
|
};
|
|
EventTimeline.prototype.getFrameCount = function () {
|
|
return this.frames.length;
|
|
};
|
|
EventTimeline.prototype.setFrame = function (frameIndex, event) {
|
|
this.frames[frameIndex] = event.time;
|
|
this.events[frameIndex] = event;
|
|
};
|
|
EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
if (firedEvents == null)
|
|
return;
|
|
var frames = this.frames;
|
|
var frameCount = this.frames.length;
|
|
if (lastTime > time) {
|
|
this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction);
|
|
lastTime = -1;
|
|
}
|
|
else if (lastTime >= frames[frameCount - 1])
|
|
return;
|
|
if (time < frames[0])
|
|
return;
|
|
var frame = 0;
|
|
if (lastTime < frames[0])
|
|
frame = 0;
|
|
else {
|
|
frame = Animation.binarySearch(frames, lastTime);
|
|
var frameTime = frames[frame];
|
|
while (frame > 0) {
|
|
if (frames[frame - 1] != frameTime)
|
|
break;
|
|
frame--;
|
|
}
|
|
}
|
|
for (; frame < frameCount && time >= frames[frame]; frame++)
|
|
firedEvents.push(this.events[frame]);
|
|
};
|
|
return EventTimeline;
|
|
}());
|
|
spine.EventTimeline = EventTimeline;
|
|
var DrawOrderTimeline = (function () {
|
|
function DrawOrderTimeline(frameCount) {
|
|
this.frames = spine.Utils.newFloatArray(frameCount);
|
|
this.drawOrders = new Array(frameCount);
|
|
}
|
|
DrawOrderTimeline.prototype.getPropertyId = function () {
|
|
return TimelineType.drawOrder << 24;
|
|
};
|
|
DrawOrderTimeline.prototype.getFrameCount = function () {
|
|
return this.frames.length;
|
|
};
|
|
DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) {
|
|
this.frames[frameIndex] = time;
|
|
this.drawOrders[frameIndex] = drawOrder;
|
|
};
|
|
DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var drawOrder = skeleton.drawOrder;
|
|
var slots = skeleton.slots;
|
|
if (direction == MixDirection.mixOut) {
|
|
if (blend == MixBlend.setup)
|
|
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
|
|
return;
|
|
}
|
|
var frames = this.frames;
|
|
if (time < frames[0]) {
|
|
if (blend == MixBlend.setup || blend == MixBlend.first)
|
|
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
|
|
return;
|
|
}
|
|
var frame = 0;
|
|
if (time >= frames[frames.length - 1])
|
|
frame = frames.length - 1;
|
|
else
|
|
frame = Animation.binarySearch(frames, time) - 1;
|
|
var drawOrderToSetupIndex = this.drawOrders[frame];
|
|
if (drawOrderToSetupIndex == null)
|
|
spine.Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length);
|
|
else {
|
|
for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
|
|
drawOrder[i] = slots[drawOrderToSetupIndex[i]];
|
|
}
|
|
};
|
|
return DrawOrderTimeline;
|
|
}());
|
|
spine.DrawOrderTimeline = DrawOrderTimeline;
|
|
var IkConstraintTimeline = (function (_super) {
|
|
__extends(IkConstraintTimeline, _super);
|
|
function IkConstraintTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
IkConstraintTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
|
|
};
|
|
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, softness, bendDirection, compress, stretch) {
|
|
frameIndex *= IkConstraintTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
|
|
this.frames[frameIndex + IkConstraintTimeline.SOFTNESS] = softness;
|
|
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
|
|
this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0;
|
|
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
|
|
};
|
|
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
|
|
if (!constraint.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
constraint.mix = constraint.data.mix;
|
|
constraint.softness = constraint.data.softness;
|
|
constraint.bendDirection = constraint.data.bendDirection;
|
|
constraint.compress = constraint.data.compress;
|
|
constraint.stretch = constraint.data.stretch;
|
|
return;
|
|
case MixBlend.first:
|
|
constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
|
|
constraint.softness += (constraint.data.softness - constraint.softness) * alpha;
|
|
constraint.bendDirection = constraint.data.bendDirection;
|
|
constraint.compress = constraint.data.compress;
|
|
constraint.stretch = constraint.data.stretch;
|
|
}
|
|
return;
|
|
}
|
|
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
|
|
if (blend == MixBlend.setup) {
|
|
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
|
|
constraint.softness = constraint.data.softness
|
|
+ (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.data.softness) * alpha;
|
|
if (direction == MixDirection.mixOut) {
|
|
constraint.bendDirection = constraint.data.bendDirection;
|
|
constraint.compress = constraint.data.compress;
|
|
constraint.stretch = constraint.data.stretch;
|
|
}
|
|
else {
|
|
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
|
|
constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0;
|
|
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
|
|
}
|
|
}
|
|
else {
|
|
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
|
|
constraint.softness += (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.softness) * alpha;
|
|
if (direction == MixDirection.mixIn) {
|
|
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
|
|
constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0;
|
|
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
var frame = Animation.binarySearch(frames, time, IkConstraintTimeline.ENTRIES);
|
|
var mix = frames[frame + IkConstraintTimeline.PREV_MIX];
|
|
var softness = frames[frame + IkConstraintTimeline.PREV_SOFTNESS];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
|
|
if (blend == MixBlend.setup) {
|
|
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
|
|
constraint.softness = constraint.data.softness
|
|
+ (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.data.softness) * alpha;
|
|
if (direction == MixDirection.mixOut) {
|
|
constraint.bendDirection = constraint.data.bendDirection;
|
|
constraint.compress = constraint.data.compress;
|
|
constraint.stretch = constraint.data.stretch;
|
|
}
|
|
else {
|
|
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
|
|
constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0;
|
|
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
|
|
}
|
|
}
|
|
else {
|
|
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
|
|
constraint.softness += (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.softness) * alpha;
|
|
if (direction == MixDirection.mixIn) {
|
|
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
|
|
constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0;
|
|
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
|
|
}
|
|
}
|
|
};
|
|
IkConstraintTimeline.ENTRIES = 6;
|
|
IkConstraintTimeline.PREV_TIME = -6;
|
|
IkConstraintTimeline.PREV_MIX = -5;
|
|
IkConstraintTimeline.PREV_SOFTNESS = -4;
|
|
IkConstraintTimeline.PREV_BEND_DIRECTION = -3;
|
|
IkConstraintTimeline.PREV_COMPRESS = -2;
|
|
IkConstraintTimeline.PREV_STRETCH = -1;
|
|
IkConstraintTimeline.MIX = 1;
|
|
IkConstraintTimeline.SOFTNESS = 2;
|
|
IkConstraintTimeline.BEND_DIRECTION = 3;
|
|
IkConstraintTimeline.COMPRESS = 4;
|
|
IkConstraintTimeline.STRETCH = 5;
|
|
return IkConstraintTimeline;
|
|
}(CurveTimeline));
|
|
spine.IkConstraintTimeline = IkConstraintTimeline;
|
|
var TransformConstraintTimeline = (function (_super) {
|
|
__extends(TransformConstraintTimeline, _super);
|
|
function TransformConstraintTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
TransformConstraintTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
|
|
};
|
|
TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) {
|
|
frameIndex *= TransformConstraintTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix;
|
|
this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix;
|
|
this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix;
|
|
this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
|
|
};
|
|
TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
|
|
if (!constraint.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
var data = constraint.data;
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
constraint.rotateMix = data.rotateMix;
|
|
constraint.translateMix = data.translateMix;
|
|
constraint.scaleMix = data.scaleMix;
|
|
constraint.shearMix = data.shearMix;
|
|
return;
|
|
case MixBlend.first:
|
|
constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
|
|
constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
|
|
constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
|
|
constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var rotate = 0, translate = 0, scale = 0, shear = 0;
|
|
if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) {
|
|
var i = frames.length;
|
|
rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE];
|
|
translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE];
|
|
scale = frames[i + TransformConstraintTimeline.PREV_SCALE];
|
|
shear = frames[i + TransformConstraintTimeline.PREV_SHEAR];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES);
|
|
rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE];
|
|
translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE];
|
|
scale = frames[frame + TransformConstraintTimeline.PREV_SCALE];
|
|
shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime));
|
|
rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent;
|
|
translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent;
|
|
scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
|
|
shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
|
|
}
|
|
if (blend == MixBlend.setup) {
|
|
var data = constraint.data;
|
|
constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
|
|
constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
|
|
constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha;
|
|
constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha;
|
|
}
|
|
else {
|
|
constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
|
|
constraint.translateMix += (translate - constraint.translateMix) * alpha;
|
|
constraint.scaleMix += (scale - constraint.scaleMix) * alpha;
|
|
constraint.shearMix += (shear - constraint.shearMix) * alpha;
|
|
}
|
|
};
|
|
TransformConstraintTimeline.ENTRIES = 5;
|
|
TransformConstraintTimeline.PREV_TIME = -5;
|
|
TransformConstraintTimeline.PREV_ROTATE = -4;
|
|
TransformConstraintTimeline.PREV_TRANSLATE = -3;
|
|
TransformConstraintTimeline.PREV_SCALE = -2;
|
|
TransformConstraintTimeline.PREV_SHEAR = -1;
|
|
TransformConstraintTimeline.ROTATE = 1;
|
|
TransformConstraintTimeline.TRANSLATE = 2;
|
|
TransformConstraintTimeline.SCALE = 3;
|
|
TransformConstraintTimeline.SHEAR = 4;
|
|
return TransformConstraintTimeline;
|
|
}(CurveTimeline));
|
|
spine.TransformConstraintTimeline = TransformConstraintTimeline;
|
|
var PathConstraintPositionTimeline = (function (_super) {
|
|
__extends(PathConstraintPositionTimeline, _super);
|
|
function PathConstraintPositionTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
PathConstraintPositionTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
|
|
};
|
|
PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) {
|
|
frameIndex *= PathConstraintPositionTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
|
|
};
|
|
PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
|
|
if (!constraint.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
constraint.position = constraint.data.position;
|
|
return;
|
|
case MixBlend.first:
|
|
constraint.position += (constraint.data.position - constraint.position) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var position = 0;
|
|
if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES])
|
|
position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE];
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES);
|
|
position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
|
|
position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
|
|
}
|
|
if (blend == MixBlend.setup)
|
|
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
|
|
else
|
|
constraint.position += (position - constraint.position) * alpha;
|
|
};
|
|
PathConstraintPositionTimeline.ENTRIES = 2;
|
|
PathConstraintPositionTimeline.PREV_TIME = -2;
|
|
PathConstraintPositionTimeline.PREV_VALUE = -1;
|
|
PathConstraintPositionTimeline.VALUE = 1;
|
|
return PathConstraintPositionTimeline;
|
|
}(CurveTimeline));
|
|
spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
|
|
var PathConstraintSpacingTimeline = (function (_super) {
|
|
__extends(PathConstraintSpacingTimeline, _super);
|
|
function PathConstraintSpacingTimeline(frameCount) {
|
|
return _super.call(this, frameCount) || this;
|
|
}
|
|
PathConstraintSpacingTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
|
|
};
|
|
PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
|
|
if (!constraint.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
constraint.spacing = constraint.data.spacing;
|
|
return;
|
|
case MixBlend.first:
|
|
constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var spacing = 0;
|
|
if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES])
|
|
spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE];
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES);
|
|
spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
|
|
spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
|
|
}
|
|
if (blend == MixBlend.setup)
|
|
constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
|
|
else
|
|
constraint.spacing += (spacing - constraint.spacing) * alpha;
|
|
};
|
|
return PathConstraintSpacingTimeline;
|
|
}(PathConstraintPositionTimeline));
|
|
spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline;
|
|
var PathConstraintMixTimeline = (function (_super) {
|
|
__extends(PathConstraintMixTimeline, _super);
|
|
function PathConstraintMixTimeline(frameCount) {
|
|
var _this = _super.call(this, frameCount) || this;
|
|
_this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
|
|
return _this;
|
|
}
|
|
PathConstraintMixTimeline.prototype.getPropertyId = function () {
|
|
return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
|
|
};
|
|
PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) {
|
|
frameIndex *= PathConstraintMixTimeline.ENTRIES;
|
|
this.frames[frameIndex] = time;
|
|
this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix;
|
|
this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
|
|
};
|
|
PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
|
|
var frames = this.frames;
|
|
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
|
|
if (!constraint.active)
|
|
return;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case MixBlend.setup:
|
|
constraint.rotateMix = constraint.data.rotateMix;
|
|
constraint.translateMix = constraint.data.translateMix;
|
|
return;
|
|
case MixBlend.first:
|
|
constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
|
|
constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
|
|
}
|
|
return;
|
|
}
|
|
var rotate = 0, translate = 0;
|
|
if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) {
|
|
rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE];
|
|
translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE];
|
|
}
|
|
else {
|
|
var frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES);
|
|
rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE];
|
|
translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE];
|
|
var frameTime = frames[frame];
|
|
var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime));
|
|
rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
|
|
translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
|
|
}
|
|
if (blend == MixBlend.setup) {
|
|
constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
|
|
constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
|
|
}
|
|
else {
|
|
constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
|
|
constraint.translateMix += (translate - constraint.translateMix) * alpha;
|
|
}
|
|
};
|
|
PathConstraintMixTimeline.ENTRIES = 3;
|
|
PathConstraintMixTimeline.PREV_TIME = -3;
|
|
PathConstraintMixTimeline.PREV_ROTATE = -2;
|
|
PathConstraintMixTimeline.PREV_TRANSLATE = -1;
|
|
PathConstraintMixTimeline.ROTATE = 1;
|
|
PathConstraintMixTimeline.TRANSLATE = 2;
|
|
return PathConstraintMixTimeline;
|
|
}(CurveTimeline));
|
|
spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var AnimationState = (function () {
|
|
function AnimationState(data) {
|
|
this.tracks = new Array();
|
|
this.timeScale = 1;
|
|
this.unkeyedState = 0;
|
|
this.events = new Array();
|
|
this.listeners = new Array();
|
|
this.queue = new EventQueue(this);
|
|
this.propertyIDs = new spine.IntSet();
|
|
this.animationsChanged = false;
|
|
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
|
|
this.data = data;
|
|
}
|
|
AnimationState.prototype.update = function (delta) {
|
|
delta *= this.timeScale;
|
|
var tracks = this.tracks;
|
|
for (var i = 0, n = tracks.length; i < n; i++) {
|
|
var current = tracks[i];
|
|
if (current == null)
|
|
continue;
|
|
current.animationLast = current.nextAnimationLast;
|
|
current.trackLast = current.nextTrackLast;
|
|
var currentDelta = delta * current.timeScale;
|
|
if (current.delay > 0) {
|
|
current.delay -= currentDelta;
|
|
if (current.delay > 0)
|
|
continue;
|
|
currentDelta = -current.delay;
|
|
current.delay = 0;
|
|
}
|
|
var next = current.next;
|
|
if (next != null) {
|
|
var nextTime = current.trackLast - next.delay;
|
|
if (nextTime >= 0) {
|
|
next.delay = 0;
|
|
next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale;
|
|
current.trackTime += currentDelta;
|
|
this.setCurrent(i, next, true);
|
|
while (next.mixingFrom != null) {
|
|
next.mixTime += delta;
|
|
next = next.mixingFrom;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
|
|
tracks[i] = null;
|
|
this.queue.end(current);
|
|
this.disposeNext(current);
|
|
continue;
|
|
}
|
|
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
|
|
var from = current.mixingFrom;
|
|
current.mixingFrom = null;
|
|
if (from != null)
|
|
from.mixingTo = null;
|
|
while (from != null) {
|
|
this.queue.end(from);
|
|
from = from.mixingFrom;
|
|
}
|
|
}
|
|
current.trackTime += currentDelta;
|
|
}
|
|
this.queue.drain();
|
|
};
|
|
AnimationState.prototype.updateMixingFrom = function (to, delta) {
|
|
var from = to.mixingFrom;
|
|
if (from == null)
|
|
return true;
|
|
var finished = this.updateMixingFrom(from, delta);
|
|
from.animationLast = from.nextAnimationLast;
|
|
from.trackLast = from.nextTrackLast;
|
|
if (to.mixTime > 0 && to.mixTime >= to.mixDuration) {
|
|
if (from.totalAlpha == 0 || to.mixDuration == 0) {
|
|
to.mixingFrom = from.mixingFrom;
|
|
if (from.mixingFrom != null)
|
|
from.mixingFrom.mixingTo = to;
|
|
to.interruptAlpha = from.interruptAlpha;
|
|
this.queue.end(from);
|
|
}
|
|
return finished;
|
|
}
|
|
from.trackTime += delta * from.timeScale;
|
|
to.mixTime += delta;
|
|
return false;
|
|
};
|
|
AnimationState.prototype.apply = function (skeleton) {
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
if (this.animationsChanged)
|
|
this._animationsChanged();
|
|
var events = this.events;
|
|
var tracks = this.tracks;
|
|
var applied = false;
|
|
for (var i_16 = 0, n_1 = tracks.length; i_16 < n_1; i_16++) {
|
|
var current = tracks[i_16];
|
|
if (current == null || current.delay > 0)
|
|
continue;
|
|
applied = true;
|
|
var blend = i_16 == 0 ? spine.MixBlend.first : current.mixBlend;
|
|
var mix = current.alpha;
|
|
if (current.mixingFrom != null)
|
|
mix *= this.applyMixingFrom(current, skeleton, blend);
|
|
else if (current.trackTime >= current.trackEnd && current.next == null)
|
|
mix = 0;
|
|
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
|
|
var timelineCount = current.animation.timelines.length;
|
|
var timelines = current.animation.timelines;
|
|
if ((i_16 == 0 && mix == 1) || blend == spine.MixBlend.add) {
|
|
for (var ii = 0; ii < timelineCount; ii++) {
|
|
spine.Utils.webkit602BugfixHelper(mix, blend);
|
|
var timeline = timelines[ii];
|
|
if (timeline instanceof spine.AttachmentTimeline)
|
|
this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true);
|
|
else
|
|
timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection.mixIn);
|
|
}
|
|
}
|
|
else {
|
|
var timelineMode = current.timelineMode;
|
|
var firstFrame = current.timelinesRotation.length == 0;
|
|
if (firstFrame)
|
|
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
|
|
var timelinesRotation = current.timelinesRotation;
|
|
for (var ii = 0; ii < timelineCount; ii++) {
|
|
var timeline_1 = timelines[ii];
|
|
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
|
|
if (timeline_1 instanceof spine.RotateTimeline) {
|
|
this.applyRotateTimeline(timeline_1, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
|
}
|
|
else if (timeline_1 instanceof spine.AttachmentTimeline) {
|
|
this.applyAttachmentTimeline(timeline_1, skeleton, animationTime, blend, true);
|
|
}
|
|
else {
|
|
spine.Utils.webkit602BugfixHelper(mix, blend);
|
|
timeline_1.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, spine.MixDirection.mixIn);
|
|
}
|
|
}
|
|
}
|
|
this.queueEvents(current, animationTime);
|
|
events.length = 0;
|
|
current.nextAnimationLast = animationTime;
|
|
current.nextTrackLast = current.trackTime;
|
|
}
|
|
var setupState = this.unkeyedState + AnimationState.SETUP;
|
|
var slots = skeleton.slots;
|
|
for (var i = 0, n = skeleton.slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (slot.attachmentState == setupState) {
|
|
var attachmentName = slot.data.attachmentName;
|
|
slot.attachment = (attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
|
|
}
|
|
}
|
|
this.unkeyedState += 2;
|
|
this.queue.drain();
|
|
return applied;
|
|
};
|
|
AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) {
|
|
var from = to.mixingFrom;
|
|
if (from.mixingFrom != null)
|
|
this.applyMixingFrom(from, skeleton, blend);
|
|
var mix = 0;
|
|
if (to.mixDuration == 0) {
|
|
mix = 1;
|
|
if (blend == spine.MixBlend.first)
|
|
blend = spine.MixBlend.setup;
|
|
}
|
|
else {
|
|
mix = to.mixTime / to.mixDuration;
|
|
if (mix > 1)
|
|
mix = 1;
|
|
if (blend != spine.MixBlend.first)
|
|
blend = from.mixBlend;
|
|
}
|
|
var events = mix < from.eventThreshold ? this.events : null;
|
|
var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
|
|
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
|
|
var timelineCount = from.animation.timelines.length;
|
|
var timelines = from.animation.timelines;
|
|
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
|
|
if (blend == spine.MixBlend.add) {
|
|
for (var i = 0; i < timelineCount; i++)
|
|
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.mixOut);
|
|
}
|
|
else {
|
|
var timelineMode = from.timelineMode;
|
|
var timelineHoldMix = from.timelineHoldMix;
|
|
var firstFrame = from.timelinesRotation.length == 0;
|
|
if (firstFrame)
|
|
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
|
|
var timelinesRotation = from.timelinesRotation;
|
|
from.totalAlpha = 0;
|
|
for (var i = 0; i < timelineCount; i++) {
|
|
var timeline = timelines[i];
|
|
var direction = spine.MixDirection.mixOut;
|
|
var timelineBlend = void 0;
|
|
var alpha = 0;
|
|
switch (timelineMode[i]) {
|
|
case AnimationState.SUBSEQUENT:
|
|
if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
|
|
continue;
|
|
timelineBlend = blend;
|
|
alpha = alphaMix;
|
|
break;
|
|
case AnimationState.FIRST:
|
|
timelineBlend = spine.MixBlend.setup;
|
|
alpha = alphaMix;
|
|
break;
|
|
case AnimationState.HOLD_SUBSEQUENT:
|
|
timelineBlend = blend;
|
|
alpha = alphaHold;
|
|
break;
|
|
case AnimationState.HOLD_FIRST:
|
|
timelineBlend = spine.MixBlend.setup;
|
|
alpha = alphaHold;
|
|
break;
|
|
default:
|
|
timelineBlend = spine.MixBlend.setup;
|
|
var holdMix = timelineHoldMix[i];
|
|
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
|
|
break;
|
|
}
|
|
from.totalAlpha += alpha;
|
|
if (timeline instanceof spine.RotateTimeline)
|
|
this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
|
else if (timeline instanceof spine.AttachmentTimeline)
|
|
this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments);
|
|
else {
|
|
spine.Utils.webkit602BugfixHelper(alpha, blend);
|
|
if (drawOrder && timeline instanceof spine.DrawOrderTimeline && timelineBlend == spine.MixBlend.setup)
|
|
direction = spine.MixDirection.mixIn;
|
|
timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction);
|
|
}
|
|
}
|
|
}
|
|
if (to.mixDuration > 0)
|
|
this.queueEvents(from, animationTime);
|
|
this.events.length = 0;
|
|
from.nextAnimationLast = animationTime;
|
|
from.nextTrackLast = from.trackTime;
|
|
return mix;
|
|
};
|
|
AnimationState.prototype.applyAttachmentTimeline = function (timeline, skeleton, time, blend, attachments) {
|
|
var slot = skeleton.slots[timeline.slotIndex];
|
|
if (!slot.bone.active)
|
|
return;
|
|
var frames = timeline.frames;
|
|
if (time < frames[0]) {
|
|
if (blend == spine.MixBlend.setup || blend == spine.MixBlend.first)
|
|
this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments);
|
|
}
|
|
else {
|
|
var frameIndex;
|
|
if (time >= frames[frames.length - 1])
|
|
frameIndex = frames.length - 1;
|
|
else
|
|
frameIndex = spine.Animation.binarySearch(frames, time) - 1;
|
|
this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments);
|
|
}
|
|
if (slot.attachmentState <= this.unkeyedState)
|
|
slot.attachmentState = this.unkeyedState + AnimationState.SETUP;
|
|
};
|
|
AnimationState.prototype.setAttachment = function (skeleton, slot, attachmentName, attachments) {
|
|
slot.attachment = attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName);
|
|
if (attachments)
|
|
slot.attachmentState = this.unkeyedState + AnimationState.CURRENT;
|
|
};
|
|
AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) {
|
|
if (firstFrame)
|
|
timelinesRotation[i] = 0;
|
|
if (alpha == 1) {
|
|
timeline.apply(skeleton, 0, time, null, 1, blend, spine.MixDirection.mixIn);
|
|
return;
|
|
}
|
|
var rotateTimeline = timeline;
|
|
var frames = rotateTimeline.frames;
|
|
var bone = skeleton.bones[rotateTimeline.boneIndex];
|
|
if (!bone.active)
|
|
return;
|
|
var r1 = 0, r2 = 0;
|
|
if (time < frames[0]) {
|
|
switch (blend) {
|
|
case spine.MixBlend.setup:
|
|
bone.rotation = bone.data.rotation;
|
|
default:
|
|
return;
|
|
case spine.MixBlend.first:
|
|
r1 = bone.rotation;
|
|
r2 = bone.data.rotation;
|
|
}
|
|
}
|
|
else {
|
|
r1 = blend == spine.MixBlend.setup ? bone.data.rotation : bone.rotation;
|
|
if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES])
|
|
r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION];
|
|
else {
|
|
var frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES);
|
|
var prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION];
|
|
var frameTime = frames[frame];
|
|
var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime));
|
|
r2 = frames[frame + spine.RotateTimeline.ROTATION] - prevRotation;
|
|
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
|
|
r2 = prevRotation + r2 * percent + bone.data.rotation;
|
|
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
|
|
}
|
|
}
|
|
var total = 0, diff = r2 - r1;
|
|
diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
|
|
if (diff == 0) {
|
|
total = timelinesRotation[i];
|
|
}
|
|
else {
|
|
var lastTotal = 0, lastDiff = 0;
|
|
if (firstFrame) {
|
|
lastTotal = 0;
|
|
lastDiff = diff;
|
|
}
|
|
else {
|
|
lastTotal = timelinesRotation[i];
|
|
lastDiff = timelinesRotation[i + 1];
|
|
}
|
|
var current = diff > 0, dir = lastTotal >= 0;
|
|
if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) {
|
|
if (Math.abs(lastTotal) > 180)
|
|
lastTotal += 360 * spine.MathUtils.signum(lastTotal);
|
|
dir = current;
|
|
}
|
|
total = diff + lastTotal - lastTotal % 360;
|
|
if (dir != current)
|
|
total += 360 * spine.MathUtils.signum(lastTotal);
|
|
timelinesRotation[i] = total;
|
|
}
|
|
timelinesRotation[i + 1] = diff;
|
|
r1 += total * alpha;
|
|
bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360;
|
|
};
|
|
AnimationState.prototype.queueEvents = function (entry, animationTime) {
|
|
var animationStart = entry.animationStart, animationEnd = entry.animationEnd;
|
|
var duration = animationEnd - animationStart;
|
|
var trackLastWrapped = entry.trackLast % duration;
|
|
var events = this.events;
|
|
var i = 0, n = events.length;
|
|
for (; i < n; i++) {
|
|
var event_1 = events[i];
|
|
if (event_1.time < trackLastWrapped)
|
|
break;
|
|
if (event_1.time > animationEnd)
|
|
continue;
|
|
this.queue.event(entry, event_1);
|
|
}
|
|
var complete = false;
|
|
if (entry.loop)
|
|
complete = duration == 0 || trackLastWrapped > entry.trackTime % duration;
|
|
else
|
|
complete = animationTime >= animationEnd && entry.animationLast < animationEnd;
|
|
if (complete)
|
|
this.queue.complete(entry);
|
|
for (; i < n; i++) {
|
|
var event_2 = events[i];
|
|
if (event_2.time < animationStart)
|
|
continue;
|
|
this.queue.event(entry, events[i]);
|
|
}
|
|
};
|
|
AnimationState.prototype.clearTracks = function () {
|
|
var oldDrainDisabled = this.queue.drainDisabled;
|
|
this.queue.drainDisabled = true;
|
|
for (var i = 0, n = this.tracks.length; i < n; i++)
|
|
this.clearTrack(i);
|
|
this.tracks.length = 0;
|
|
this.queue.drainDisabled = oldDrainDisabled;
|
|
this.queue.drain();
|
|
};
|
|
AnimationState.prototype.clearTrack = function (trackIndex) {
|
|
if (trackIndex >= this.tracks.length)
|
|
return;
|
|
var current = this.tracks[trackIndex];
|
|
if (current == null)
|
|
return;
|
|
this.queue.end(current);
|
|
this.disposeNext(current);
|
|
var entry = current;
|
|
while (true) {
|
|
var from = entry.mixingFrom;
|
|
if (from == null)
|
|
break;
|
|
this.queue.end(from);
|
|
entry.mixingFrom = null;
|
|
entry.mixingTo = null;
|
|
entry = from;
|
|
}
|
|
this.tracks[current.trackIndex] = null;
|
|
this.queue.drain();
|
|
};
|
|
AnimationState.prototype.setCurrent = function (index, current, interrupt) {
|
|
var from = this.expandToIndex(index);
|
|
this.tracks[index] = current;
|
|
if (from != null) {
|
|
if (interrupt)
|
|
this.queue.interrupt(from);
|
|
current.mixingFrom = from;
|
|
from.mixingTo = current;
|
|
current.mixTime = 0;
|
|
if (from.mixingFrom != null && from.mixDuration > 0)
|
|
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
|
|
from.timelinesRotation.length = 0;
|
|
}
|
|
this.queue.start(current);
|
|
};
|
|
AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) {
|
|
var animation = this.data.skeletonData.findAnimation(animationName);
|
|
if (animation == null)
|
|
throw new Error("Animation not found: " + animationName);
|
|
return this.setAnimationWith(trackIndex, animation, loop);
|
|
};
|
|
AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) {
|
|
if (animation == null)
|
|
throw new Error("animation cannot be null.");
|
|
var interrupt = true;
|
|
var current = this.expandToIndex(trackIndex);
|
|
if (current != null) {
|
|
if (current.nextTrackLast == -1) {
|
|
this.tracks[trackIndex] = current.mixingFrom;
|
|
this.queue.interrupt(current);
|
|
this.queue.end(current);
|
|
this.disposeNext(current);
|
|
current = current.mixingFrom;
|
|
interrupt = false;
|
|
}
|
|
else
|
|
this.disposeNext(current);
|
|
}
|
|
var entry = this.trackEntry(trackIndex, animation, loop, current);
|
|
this.setCurrent(trackIndex, entry, interrupt);
|
|
this.queue.drain();
|
|
return entry;
|
|
};
|
|
AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) {
|
|
var animation = this.data.skeletonData.findAnimation(animationName);
|
|
if (animation == null)
|
|
throw new Error("Animation not found: " + animationName);
|
|
return this.addAnimationWith(trackIndex, animation, loop, delay);
|
|
};
|
|
AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) {
|
|
if (animation == null)
|
|
throw new Error("animation cannot be null.");
|
|
var last = this.expandToIndex(trackIndex);
|
|
if (last != null) {
|
|
while (last.next != null)
|
|
last = last.next;
|
|
}
|
|
var entry = this.trackEntry(trackIndex, animation, loop, last);
|
|
if (last == null) {
|
|
this.setCurrent(trackIndex, entry, true);
|
|
this.queue.drain();
|
|
}
|
|
else {
|
|
last.next = entry;
|
|
if (delay <= 0) {
|
|
var duration = last.animationEnd - last.animationStart;
|
|
if (duration != 0) {
|
|
if (last.loop)
|
|
delay += duration * (1 + ((last.trackTime / duration) | 0));
|
|
else
|
|
delay += Math.max(duration, last.trackTime);
|
|
delay -= this.data.getMix(last.animation, animation);
|
|
}
|
|
else
|
|
delay = last.trackTime;
|
|
}
|
|
}
|
|
entry.delay = delay;
|
|
return entry;
|
|
};
|
|
AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) {
|
|
var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false);
|
|
entry.mixDuration = mixDuration;
|
|
entry.trackEnd = mixDuration;
|
|
return entry;
|
|
};
|
|
AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) {
|
|
if (delay <= 0)
|
|
delay -= mixDuration;
|
|
var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay);
|
|
entry.mixDuration = mixDuration;
|
|
entry.trackEnd = mixDuration;
|
|
return entry;
|
|
};
|
|
AnimationState.prototype.setEmptyAnimations = function (mixDuration) {
|
|
var oldDrainDisabled = this.queue.drainDisabled;
|
|
this.queue.drainDisabled = true;
|
|
for (var i = 0, n = this.tracks.length; i < n; i++) {
|
|
var current = this.tracks[i];
|
|
if (current != null)
|
|
this.setEmptyAnimation(current.trackIndex, mixDuration);
|
|
}
|
|
this.queue.drainDisabled = oldDrainDisabled;
|
|
this.queue.drain();
|
|
};
|
|
AnimationState.prototype.expandToIndex = function (index) {
|
|
if (index < this.tracks.length)
|
|
return this.tracks[index];
|
|
spine.Utils.ensureArrayCapacity(this.tracks, index + 1, null);
|
|
this.tracks.length = index + 1;
|
|
return null;
|
|
};
|
|
AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) {
|
|
var entry = this.trackEntryPool.obtain();
|
|
entry.trackIndex = trackIndex;
|
|
entry.animation = animation;
|
|
entry.loop = loop;
|
|
entry.holdPrevious = false;
|
|
entry.eventThreshold = 0;
|
|
entry.attachmentThreshold = 0;
|
|
entry.drawOrderThreshold = 0;
|
|
entry.animationStart = 0;
|
|
entry.animationEnd = animation.duration;
|
|
entry.animationLast = -1;
|
|
entry.nextAnimationLast = -1;
|
|
entry.delay = 0;
|
|
entry.trackTime = 0;
|
|
entry.trackLast = -1;
|
|
entry.nextTrackLast = -1;
|
|
entry.trackEnd = Number.MAX_VALUE;
|
|
entry.timeScale = 1;
|
|
entry.alpha = 1;
|
|
entry.interruptAlpha = 1;
|
|
entry.mixTime = 0;
|
|
entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
|
|
entry.mixBlend = spine.MixBlend.replace;
|
|
return entry;
|
|
};
|
|
AnimationState.prototype.disposeNext = function (entry) {
|
|
var next = entry.next;
|
|
while (next != null) {
|
|
this.queue.dispose(next);
|
|
next = next.next;
|
|
}
|
|
entry.next = null;
|
|
};
|
|
AnimationState.prototype._animationsChanged = function () {
|
|
this.animationsChanged = false;
|
|
this.propertyIDs.clear();
|
|
for (var i = 0, n = this.tracks.length; i < n; i++) {
|
|
var entry = this.tracks[i];
|
|
if (entry == null)
|
|
continue;
|
|
while (entry.mixingFrom != null)
|
|
entry = entry.mixingFrom;
|
|
do {
|
|
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
|
|
this.computeHold(entry);
|
|
entry = entry.mixingTo;
|
|
} while (entry != null);
|
|
}
|
|
};
|
|
AnimationState.prototype.computeHold = function (entry) {
|
|
var to = entry.mixingTo;
|
|
var timelines = entry.animation.timelines;
|
|
var timelinesCount = entry.animation.timelines.length;
|
|
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
|
|
entry.timelineHoldMix.length = 0;
|
|
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
|
|
var propertyIDs = this.propertyIDs;
|
|
if (to != null && to.holdPrevious) {
|
|
for (var i = 0; i < timelinesCount; i++) {
|
|
timelineMode[i] = propertyIDs.add(timelines[i].getPropertyId()) ? AnimationState.HOLD_FIRST : AnimationState.HOLD_SUBSEQUENT;
|
|
}
|
|
return;
|
|
}
|
|
outer: for (var i = 0; i < timelinesCount; i++) {
|
|
var timeline = timelines[i];
|
|
var id = timeline.getPropertyId();
|
|
if (!propertyIDs.add(id))
|
|
timelineMode[i] = AnimationState.SUBSEQUENT;
|
|
else if (to == null || timeline instanceof spine.AttachmentTimeline || timeline instanceof spine.DrawOrderTimeline
|
|
|| timeline instanceof spine.EventTimeline || !to.animation.hasTimeline(id)) {
|
|
timelineMode[i] = AnimationState.FIRST;
|
|
}
|
|
else {
|
|
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
|
|
if (next.animation.hasTimeline(id))
|
|
continue;
|
|
if (entry.mixDuration > 0) {
|
|
timelineMode[i] = AnimationState.HOLD_MIX;
|
|
timelineDipMix[i] = next;
|
|
continue outer;
|
|
}
|
|
break;
|
|
}
|
|
timelineMode[i] = AnimationState.HOLD_FIRST;
|
|
}
|
|
}
|
|
};
|
|
AnimationState.prototype.getCurrent = function (trackIndex) {
|
|
if (trackIndex >= this.tracks.length)
|
|
return null;
|
|
return this.tracks[trackIndex];
|
|
};
|
|
AnimationState.prototype.addListener = function (listener) {
|
|
if (listener == null)
|
|
throw new Error("listener cannot be null.");
|
|
this.listeners.push(listener);
|
|
};
|
|
AnimationState.prototype.removeListener = function (listener) {
|
|
var index = this.listeners.indexOf(listener);
|
|
if (index >= 0)
|
|
this.listeners.splice(index, 1);
|
|
};
|
|
AnimationState.prototype.clearListeners = function () {
|
|
this.listeners.length = 0;
|
|
};
|
|
AnimationState.prototype.clearListenerNotifications = function () {
|
|
this.queue.clear();
|
|
};
|
|
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
|
|
AnimationState.SUBSEQUENT = 0;
|
|
AnimationState.FIRST = 1;
|
|
AnimationState.HOLD_SUBSEQUENT = 2;
|
|
AnimationState.HOLD_FIRST = 3;
|
|
AnimationState.HOLD_MIX = 4;
|
|
AnimationState.SETUP = 1;
|
|
AnimationState.CURRENT = 2;
|
|
return AnimationState;
|
|
}());
|
|
spine.AnimationState = AnimationState;
|
|
var TrackEntry = (function () {
|
|
function TrackEntry() {
|
|
this.mixBlend = spine.MixBlend.replace;
|
|
this.timelineMode = new Array();
|
|
this.timelineHoldMix = new Array();
|
|
this.timelinesRotation = new Array();
|
|
}
|
|
TrackEntry.prototype.reset = function () {
|
|
this.next = null;
|
|
this.mixingFrom = null;
|
|
this.mixingTo = null;
|
|
this.animation = null;
|
|
this.listener = null;
|
|
this.timelineMode.length = 0;
|
|
this.timelineHoldMix.length = 0;
|
|
this.timelinesRotation.length = 0;
|
|
};
|
|
TrackEntry.prototype.getAnimationTime = function () {
|
|
if (this.loop) {
|
|
var duration = this.animationEnd - this.animationStart;
|
|
if (duration == 0)
|
|
return this.animationStart;
|
|
return (this.trackTime % duration) + this.animationStart;
|
|
}
|
|
return Math.min(this.trackTime + this.animationStart, this.animationEnd);
|
|
};
|
|
TrackEntry.prototype.setAnimationLast = function (animationLast) {
|
|
this.animationLast = animationLast;
|
|
this.nextAnimationLast = animationLast;
|
|
};
|
|
TrackEntry.prototype.isComplete = function () {
|
|
return this.trackTime >= this.animationEnd - this.animationStart;
|
|
};
|
|
TrackEntry.prototype.resetRotationDirections = function () {
|
|
this.timelinesRotation.length = 0;
|
|
};
|
|
return TrackEntry;
|
|
}());
|
|
spine.TrackEntry = TrackEntry;
|
|
var EventQueue = (function () {
|
|
function EventQueue(animState) {
|
|
this.objects = [];
|
|
this.drainDisabled = false;
|
|
this.animState = animState;
|
|
}
|
|
EventQueue.prototype.start = function (entry) {
|
|
this.objects.push(EventType.start);
|
|
this.objects.push(entry);
|
|
this.animState.animationsChanged = true;
|
|
};
|
|
EventQueue.prototype.interrupt = function (entry) {
|
|
this.objects.push(EventType.interrupt);
|
|
this.objects.push(entry);
|
|
};
|
|
EventQueue.prototype.end = function (entry) {
|
|
this.objects.push(EventType.end);
|
|
this.objects.push(entry);
|
|
this.animState.animationsChanged = true;
|
|
};
|
|
EventQueue.prototype.dispose = function (entry) {
|
|
this.objects.push(EventType.dispose);
|
|
this.objects.push(entry);
|
|
};
|
|
EventQueue.prototype.complete = function (entry) {
|
|
this.objects.push(EventType.complete);
|
|
this.objects.push(entry);
|
|
};
|
|
EventQueue.prototype.event = function (entry, event) {
|
|
this.objects.push(EventType.event);
|
|
this.objects.push(entry);
|
|
this.objects.push(event);
|
|
};
|
|
EventQueue.prototype.drain = function () {
|
|
if (this.drainDisabled)
|
|
return;
|
|
this.drainDisabled = true;
|
|
var objects = this.objects;
|
|
var listeners = this.animState.listeners;
|
|
for (var i = 0; i < objects.length; i += 2) {
|
|
var type = objects[i];
|
|
var entry = objects[i + 1];
|
|
switch (type) {
|
|
case EventType.start:
|
|
if (entry.listener != null && entry.listener.start)
|
|
entry.listener.start(entry);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].start)
|
|
listeners[ii].start(entry);
|
|
break;
|
|
case EventType.interrupt:
|
|
if (entry.listener != null && entry.listener.interrupt)
|
|
entry.listener.interrupt(entry);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].interrupt)
|
|
listeners[ii].interrupt(entry);
|
|
break;
|
|
case EventType.end:
|
|
if (entry.listener != null && entry.listener.end)
|
|
entry.listener.end(entry);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].end)
|
|
listeners[ii].end(entry);
|
|
case EventType.dispose:
|
|
if (entry.listener != null && entry.listener.dispose)
|
|
entry.listener.dispose(entry);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].dispose)
|
|
listeners[ii].dispose(entry);
|
|
this.animState.trackEntryPool.free(entry);
|
|
break;
|
|
case EventType.complete:
|
|
if (entry.listener != null && entry.listener.complete)
|
|
entry.listener.complete(entry);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].complete)
|
|
listeners[ii].complete(entry);
|
|
break;
|
|
case EventType.event:
|
|
var event_3 = objects[i++ + 2];
|
|
if (entry.listener != null && entry.listener.event)
|
|
entry.listener.event(entry, event_3);
|
|
for (var ii = 0; ii < listeners.length; ii++)
|
|
if (listeners[ii].event)
|
|
listeners[ii].event(entry, event_3);
|
|
break;
|
|
}
|
|
}
|
|
this.clear();
|
|
this.drainDisabled = false;
|
|
};
|
|
EventQueue.prototype.clear = function () {
|
|
this.objects.length = 0;
|
|
};
|
|
return EventQueue;
|
|
}());
|
|
spine.EventQueue = EventQueue;
|
|
var EventType;
|
|
(function (EventType) {
|
|
EventType[EventType["start"] = 0] = "start";
|
|
EventType[EventType["interrupt"] = 1] = "interrupt";
|
|
EventType[EventType["end"] = 2] = "end";
|
|
EventType[EventType["dispose"] = 3] = "dispose";
|
|
EventType[EventType["complete"] = 4] = "complete";
|
|
EventType[EventType["event"] = 5] = "event";
|
|
})(EventType = spine.EventType || (spine.EventType = {}));
|
|
var AnimationStateAdapter = (function () {
|
|
function AnimationStateAdapter() {
|
|
}
|
|
AnimationStateAdapter.prototype.start = function (entry) {
|
|
};
|
|
AnimationStateAdapter.prototype.interrupt = function (entry) {
|
|
};
|
|
AnimationStateAdapter.prototype.end = function (entry) {
|
|
};
|
|
AnimationStateAdapter.prototype.dispose = function (entry) {
|
|
};
|
|
AnimationStateAdapter.prototype.complete = function (entry) {
|
|
};
|
|
AnimationStateAdapter.prototype.event = function (entry, event) {
|
|
};
|
|
return AnimationStateAdapter;
|
|
}());
|
|
spine.AnimationStateAdapter = AnimationStateAdapter;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var AnimationStateData = (function () {
|
|
function AnimationStateData(skeletonData) {
|
|
this.animationToMixTime = {};
|
|
this.defaultMix = 0;
|
|
if (skeletonData == null)
|
|
throw new Error("skeletonData cannot be null.");
|
|
this.skeletonData = skeletonData;
|
|
}
|
|
AnimationStateData.prototype.setMix = function (fromName, toName, duration) {
|
|
var from = this.skeletonData.findAnimation(fromName);
|
|
if (from == null)
|
|
throw new Error("Animation not found: " + fromName);
|
|
var to = this.skeletonData.findAnimation(toName);
|
|
if (to == null)
|
|
throw new Error("Animation not found: " + toName);
|
|
this.setMixWith(from, to, duration);
|
|
};
|
|
AnimationStateData.prototype.setMixWith = function (from, to, duration) {
|
|
if (from == null)
|
|
throw new Error("from cannot be null.");
|
|
if (to == null)
|
|
throw new Error("to cannot be null.");
|
|
var key = from.name + "." + to.name;
|
|
this.animationToMixTime[key] = duration;
|
|
};
|
|
AnimationStateData.prototype.getMix = function (from, to) {
|
|
var key = from.name + "." + to.name;
|
|
var value = this.animationToMixTime[key];
|
|
return value === undefined ? this.defaultMix : value;
|
|
};
|
|
return AnimationStateData;
|
|
}());
|
|
spine.AnimationStateData = AnimationStateData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var AssetManager = (function () {
|
|
function AssetManager(textureLoader, pathPrefix) {
|
|
if (pathPrefix === void 0) { pathPrefix = ""; }
|
|
this.assets = {};
|
|
this.errors = {};
|
|
this.toLoad = 0;
|
|
this.loaded = 0;
|
|
this.rawDataUris = {};
|
|
this.textureLoader = textureLoader;
|
|
this.pathPrefix = pathPrefix;
|
|
}
|
|
AssetManager.prototype.downloadText = function (url, success, error) {
|
|
var request = new XMLHttpRequest();
|
|
request.overrideMimeType("text/html");
|
|
if (this.rawDataUris[url])
|
|
url = this.rawDataUris[url];
|
|
request.open("GET", url, true);
|
|
request.onload = function () {
|
|
if (request.status == 200) {
|
|
success(request.responseText);
|
|
}
|
|
else {
|
|
error(request.status, request.responseText);
|
|
}
|
|
};
|
|
request.onerror = function () {
|
|
error(request.status, request.responseText);
|
|
};
|
|
request.send();
|
|
};
|
|
AssetManager.prototype.downloadBinary = function (url, success, error) {
|
|
var request = new XMLHttpRequest();
|
|
if (this.rawDataUris[url])
|
|
url = this.rawDataUris[url];
|
|
request.open("GET", url, true);
|
|
request.responseType = "arraybuffer";
|
|
request.onload = function () {
|
|
if (request.status == 200) {
|
|
success(new Uint8Array(request.response));
|
|
}
|
|
else {
|
|
error(request.status, request.responseText);
|
|
}
|
|
};
|
|
request.onerror = function () {
|
|
error(request.status, request.responseText);
|
|
};
|
|
request.send();
|
|
};
|
|
AssetManager.prototype.setRawDataURI = function (path, data) {
|
|
this.rawDataUris[this.pathPrefix + path] = data;
|
|
};
|
|
AssetManager.prototype.loadBinary = function (path, success, error) {
|
|
var _this = this;
|
|
if (success === void 0) { success = null; }
|
|
if (error === void 0) { error = null; }
|
|
path = this.pathPrefix + path;
|
|
this.toLoad++;
|
|
this.downloadBinary(path, function (data) {
|
|
_this.assets[path] = data;
|
|
if (success)
|
|
success(path, data);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}, function (state, responseText) {
|
|
_this.errors[path] = "Couldn't load binary " + path + ": status " + status + ", " + responseText;
|
|
if (error)
|
|
error(path, "Couldn't load binary " + path + ": status " + status + ", " + responseText);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
});
|
|
};
|
|
AssetManager.prototype.loadText = function (path, success, error) {
|
|
var _this = this;
|
|
if (success === void 0) { success = null; }
|
|
if (error === void 0) { error = null; }
|
|
path = this.pathPrefix + path;
|
|
this.toLoad++;
|
|
this.downloadText(path, function (data) {
|
|
_this.assets[path] = data;
|
|
if (success)
|
|
success(path, data);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}, function (state, responseText) {
|
|
_this.errors[path] = "Couldn't load text " + path + ": status " + status + ", " + responseText;
|
|
if (error)
|
|
error(path, "Couldn't load text " + path + ": status " + status + ", " + responseText);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
});
|
|
};
|
|
AssetManager.prototype.loadTexture = function (path, success, error) {
|
|
var _this = this;
|
|
if (success === void 0) { success = null; }
|
|
if (error === void 0) { error = null; }
|
|
path = this.pathPrefix + path;
|
|
var storagePath = path;
|
|
this.toLoad++;
|
|
var img = new Image();
|
|
img.crossOrigin = "anonymous";
|
|
img.onload = function (ev) {
|
|
var texture = _this.textureLoader(img);
|
|
_this.assets[storagePath] = texture;
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
if (success)
|
|
success(path, img);
|
|
};
|
|
img.onerror = function (ev) {
|
|
_this.errors[path] = "Couldn't load image " + path;
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
if (error)
|
|
error(path, "Couldn't load image " + path);
|
|
};
|
|
if (this.rawDataUris[path])
|
|
path = this.rawDataUris[path];
|
|
img.src = path;
|
|
};
|
|
AssetManager.prototype.loadTextureAtlas = function (path, success, error) {
|
|
var _this = this;
|
|
if (success === void 0) { success = null; }
|
|
if (error === void 0) { error = null; }
|
|
var parent = path.lastIndexOf("/") >= 0 ? path.substring(0, path.lastIndexOf("/")) : "";
|
|
path = this.pathPrefix + path;
|
|
this.toLoad++;
|
|
this.downloadText(path, function (atlasData) {
|
|
var pagesLoaded = { count: 0 };
|
|
var atlasPages = new Array();
|
|
try {
|
|
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
|
atlasPages.push(parent == "" ? path : parent + "/" + path);
|
|
var image = document.createElement("img");
|
|
image.width = 16;
|
|
image.height = 16;
|
|
return new spine.FakeTexture(image);
|
|
});
|
|
}
|
|
catch (e) {
|
|
var ex = e;
|
|
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
|
if (error)
|
|
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
return;
|
|
}
|
|
var _loop_1 = function (atlasPage) {
|
|
var pageLoadError = false;
|
|
_this.loadTexture(atlasPage, function (imagePath, image) {
|
|
pagesLoaded.count++;
|
|
if (pagesLoaded.count == atlasPages.length) {
|
|
if (!pageLoadError) {
|
|
try {
|
|
var atlas = new spine.TextureAtlas(atlasData, function (path) {
|
|
return _this.get(parent == "" ? path : parent + "/" + path);
|
|
});
|
|
_this.assets[path] = atlas;
|
|
if (success)
|
|
success(path, atlas);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}
|
|
catch (e) {
|
|
var ex = e;
|
|
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
|
if (error)
|
|
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}
|
|
}
|
|
else {
|
|
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
|
if (error)
|
|
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}
|
|
}
|
|
}, function (imagePath, errorMessage) {
|
|
pageLoadError = true;
|
|
pagesLoaded.count++;
|
|
if (pagesLoaded.count == atlasPages.length) {
|
|
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
|
if (error)
|
|
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
}
|
|
});
|
|
};
|
|
for (var _i = 0, atlasPages_1 = atlasPages; _i < atlasPages_1.length; _i++) {
|
|
var atlasPage = atlasPages_1[_i];
|
|
_loop_1(atlasPage);
|
|
}
|
|
}, function (state, responseText) {
|
|
_this.errors[path] = "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText;
|
|
if (error)
|
|
error(path, "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText);
|
|
_this.toLoad--;
|
|
_this.loaded++;
|
|
});
|
|
};
|
|
AssetManager.prototype.get = function (path) {
|
|
path = this.pathPrefix + path;
|
|
return this.assets[path];
|
|
};
|
|
AssetManager.prototype.remove = function (path) {
|
|
path = this.pathPrefix + path;
|
|
var asset = this.assets[path];
|
|
if (asset.dispose)
|
|
asset.dispose();
|
|
this.assets[path] = null;
|
|
};
|
|
AssetManager.prototype.removeAll = function () {
|
|
for (var key in this.assets) {
|
|
var asset = this.assets[key];
|
|
if (asset.dispose)
|
|
asset.dispose();
|
|
}
|
|
this.assets = {};
|
|
};
|
|
AssetManager.prototype.isLoadingComplete = function () {
|
|
return this.toLoad == 0;
|
|
};
|
|
AssetManager.prototype.getToLoad = function () {
|
|
return this.toLoad;
|
|
};
|
|
AssetManager.prototype.getLoaded = function () {
|
|
return this.loaded;
|
|
};
|
|
AssetManager.prototype.dispose = function () {
|
|
this.removeAll();
|
|
};
|
|
AssetManager.prototype.hasErrors = function () {
|
|
return Object.keys(this.errors).length > 0;
|
|
};
|
|
AssetManager.prototype.getErrors = function () {
|
|
return this.errors;
|
|
};
|
|
return AssetManager;
|
|
}());
|
|
spine.AssetManager = AssetManager;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var AtlasAttachmentLoader = (function () {
|
|
function AtlasAttachmentLoader(atlas) {
|
|
this.atlas = atlas;
|
|
}
|
|
AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) {
|
|
var region = this.atlas.findRegion(path);
|
|
if (region == null)
|
|
throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
|
|
region.renderObject = region;
|
|
var attachment = new spine.RegionAttachment(name);
|
|
attachment.setRegion(region);
|
|
return attachment;
|
|
};
|
|
AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) {
|
|
var region = this.atlas.findRegion(path);
|
|
if (region == null)
|
|
throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
|
|
region.renderObject = region;
|
|
var attachment = new spine.MeshAttachment(name);
|
|
attachment.region = region;
|
|
return attachment;
|
|
};
|
|
AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) {
|
|
return new spine.BoundingBoxAttachment(name);
|
|
};
|
|
AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) {
|
|
return new spine.PathAttachment(name);
|
|
};
|
|
AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
|
|
return new spine.PointAttachment(name);
|
|
};
|
|
AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
|
|
return new spine.ClippingAttachment(name);
|
|
};
|
|
return AtlasAttachmentLoader;
|
|
}());
|
|
spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var BlendMode;
|
|
(function (BlendMode) {
|
|
BlendMode[BlendMode["Normal"] = 0] = "Normal";
|
|
BlendMode[BlendMode["Additive"] = 1] = "Additive";
|
|
BlendMode[BlendMode["Multiply"] = 2] = "Multiply";
|
|
BlendMode[BlendMode["Screen"] = 3] = "Screen";
|
|
})(BlendMode = spine.BlendMode || (spine.BlendMode = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Bone = (function () {
|
|
function Bone(data, skeleton, parent) {
|
|
this.children = new Array();
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.rotation = 0;
|
|
this.scaleX = 0;
|
|
this.scaleY = 0;
|
|
this.shearX = 0;
|
|
this.shearY = 0;
|
|
this.ax = 0;
|
|
this.ay = 0;
|
|
this.arotation = 0;
|
|
this.ascaleX = 0;
|
|
this.ascaleY = 0;
|
|
this.ashearX = 0;
|
|
this.ashearY = 0;
|
|
this.appliedValid = false;
|
|
this.a = 0;
|
|
this.b = 0;
|
|
this.c = 0;
|
|
this.d = 0;
|
|
this.worldY = 0;
|
|
this.worldX = 0;
|
|
this.sorted = false;
|
|
this.active = false;
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
this.data = data;
|
|
this.skeleton = skeleton;
|
|
this.parent = parent;
|
|
this.setToSetupPose();
|
|
}
|
|
Bone.prototype.isActive = function () {
|
|
return this.active;
|
|
};
|
|
Bone.prototype.update = function () {
|
|
this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
|
|
};
|
|
Bone.prototype.updateWorldTransform = function () {
|
|
this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
|
|
};
|
|
Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) {
|
|
this.ax = x;
|
|
this.ay = y;
|
|
this.arotation = rotation;
|
|
this.ascaleX = scaleX;
|
|
this.ascaleY = scaleY;
|
|
this.ashearX = shearX;
|
|
this.ashearY = shearY;
|
|
this.appliedValid = true;
|
|
var parent = this.parent;
|
|
if (parent == null) {
|
|
var skeleton = this.skeleton;
|
|
var rotationY = rotation + 90 + shearY;
|
|
var sx = skeleton.scaleX;
|
|
var sy = skeleton.scaleY;
|
|
this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX * sx;
|
|
this.b = spine.MathUtils.cosDeg(rotationY) * scaleY * sx;
|
|
this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX * sy;
|
|
this.d = spine.MathUtils.sinDeg(rotationY) * scaleY * sy;
|
|
this.worldX = x * sx + skeleton.x;
|
|
this.worldY = y * sy + skeleton.y;
|
|
return;
|
|
}
|
|
var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
|
this.worldX = pa * x + pb * y + parent.worldX;
|
|
this.worldY = pc * x + pd * y + parent.worldY;
|
|
switch (this.data.transformMode) {
|
|
case spine.TransformMode.Normal: {
|
|
var rotationY = rotation + 90 + shearY;
|
|
var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
|
|
var lb = spine.MathUtils.cosDeg(rotationY) * scaleY;
|
|
var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
|
|
var ld = spine.MathUtils.sinDeg(rotationY) * scaleY;
|
|
this.a = pa * la + pb * lc;
|
|
this.b = pa * lb + pb * ld;
|
|
this.c = pc * la + pd * lc;
|
|
this.d = pc * lb + pd * ld;
|
|
return;
|
|
}
|
|
case spine.TransformMode.OnlyTranslation: {
|
|
var rotationY = rotation + 90 + shearY;
|
|
this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
|
|
this.b = spine.MathUtils.cosDeg(rotationY) * scaleY;
|
|
this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
|
|
this.d = spine.MathUtils.sinDeg(rotationY) * scaleY;
|
|
break;
|
|
}
|
|
case spine.TransformMode.NoRotationOrReflection: {
|
|
var s = pa * pa + pc * pc;
|
|
var prx = 0;
|
|
if (s > 0.0001) {
|
|
s = Math.abs(pa * pd - pb * pc) / s;
|
|
pa /= this.skeleton.scaleX;
|
|
pc /= this.skeleton.scaleY;
|
|
pb = pc * s;
|
|
pd = pa * s;
|
|
prx = Math.atan2(pc, pa) * spine.MathUtils.radDeg;
|
|
}
|
|
else {
|
|
pa = 0;
|
|
pc = 0;
|
|
prx = 90 - Math.atan2(pd, pb) * spine.MathUtils.radDeg;
|
|
}
|
|
var rx = rotation + shearX - prx;
|
|
var ry = rotation + shearY - prx + 90;
|
|
var la = spine.MathUtils.cosDeg(rx) * scaleX;
|
|
var lb = spine.MathUtils.cosDeg(ry) * scaleY;
|
|
var lc = spine.MathUtils.sinDeg(rx) * scaleX;
|
|
var ld = spine.MathUtils.sinDeg(ry) * scaleY;
|
|
this.a = pa * la - pb * lc;
|
|
this.b = pa * lb - pb * ld;
|
|
this.c = pc * la + pd * lc;
|
|
this.d = pc * lb + pd * ld;
|
|
break;
|
|
}
|
|
case spine.TransformMode.NoScale:
|
|
case spine.TransformMode.NoScaleOrReflection: {
|
|
var cos = spine.MathUtils.cosDeg(rotation);
|
|
var sin = spine.MathUtils.sinDeg(rotation);
|
|
var za = (pa * cos + pb * sin) / this.skeleton.scaleX;
|
|
var zc = (pc * cos + pd * sin) / this.skeleton.scaleY;
|
|
var s = Math.sqrt(za * za + zc * zc);
|
|
if (s > 0.00001)
|
|
s = 1 / s;
|
|
za *= s;
|
|
zc *= s;
|
|
s = Math.sqrt(za * za + zc * zc);
|
|
if (this.data.transformMode == spine.TransformMode.NoScale
|
|
&& (pa * pd - pb * pc < 0) != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))
|
|
s = -s;
|
|
var r = Math.PI / 2 + Math.atan2(zc, za);
|
|
var zb = Math.cos(r) * s;
|
|
var zd = Math.sin(r) * s;
|
|
var la = spine.MathUtils.cosDeg(shearX) * scaleX;
|
|
var lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY;
|
|
var lc = spine.MathUtils.sinDeg(shearX) * scaleX;
|
|
var ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY;
|
|
this.a = za * la + zb * lc;
|
|
this.b = za * lb + zb * ld;
|
|
this.c = zc * la + zd * lc;
|
|
this.d = zc * lb + zd * ld;
|
|
break;
|
|
}
|
|
}
|
|
this.a *= this.skeleton.scaleX;
|
|
this.b *= this.skeleton.scaleX;
|
|
this.c *= this.skeleton.scaleY;
|
|
this.d *= this.skeleton.scaleY;
|
|
};
|
|
Bone.prototype.setToSetupPose = function () {
|
|
var data = this.data;
|
|
this.x = data.x;
|
|
this.y = data.y;
|
|
this.rotation = data.rotation;
|
|
this.scaleX = data.scaleX;
|
|
this.scaleY = data.scaleY;
|
|
this.shearX = data.shearX;
|
|
this.shearY = data.shearY;
|
|
};
|
|
Bone.prototype.getWorldRotationX = function () {
|
|
return Math.atan2(this.c, this.a) * spine.MathUtils.radDeg;
|
|
};
|
|
Bone.prototype.getWorldRotationY = function () {
|
|
return Math.atan2(this.d, this.b) * spine.MathUtils.radDeg;
|
|
};
|
|
Bone.prototype.getWorldScaleX = function () {
|
|
return Math.sqrt(this.a * this.a + this.c * this.c);
|
|
};
|
|
Bone.prototype.getWorldScaleY = function () {
|
|
return Math.sqrt(this.b * this.b + this.d * this.d);
|
|
};
|
|
Bone.prototype.updateAppliedTransform = function () {
|
|
this.appliedValid = true;
|
|
var parent = this.parent;
|
|
if (parent == null) {
|
|
this.ax = this.worldX;
|
|
this.ay = this.worldY;
|
|
this.arotation = Math.atan2(this.c, this.a) * spine.MathUtils.radDeg;
|
|
this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c);
|
|
this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d);
|
|
this.ashearX = 0;
|
|
this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * spine.MathUtils.radDeg;
|
|
return;
|
|
}
|
|
var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
|
var pid = 1 / (pa * pd - pb * pc);
|
|
var dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY;
|
|
this.ax = (dx * pd * pid - dy * pb * pid);
|
|
this.ay = (dy * pa * pid - dx * pc * pid);
|
|
var ia = pid * pd;
|
|
var id = pid * pa;
|
|
var ib = pid * pb;
|
|
var ic = pid * pc;
|
|
var ra = ia * this.a - ib * this.c;
|
|
var rb = ia * this.b - ib * this.d;
|
|
var rc = id * this.c - ic * this.a;
|
|
var rd = id * this.d - ic * this.b;
|
|
this.ashearX = 0;
|
|
this.ascaleX = Math.sqrt(ra * ra + rc * rc);
|
|
if (this.ascaleX > 0.0001) {
|
|
var det = ra * rd - rb * rc;
|
|
this.ascaleY = det / this.ascaleX;
|
|
this.ashearY = Math.atan2(ra * rb + rc * rd, det) * spine.MathUtils.radDeg;
|
|
this.arotation = Math.atan2(rc, ra) * spine.MathUtils.radDeg;
|
|
}
|
|
else {
|
|
this.ascaleX = 0;
|
|
this.ascaleY = Math.sqrt(rb * rb + rd * rd);
|
|
this.ashearY = 0;
|
|
this.arotation = 90 - Math.atan2(rd, rb) * spine.MathUtils.radDeg;
|
|
}
|
|
};
|
|
Bone.prototype.worldToLocal = function (world) {
|
|
var a = this.a, b = this.b, c = this.c, d = this.d;
|
|
var invDet = 1 / (a * d - b * c);
|
|
var x = world.x - this.worldX, y = world.y - this.worldY;
|
|
world.x = (x * d * invDet - y * b * invDet);
|
|
world.y = (y * a * invDet - x * c * invDet);
|
|
return world;
|
|
};
|
|
Bone.prototype.localToWorld = function (local) {
|
|
var x = local.x, y = local.y;
|
|
local.x = x * this.a + y * this.b + this.worldX;
|
|
local.y = x * this.c + y * this.d + this.worldY;
|
|
return local;
|
|
};
|
|
Bone.prototype.worldToLocalRotation = function (worldRotation) {
|
|
var sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation);
|
|
return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg + this.rotation - this.shearX;
|
|
};
|
|
Bone.prototype.localToWorldRotation = function (localRotation) {
|
|
localRotation -= this.rotation - this.shearX;
|
|
var sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation);
|
|
return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg;
|
|
};
|
|
Bone.prototype.rotateWorld = function (degrees) {
|
|
var a = this.a, b = this.b, c = this.c, d = this.d;
|
|
var cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees);
|
|
this.a = cos * a - sin * c;
|
|
this.b = cos * b - sin * d;
|
|
this.c = sin * a + cos * c;
|
|
this.d = sin * b + cos * d;
|
|
this.appliedValid = false;
|
|
};
|
|
return Bone;
|
|
}());
|
|
spine.Bone = Bone;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var BoneData = (function () {
|
|
function BoneData(index, name, parent) {
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.rotation = 0;
|
|
this.scaleX = 1;
|
|
this.scaleY = 1;
|
|
this.shearX = 0;
|
|
this.shearY = 0;
|
|
this.transformMode = TransformMode.Normal;
|
|
this.skinRequired = false;
|
|
this.color = new spine.Color();
|
|
if (index < 0)
|
|
throw new Error("index must be >= 0.");
|
|
if (name == null)
|
|
throw new Error("name cannot be null.");
|
|
this.index = index;
|
|
this.name = name;
|
|
this.parent = parent;
|
|
}
|
|
return BoneData;
|
|
}());
|
|
spine.BoneData = BoneData;
|
|
var TransformMode;
|
|
(function (TransformMode) {
|
|
TransformMode[TransformMode["Normal"] = 0] = "Normal";
|
|
TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation";
|
|
TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection";
|
|
TransformMode[TransformMode["NoScale"] = 3] = "NoScale";
|
|
TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection";
|
|
})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var ConstraintData = (function () {
|
|
function ConstraintData(name, order, skinRequired) {
|
|
this.name = name;
|
|
this.order = order;
|
|
this.skinRequired = skinRequired;
|
|
}
|
|
return ConstraintData;
|
|
}());
|
|
spine.ConstraintData = ConstraintData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Event = (function () {
|
|
function Event(time, data) {
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
this.time = time;
|
|
this.data = data;
|
|
}
|
|
return Event;
|
|
}());
|
|
spine.Event = Event;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var EventData = (function () {
|
|
function EventData(name) {
|
|
this.name = name;
|
|
}
|
|
return EventData;
|
|
}());
|
|
spine.EventData = EventData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var IkConstraint = (function () {
|
|
function IkConstraint(data, skeleton) {
|
|
this.bendDirection = 0;
|
|
this.compress = false;
|
|
this.stretch = false;
|
|
this.mix = 1;
|
|
this.softness = 0;
|
|
this.active = false;
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
this.data = data;
|
|
this.mix = data.mix;
|
|
this.softness = data.softness;
|
|
this.bendDirection = data.bendDirection;
|
|
this.compress = data.compress;
|
|
this.stretch = data.stretch;
|
|
this.bones = new Array();
|
|
for (var i = 0; i < data.bones.length; i++)
|
|
this.bones.push(skeleton.findBone(data.bones[i].name));
|
|
this.target = skeleton.findBone(data.target.name);
|
|
}
|
|
IkConstraint.prototype.isActive = function () {
|
|
return this.active;
|
|
};
|
|
IkConstraint.prototype.apply = function () {
|
|
this.update();
|
|
};
|
|
IkConstraint.prototype.update = function () {
|
|
var target = this.target;
|
|
var bones = this.bones;
|
|
switch (bones.length) {
|
|
case 1:
|
|
this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix);
|
|
break;
|
|
case 2:
|
|
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.softness, this.mix);
|
|
break;
|
|
}
|
|
};
|
|
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) {
|
|
if (!bone.appliedValid)
|
|
bone.updateAppliedTransform();
|
|
var p = bone.parent;
|
|
var pa = p.a, pb = p.b, pc = p.c, pd = p.d;
|
|
var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;
|
|
switch (bone.data.transformMode) {
|
|
case spine.TransformMode.OnlyTranslation:
|
|
tx = targetX - bone.worldX;
|
|
ty = targetY - bone.worldY;
|
|
break;
|
|
case spine.TransformMode.NoRotationOrReflection:
|
|
var s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
|
var sa = pa / bone.skeleton.scaleX;
|
|
var sc = pc / bone.skeleton.scaleY;
|
|
pb = -sc * s * bone.skeleton.scaleX;
|
|
pd = sa * s * bone.skeleton.scaleY;
|
|
rotationIK += Math.atan2(sc, sa) * spine.MathUtils.radDeg;
|
|
default:
|
|
var x = targetX - p.worldX, y = targetY - p.worldY;
|
|
var d = pa * pd - pb * pc;
|
|
tx = (x * pd - y * pb) / d - bone.ax;
|
|
ty = (y * pa - x * pc) / d - bone.ay;
|
|
}
|
|
rotationIK += Math.atan2(ty, tx) * spine.MathUtils.radDeg;
|
|
if (bone.ascaleX < 0)
|
|
rotationIK += 180;
|
|
if (rotationIK > 180)
|
|
rotationIK -= 360;
|
|
else if (rotationIK < -180)
|
|
rotationIK += 360;
|
|
var sx = bone.ascaleX, sy = bone.ascaleY;
|
|
if (compress || stretch) {
|
|
switch (bone.data.transformMode) {
|
|
case spine.TransformMode.NoScale:
|
|
case spine.TransformMode.NoScaleOrReflection:
|
|
tx = targetX - bone.worldX;
|
|
ty = targetY - bone.worldY;
|
|
}
|
|
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
|
|
if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) {
|
|
var s = (dd / b - 1) * alpha + 1;
|
|
sx *= s;
|
|
if (uniform)
|
|
sy *= s;
|
|
}
|
|
}
|
|
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY);
|
|
};
|
|
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, softness, alpha) {
|
|
if (alpha == 0) {
|
|
child.updateWorldTransform();
|
|
return;
|
|
}
|
|
if (!parent.appliedValid)
|
|
parent.updateAppliedTransform();
|
|
if (!child.appliedValid)
|
|
child.updateAppliedTransform();
|
|
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
|
|
var os1 = 0, os2 = 0, s2 = 0;
|
|
if (psx < 0) {
|
|
psx = -psx;
|
|
os1 = 180;
|
|
s2 = -1;
|
|
}
|
|
else {
|
|
os1 = 0;
|
|
s2 = 1;
|
|
}
|
|
if (psy < 0) {
|
|
psy = -psy;
|
|
s2 = -s2;
|
|
}
|
|
if (csx < 0) {
|
|
csx = -csx;
|
|
os2 = 180;
|
|
}
|
|
else
|
|
os2 = 0;
|
|
var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;
|
|
var u = Math.abs(psx - psy) <= 0.0001;
|
|
if (!u) {
|
|
cy = 0;
|
|
cwx = a * cx + parent.worldX;
|
|
cwy = c * cx + parent.worldY;
|
|
}
|
|
else {
|
|
cy = child.ay;
|
|
cwx = a * cx + b * cy + parent.worldX;
|
|
cwy = c * cx + d * cy + parent.worldY;
|
|
}
|
|
var pp = parent.parent;
|
|
a = pp.a;
|
|
b = pp.b;
|
|
c = pp.c;
|
|
d = pp.d;
|
|
var id = 1 / (a * d - b * c), x = cwx - pp.worldX, y = cwy - pp.worldY;
|
|
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
|
|
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2;
|
|
if (l1 < 0.0001) {
|
|
this.apply1(parent, targetX, targetY, false, stretch, false, alpha);
|
|
child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
|
|
return;
|
|
}
|
|
x = targetX - pp.worldX;
|
|
y = targetY - pp.worldY;
|
|
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
|
|
var dd = tx * tx + ty * ty;
|
|
if (softness != 0) {
|
|
softness *= psx * (csx + 1) / 2;
|
|
var td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness;
|
|
if (sd > 0) {
|
|
var p = Math.min(1, sd / (softness * 2)) - 1;
|
|
p = (sd - softness * (1 - p * p)) / td;
|
|
tx -= p * tx;
|
|
ty -= p * ty;
|
|
dd = tx * tx + ty * ty;
|
|
}
|
|
}
|
|
outer: if (u) {
|
|
l2 *= psx;
|
|
var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
|
if (cos < -1)
|
|
cos = -1;
|
|
else if (cos > 1) {
|
|
cos = 1;
|
|
if (stretch)
|
|
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
|
|
}
|
|
a2 = Math.acos(cos) * bendDir;
|
|
a = l1 + l2 * cos;
|
|
b = l2 * Math.sin(a2);
|
|
a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
|
|
}
|
|
else {
|
|
a = psx * l2;
|
|
b = psy * l2;
|
|
var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
|
|
c = bb * l1 * l1 + aa * dd - aa * bb;
|
|
var c1 = -2 * bb * l1, c2 = bb - aa;
|
|
d = c1 * c1 - 4 * c2 * c;
|
|
if (d >= 0) {
|
|
var q = Math.sqrt(d);
|
|
if (c1 < 0)
|
|
q = -q;
|
|
q = -(c1 + q) / 2;
|
|
var r0 = q / c2, r1 = c / q;
|
|
var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
|
|
if (r * r <= dd) {
|
|
y = Math.sqrt(dd - r * r) * bendDir;
|
|
a1 = ta - Math.atan2(y, r);
|
|
a2 = Math.atan2(y / psy, (r - l1) / psx);
|
|
break outer;
|
|
}
|
|
}
|
|
var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
|
|
var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
|
|
c = -a * l1 / (aa - bb);
|
|
if (c >= -1 && c <= 1) {
|
|
c = Math.acos(c);
|
|
x = a * Math.cos(c) + l1;
|
|
y = b * Math.sin(c);
|
|
d = x * x + y * y;
|
|
if (d < minDist) {
|
|
minAngle = c;
|
|
minDist = d;
|
|
minX = x;
|
|
minY = y;
|
|
}
|
|
if (d > maxDist) {
|
|
maxAngle = c;
|
|
maxDist = d;
|
|
maxX = x;
|
|
maxY = y;
|
|
}
|
|
}
|
|
if (dd <= (minDist + maxDist) / 2) {
|
|
a1 = ta - Math.atan2(minY * bendDir, minX);
|
|
a2 = minAngle * bendDir;
|
|
}
|
|
else {
|
|
a1 = ta - Math.atan2(maxY * bendDir, maxX);
|
|
a2 = maxAngle * bendDir;
|
|
}
|
|
}
|
|
var os = Math.atan2(cy, cx) * s2;
|
|
var rotation = parent.arotation;
|
|
a1 = (a1 - os) * spine.MathUtils.radDeg + os1 - rotation;
|
|
if (a1 > 180)
|
|
a1 -= 360;
|
|
else if (a1 < -180)
|
|
a1 += 360;
|
|
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
|
|
rotation = child.arotation;
|
|
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
|
|
if (a2 > 180)
|
|
a2 -= 360;
|
|
else if (a2 < -180)
|
|
a2 += 360;
|
|
child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
|
|
};
|
|
return IkConstraint;
|
|
}());
|
|
spine.IkConstraint = IkConstraint;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var IkConstraintData = (function (_super) {
|
|
__extends(IkConstraintData, _super);
|
|
function IkConstraintData(name) {
|
|
var _this = _super.call(this, name, 0, false) || this;
|
|
_this.bones = new Array();
|
|
_this.bendDirection = 1;
|
|
_this.compress = false;
|
|
_this.stretch = false;
|
|
_this.uniform = false;
|
|
_this.mix = 1;
|
|
_this.softness = 0;
|
|
return _this;
|
|
}
|
|
return IkConstraintData;
|
|
}(spine.ConstraintData));
|
|
spine.IkConstraintData = IkConstraintData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var PathConstraint = (function () {
|
|
function PathConstraint(data, skeleton) {
|
|
this.position = 0;
|
|
this.spacing = 0;
|
|
this.rotateMix = 0;
|
|
this.translateMix = 0;
|
|
this.spaces = new Array();
|
|
this.positions = new Array();
|
|
this.world = new Array();
|
|
this.curves = new Array();
|
|
this.lengths = new Array();
|
|
this.segments = new Array();
|
|
this.active = false;
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
this.data = data;
|
|
this.bones = new Array();
|
|
for (var i = 0, n = data.bones.length; i < n; i++)
|
|
this.bones.push(skeleton.findBone(data.bones[i].name));
|
|
this.target = skeleton.findSlot(data.target.name);
|
|
this.position = data.position;
|
|
this.spacing = data.spacing;
|
|
this.rotateMix = data.rotateMix;
|
|
this.translateMix = data.translateMix;
|
|
}
|
|
PathConstraint.prototype.isActive = function () {
|
|
return this.active;
|
|
};
|
|
PathConstraint.prototype.apply = function () {
|
|
this.update();
|
|
};
|
|
PathConstraint.prototype.update = function () {
|
|
var attachment = this.target.getAttachment();
|
|
if (!(attachment instanceof spine.PathAttachment))
|
|
return;
|
|
var rotateMix = this.rotateMix, translateMix = this.translateMix;
|
|
var translate = translateMix > 0, rotate = rotateMix > 0;
|
|
if (!translate && !rotate)
|
|
return;
|
|
var data = this.data;
|
|
var percentSpacing = data.spacingMode == spine.SpacingMode.Percent;
|
|
var rotateMode = data.rotateMode;
|
|
var tangents = rotateMode == spine.RotateMode.Tangent, scale = rotateMode == spine.RotateMode.ChainScale;
|
|
var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1;
|
|
var bones = this.bones;
|
|
var spaces = spine.Utils.setArraySize(this.spaces, spacesCount), lengths = null;
|
|
var spacing = this.spacing;
|
|
if (scale || !percentSpacing) {
|
|
if (scale)
|
|
lengths = spine.Utils.setArraySize(this.lengths, boneCount);
|
|
var lengthSpacing = data.spacingMode == spine.SpacingMode.Length;
|
|
for (var i = 0, n = spacesCount - 1; i < n;) {
|
|
var bone = bones[i];
|
|
var setupLength = bone.data.length;
|
|
if (setupLength < PathConstraint.epsilon) {
|
|
if (scale)
|
|
lengths[i] = 0;
|
|
spaces[++i] = 0;
|
|
}
|
|
else if (percentSpacing) {
|
|
if (scale) {
|
|
var x = setupLength * bone.a, y = setupLength * bone.c;
|
|
var length_1 = Math.sqrt(x * x + y * y);
|
|
lengths[i] = length_1;
|
|
}
|
|
spaces[++i] = spacing;
|
|
}
|
|
else {
|
|
var x = setupLength * bone.a, y = setupLength * bone.c;
|
|
var length_2 = Math.sqrt(x * x + y * y);
|
|
if (scale)
|
|
lengths[i] = length_2;
|
|
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_2 / setupLength;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 1; i < spacesCount; i++)
|
|
spaces[i] = spacing;
|
|
}
|
|
var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == spine.PositionMode.Percent, percentSpacing);
|
|
var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
|
|
var tip = false;
|
|
if (offsetRotation == 0)
|
|
tip = rotateMode == spine.RotateMode.Chain;
|
|
else {
|
|
tip = false;
|
|
var p = this.target.bone;
|
|
offsetRotation *= p.a * p.d - p.b * p.c > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
|
|
}
|
|
for (var i = 0, p = 3; i < boneCount; i++, p += 3) {
|
|
var bone = bones[i];
|
|
bone.worldX += (boneX - bone.worldX) * translateMix;
|
|
bone.worldY += (boneY - bone.worldY) * translateMix;
|
|
var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
|
|
if (scale) {
|
|
var length_3 = lengths[i];
|
|
if (length_3 != 0) {
|
|
var s = (Math.sqrt(dx * dx + dy * dy) / length_3 - 1) * rotateMix + 1;
|
|
bone.a *= s;
|
|
bone.c *= s;
|
|
}
|
|
}
|
|
boneX = x;
|
|
boneY = y;
|
|
if (rotate) {
|
|
var a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0;
|
|
if (tangents)
|
|
r = positions[p - 1];
|
|
else if (spaces[i + 1] == 0)
|
|
r = positions[p + 2];
|
|
else
|
|
r = Math.atan2(dy, dx);
|
|
r -= Math.atan2(c, a);
|
|
if (tip) {
|
|
cos = Math.cos(r);
|
|
sin = Math.sin(r);
|
|
var length_4 = bone.data.length;
|
|
boneX += (length_4 * (cos * a - sin * c) - dx) * rotateMix;
|
|
boneY += (length_4 * (sin * a + cos * c) - dy) * rotateMix;
|
|
}
|
|
else {
|
|
r += offsetRotation;
|
|
}
|
|
if (r > spine.MathUtils.PI)
|
|
r -= spine.MathUtils.PI2;
|
|
else if (r < -spine.MathUtils.PI)
|
|
r += spine.MathUtils.PI2;
|
|
r *= rotateMix;
|
|
cos = Math.cos(r);
|
|
sin = Math.sin(r);
|
|
bone.a = cos * a - sin * c;
|
|
bone.b = cos * b - sin * d;
|
|
bone.c = sin * a + cos * c;
|
|
bone.d = sin * b + cos * d;
|
|
}
|
|
bone.appliedValid = false;
|
|
}
|
|
};
|
|
PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) {
|
|
var target = this.target;
|
|
var position = this.position;
|
|
var spaces = this.spaces, out = spine.Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null;
|
|
var closed = path.closed;
|
|
var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE;
|
|
if (!path.constantSpeed) {
|
|
var lengths = path.lengths;
|
|
curveCount -= closed ? 1 : 2;
|
|
var pathLength_1 = lengths[curveCount];
|
|
if (percentPosition)
|
|
position *= pathLength_1;
|
|
if (percentSpacing) {
|
|
for (var i = 1; i < spacesCount; i++)
|
|
spaces[i] *= pathLength_1;
|
|
}
|
|
world = spine.Utils.setArraySize(this.world, 8);
|
|
for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
|
|
var space = spaces[i];
|
|
position += space;
|
|
var p = position;
|
|
if (closed) {
|
|
p %= pathLength_1;
|
|
if (p < 0)
|
|
p += pathLength_1;
|
|
curve = 0;
|
|
}
|
|
else if (p < 0) {
|
|
if (prevCurve != PathConstraint.BEFORE) {
|
|
prevCurve = PathConstraint.BEFORE;
|
|
path.computeWorldVertices(target, 2, 4, world, 0, 2);
|
|
}
|
|
this.addBeforePosition(p, world, 0, out, o);
|
|
continue;
|
|
}
|
|
else if (p > pathLength_1) {
|
|
if (prevCurve != PathConstraint.AFTER) {
|
|
prevCurve = PathConstraint.AFTER;
|
|
path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2);
|
|
}
|
|
this.addAfterPosition(p - pathLength_1, world, 0, out, o);
|
|
continue;
|
|
}
|
|
for (;; curve++) {
|
|
var length_5 = lengths[curve];
|
|
if (p > length_5)
|
|
continue;
|
|
if (curve == 0)
|
|
p /= length_5;
|
|
else {
|
|
var prev = lengths[curve - 1];
|
|
p = (p - prev) / (length_5 - prev);
|
|
}
|
|
break;
|
|
}
|
|
if (curve != prevCurve) {
|
|
prevCurve = curve;
|
|
if (closed && curve == curveCount) {
|
|
path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2);
|
|
path.computeWorldVertices(target, 0, 4, world, 4, 2);
|
|
}
|
|
else
|
|
path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
|
|
}
|
|
this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0));
|
|
}
|
|
return out;
|
|
}
|
|
if (closed) {
|
|
verticesLength += 2;
|
|
world = spine.Utils.setArraySize(this.world, verticesLength);
|
|
path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2);
|
|
path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2);
|
|
world[verticesLength - 2] = world[0];
|
|
world[verticesLength - 1] = world[1];
|
|
}
|
|
else {
|
|
curveCount--;
|
|
verticesLength -= 4;
|
|
world = spine.Utils.setArraySize(this.world, verticesLength);
|
|
path.computeWorldVertices(target, 2, verticesLength, world, 0, 2);
|
|
}
|
|
var curves = spine.Utils.setArraySize(this.curves, curveCount);
|
|
var pathLength = 0;
|
|
var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
|
|
var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0;
|
|
for (var i = 0, w = 2; i < curveCount; i++, w += 6) {
|
|
cx1 = world[w];
|
|
cy1 = world[w + 1];
|
|
cx2 = world[w + 2];
|
|
cy2 = world[w + 3];
|
|
x2 = world[w + 4];
|
|
y2 = world[w + 5];
|
|
tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
|
|
tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
|
|
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
|
|
dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
|
|
ddfx = tmpx * 2 + dddfx;
|
|
ddfy = tmpy * 2 + dddfy;
|
|
dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
|
|
dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
|
|
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
ddfx += dddfx;
|
|
ddfy += dddfy;
|
|
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
dfx += ddfx + dddfx;
|
|
dfy += ddfy + dddfy;
|
|
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
curves[i] = pathLength;
|
|
x1 = x2;
|
|
y1 = y2;
|
|
}
|
|
if (percentPosition)
|
|
position *= pathLength;
|
|
else
|
|
position *= pathLength / path.lengths[curveCount - 1];
|
|
if (percentSpacing) {
|
|
for (var i = 1; i < spacesCount; i++)
|
|
spaces[i] *= pathLength;
|
|
}
|
|
var segments = this.segments;
|
|
var curveLength = 0;
|
|
for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
|
|
var space = spaces[i];
|
|
position += space;
|
|
var p = position;
|
|
if (closed) {
|
|
p %= pathLength;
|
|
if (p < 0)
|
|
p += pathLength;
|
|
curve = 0;
|
|
}
|
|
else if (p < 0) {
|
|
this.addBeforePosition(p, world, 0, out, o);
|
|
continue;
|
|
}
|
|
else if (p > pathLength) {
|
|
this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
|
|
continue;
|
|
}
|
|
for (;; curve++) {
|
|
var length_6 = curves[curve];
|
|
if (p > length_6)
|
|
continue;
|
|
if (curve == 0)
|
|
p /= length_6;
|
|
else {
|
|
var prev = curves[curve - 1];
|
|
p = (p - prev) / (length_6 - prev);
|
|
}
|
|
break;
|
|
}
|
|
if (curve != prevCurve) {
|
|
prevCurve = curve;
|
|
var ii = curve * 6;
|
|
x1 = world[ii];
|
|
y1 = world[ii + 1];
|
|
cx1 = world[ii + 2];
|
|
cy1 = world[ii + 3];
|
|
cx2 = world[ii + 4];
|
|
cy2 = world[ii + 5];
|
|
x2 = world[ii + 6];
|
|
y2 = world[ii + 7];
|
|
tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
|
|
tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
|
|
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
|
|
dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
|
|
ddfx = tmpx * 2 + dddfx;
|
|
ddfy = tmpy * 2 + dddfy;
|
|
dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
|
|
dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
|
|
curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
|
|
segments[0] = curveLength;
|
|
for (ii = 1; ii < 8; ii++) {
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
ddfx += dddfx;
|
|
ddfy += dddfy;
|
|
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
segments[ii] = curveLength;
|
|
}
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
segments[8] = curveLength;
|
|
dfx += ddfx + dddfx;
|
|
dfy += ddfy + dddfy;
|
|
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
|
segments[9] = curveLength;
|
|
segment = 0;
|
|
}
|
|
p *= curveLength;
|
|
for (;; segment++) {
|
|
var length_7 = segments[segment];
|
|
if (p > length_7)
|
|
continue;
|
|
if (segment == 0)
|
|
p /= length_7;
|
|
else {
|
|
var prev = segments[segment - 1];
|
|
p = segment + (p - prev) / (length_7 - prev);
|
|
}
|
|
break;
|
|
}
|
|
this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));
|
|
}
|
|
return out;
|
|
};
|
|
PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) {
|
|
var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);
|
|
out[o] = x1 + p * Math.cos(r);
|
|
out[o + 1] = y1 + p * Math.sin(r);
|
|
out[o + 2] = r;
|
|
};
|
|
PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) {
|
|
var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);
|
|
out[o] = x1 + p * Math.cos(r);
|
|
out[o + 1] = y1 + p * Math.sin(r);
|
|
out[o + 2] = r;
|
|
};
|
|
PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) {
|
|
if (p == 0 || isNaN(p)) {
|
|
out[o] = x1;
|
|
out[o + 1] = y1;
|
|
out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);
|
|
return;
|
|
}
|
|
var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
|
|
var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
|
|
var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
|
|
out[o] = x;
|
|
out[o + 1] = y;
|
|
if (tangents) {
|
|
if (p < 0.001)
|
|
out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);
|
|
else
|
|
out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
|
}
|
|
};
|
|
PathConstraint.NONE = -1;
|
|
PathConstraint.BEFORE = -2;
|
|
PathConstraint.AFTER = -3;
|
|
PathConstraint.epsilon = 0.00001;
|
|
return PathConstraint;
|
|
}());
|
|
spine.PathConstraint = PathConstraint;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var PathConstraintData = (function (_super) {
|
|
__extends(PathConstraintData, _super);
|
|
function PathConstraintData(name) {
|
|
var _this = _super.call(this, name, 0, false) || this;
|
|
_this.bones = new Array();
|
|
return _this;
|
|
}
|
|
return PathConstraintData;
|
|
}(spine.ConstraintData));
|
|
spine.PathConstraintData = PathConstraintData;
|
|
var PositionMode;
|
|
(function (PositionMode) {
|
|
PositionMode[PositionMode["Fixed"] = 0] = "Fixed";
|
|
PositionMode[PositionMode["Percent"] = 1] = "Percent";
|
|
})(PositionMode = spine.PositionMode || (spine.PositionMode = {}));
|
|
var SpacingMode;
|
|
(function (SpacingMode) {
|
|
SpacingMode[SpacingMode["Length"] = 0] = "Length";
|
|
SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed";
|
|
SpacingMode[SpacingMode["Percent"] = 2] = "Percent";
|
|
})(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {}));
|
|
var RotateMode;
|
|
(function (RotateMode) {
|
|
RotateMode[RotateMode["Tangent"] = 0] = "Tangent";
|
|
RotateMode[RotateMode["Chain"] = 1] = "Chain";
|
|
RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale";
|
|
})(RotateMode = spine.RotateMode || (spine.RotateMode = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Assets = (function () {
|
|
function Assets(clientId) {
|
|
this.toLoad = new Array();
|
|
this.assets = {};
|
|
this.clientId = clientId;
|
|
}
|
|
Assets.prototype.loaded = function () {
|
|
var i = 0;
|
|
for (var v in this.assets)
|
|
i++;
|
|
return i;
|
|
};
|
|
return Assets;
|
|
}());
|
|
var SharedAssetManager = (function () {
|
|
function SharedAssetManager(pathPrefix) {
|
|
if (pathPrefix === void 0) { pathPrefix = ""; }
|
|
this.clientAssets = {};
|
|
this.queuedAssets = {};
|
|
this.rawAssets = {};
|
|
this.errors = {};
|
|
this.pathPrefix = pathPrefix;
|
|
}
|
|
SharedAssetManager.prototype.queueAsset = function (clientId, textureLoader, path) {
|
|
var clientAssets = this.clientAssets[clientId];
|
|
if (clientAssets === null || clientAssets === undefined) {
|
|
clientAssets = new Assets(clientId);
|
|
this.clientAssets[clientId] = clientAssets;
|
|
}
|
|
if (textureLoader !== null)
|
|
clientAssets.textureLoader = textureLoader;
|
|
clientAssets.toLoad.push(path);
|
|
if (this.queuedAssets[path] === path) {
|
|
return false;
|
|
}
|
|
else {
|
|
this.queuedAssets[path] = path;
|
|
return true;
|
|
}
|
|
};
|
|
SharedAssetManager.prototype.loadText = function (clientId, path) {
|
|
var _this = this;
|
|
path = this.pathPrefix + path;
|
|
if (!this.queueAsset(clientId, null, path))
|
|
return;
|
|
var request = new XMLHttpRequest();
|
|
request.overrideMimeType("text/html");
|
|
request.onreadystatechange = function () {
|
|
if (request.readyState == XMLHttpRequest.DONE) {
|
|
if (request.status >= 200 && request.status < 300) {
|
|
_this.rawAssets[path] = request.responseText;
|
|
}
|
|
else {
|
|
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
|
}
|
|
}
|
|
};
|
|
request.open("GET", path, true);
|
|
request.send();
|
|
};
|
|
SharedAssetManager.prototype.loadJson = function (clientId, path) {
|
|
var _this = this;
|
|
path = this.pathPrefix + path;
|
|
if (!this.queueAsset(clientId, null, path))
|
|
return;
|
|
var request = new XMLHttpRequest();
|
|
request.overrideMimeType("text/html");
|
|
request.onreadystatechange = function () {
|
|
if (request.readyState == XMLHttpRequest.DONE) {
|
|
if (request.status >= 200 && request.status < 300) {
|
|
_this.rawAssets[path] = JSON.parse(request.responseText);
|
|
}
|
|
else {
|
|
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
|
}
|
|
}
|
|
};
|
|
request.open("GET", path, true);
|
|
request.send();
|
|
};
|
|
SharedAssetManager.prototype.loadTexture = function (clientId, textureLoader, path) {
|
|
var _this = this;
|
|
path = this.pathPrefix + path;
|
|
if (!this.queueAsset(clientId, textureLoader, path))
|
|
return;
|
|
var img = new Image();
|
|
img.crossOrigin = "anonymous";
|
|
img.onload = function (ev) {
|
|
_this.rawAssets[path] = img;
|
|
};
|
|
img.onerror = function (ev) {
|
|
_this.errors[path] = "Couldn't load image " + path;
|
|
};
|
|
img.src = path;
|
|
};
|
|
SharedAssetManager.prototype.get = function (clientId, path) {
|
|
path = this.pathPrefix + path;
|
|
var clientAssets = this.clientAssets[clientId];
|
|
if (clientAssets === null || clientAssets === undefined)
|
|
return true;
|
|
return clientAssets.assets[path];
|
|
};
|
|
SharedAssetManager.prototype.updateClientAssets = function (clientAssets) {
|
|
for (var i = 0; i < clientAssets.toLoad.length; i++) {
|
|
var path = clientAssets.toLoad[i];
|
|
var asset = clientAssets.assets[path];
|
|
if (asset === null || asset === undefined) {
|
|
var rawAsset = this.rawAssets[path];
|
|
if (rawAsset === null || rawAsset === undefined)
|
|
continue;
|
|
if (rawAsset instanceof HTMLImageElement) {
|
|
clientAssets.assets[path] = clientAssets.textureLoader(rawAsset);
|
|
}
|
|
else {
|
|
clientAssets.assets[path] = rawAsset;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
SharedAssetManager.prototype.isLoadingComplete = function (clientId) {
|
|
var clientAssets = this.clientAssets[clientId];
|
|
if (clientAssets === null || clientAssets === undefined)
|
|
return true;
|
|
this.updateClientAssets(clientAssets);
|
|
return clientAssets.toLoad.length == clientAssets.loaded();
|
|
};
|
|
SharedAssetManager.prototype.dispose = function () {
|
|
};
|
|
SharedAssetManager.prototype.hasErrors = function () {
|
|
return Object.keys(this.errors).length > 0;
|
|
};
|
|
SharedAssetManager.prototype.getErrors = function () {
|
|
return this.errors;
|
|
};
|
|
return SharedAssetManager;
|
|
}());
|
|
spine.SharedAssetManager = SharedAssetManager;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Skeleton = (function () {
|
|
function Skeleton(data) {
|
|
this._updateCache = new Array();
|
|
this.updateCacheReset = new Array();
|
|
this.time = 0;
|
|
this.scaleX = 1;
|
|
this.scaleY = 1;
|
|
this.x = 0;
|
|
this.y = 0;
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
this.data = data;
|
|
this.bones = new Array();
|
|
for (var i = 0; i < data.bones.length; i++) {
|
|
var boneData = data.bones[i];
|
|
var bone = void 0;
|
|
if (boneData.parent == null)
|
|
bone = new spine.Bone(boneData, this, null);
|
|
else {
|
|
var parent_1 = this.bones[boneData.parent.index];
|
|
bone = new spine.Bone(boneData, this, parent_1);
|
|
parent_1.children.push(bone);
|
|
}
|
|
this.bones.push(bone);
|
|
}
|
|
this.slots = new Array();
|
|
this.drawOrder = new Array();
|
|
for (var i = 0; i < data.slots.length; i++) {
|
|
var slotData = data.slots[i];
|
|
var bone = this.bones[slotData.boneData.index];
|
|
var slot = new spine.Slot(slotData, bone);
|
|
this.slots.push(slot);
|
|
this.drawOrder.push(slot);
|
|
}
|
|
this.ikConstraints = new Array();
|
|
for (var i = 0; i < data.ikConstraints.length; i++) {
|
|
var ikConstraintData = data.ikConstraints[i];
|
|
this.ikConstraints.push(new spine.IkConstraint(ikConstraintData, this));
|
|
}
|
|
this.transformConstraints = new Array();
|
|
for (var i = 0; i < data.transformConstraints.length; i++) {
|
|
var transformConstraintData = data.transformConstraints[i];
|
|
this.transformConstraints.push(new spine.TransformConstraint(transformConstraintData, this));
|
|
}
|
|
this.pathConstraints = new Array();
|
|
for (var i = 0; i < data.pathConstraints.length; i++) {
|
|
var pathConstraintData = data.pathConstraints[i];
|
|
this.pathConstraints.push(new spine.PathConstraint(pathConstraintData, this));
|
|
}
|
|
this.color = new spine.Color(1, 1, 1, 1);
|
|
this.updateCache();
|
|
}
|
|
Skeleton.prototype.updateCache = function () {
|
|
var updateCache = this._updateCache;
|
|
updateCache.length = 0;
|
|
this.updateCacheReset.length = 0;
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
bone.sorted = bone.data.skinRequired;
|
|
bone.active = !bone.sorted;
|
|
}
|
|
if (this.skin != null) {
|
|
var skinBones = this.skin.bones;
|
|
for (var i = 0, n = this.skin.bones.length; i < n; i++) {
|
|
var bone = this.bones[skinBones[i].index];
|
|
do {
|
|
bone.sorted = false;
|
|
bone.active = true;
|
|
bone = bone.parent;
|
|
} while (bone != null);
|
|
}
|
|
}
|
|
var ikConstraints = this.ikConstraints;
|
|
var transformConstraints = this.transformConstraints;
|
|
var pathConstraints = this.pathConstraints;
|
|
var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length;
|
|
var constraintCount = ikCount + transformCount + pathCount;
|
|
outer: for (var i = 0; i < constraintCount; i++) {
|
|
for (var ii = 0; ii < ikCount; ii++) {
|
|
var constraint = ikConstraints[ii];
|
|
if (constraint.data.order == i) {
|
|
this.sortIkConstraint(constraint);
|
|
continue outer;
|
|
}
|
|
}
|
|
for (var ii = 0; ii < transformCount; ii++) {
|
|
var constraint = transformConstraints[ii];
|
|
if (constraint.data.order == i) {
|
|
this.sortTransformConstraint(constraint);
|
|
continue outer;
|
|
}
|
|
}
|
|
for (var ii = 0; ii < pathCount; ii++) {
|
|
var constraint = pathConstraints[ii];
|
|
if (constraint.data.order == i) {
|
|
this.sortPathConstraint(constraint);
|
|
continue outer;
|
|
}
|
|
}
|
|
}
|
|
for (var i = 0, n = bones.length; i < n; i++)
|
|
this.sortBone(bones[i]);
|
|
};
|
|
Skeleton.prototype.sortIkConstraint = function (constraint) {
|
|
constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
|
|
if (!constraint.active)
|
|
return;
|
|
var target = constraint.target;
|
|
this.sortBone(target);
|
|
var constrained = constraint.bones;
|
|
var parent = constrained[0];
|
|
this.sortBone(parent);
|
|
if (constrained.length > 1) {
|
|
var child = constrained[constrained.length - 1];
|
|
if (!(this._updateCache.indexOf(child) > -1))
|
|
this.updateCacheReset.push(child);
|
|
}
|
|
this._updateCache.push(constraint);
|
|
this.sortReset(parent.children);
|
|
constrained[constrained.length - 1].sorted = true;
|
|
};
|
|
Skeleton.prototype.sortPathConstraint = function (constraint) {
|
|
constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
|
|
if (!constraint.active)
|
|
return;
|
|
var slot = constraint.target;
|
|
var slotIndex = slot.data.index;
|
|
var slotBone = slot.bone;
|
|
if (this.skin != null)
|
|
this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone);
|
|
if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin)
|
|
this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone);
|
|
for (var i = 0, n = this.data.skins.length; i < n; i++)
|
|
this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone);
|
|
var attachment = slot.getAttachment();
|
|
if (attachment instanceof spine.PathAttachment)
|
|
this.sortPathConstraintAttachmentWith(attachment, slotBone);
|
|
var constrained = constraint.bones;
|
|
var boneCount = constrained.length;
|
|
for (var i = 0; i < boneCount; i++)
|
|
this.sortBone(constrained[i]);
|
|
this._updateCache.push(constraint);
|
|
for (var i = 0; i < boneCount; i++)
|
|
this.sortReset(constrained[i].children);
|
|
for (var i = 0; i < boneCount; i++)
|
|
constrained[i].sorted = true;
|
|
};
|
|
Skeleton.prototype.sortTransformConstraint = function (constraint) {
|
|
constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
|
|
if (!constraint.active)
|
|
return;
|
|
this.sortBone(constraint.target);
|
|
var constrained = constraint.bones;
|
|
var boneCount = constrained.length;
|
|
if (constraint.data.local) {
|
|
for (var i = 0; i < boneCount; i++) {
|
|
var child = constrained[i];
|
|
this.sortBone(child.parent);
|
|
if (!(this._updateCache.indexOf(child) > -1))
|
|
this.updateCacheReset.push(child);
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 0; i < boneCount; i++) {
|
|
this.sortBone(constrained[i]);
|
|
}
|
|
}
|
|
this._updateCache.push(constraint);
|
|
for (var ii = 0; ii < boneCount; ii++)
|
|
this.sortReset(constrained[ii].children);
|
|
for (var ii = 0; ii < boneCount; ii++)
|
|
constrained[ii].sorted = true;
|
|
};
|
|
Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) {
|
|
var attachments = skin.attachments[slotIndex];
|
|
if (!attachments)
|
|
return;
|
|
for (var key in attachments) {
|
|
this.sortPathConstraintAttachmentWith(attachments[key], slotBone);
|
|
}
|
|
};
|
|
Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) {
|
|
if (!(attachment instanceof spine.PathAttachment))
|
|
return;
|
|
var pathBones = attachment.bones;
|
|
if (pathBones == null)
|
|
this.sortBone(slotBone);
|
|
else {
|
|
var bones = this.bones;
|
|
var i = 0;
|
|
while (i < pathBones.length) {
|
|
var boneCount = pathBones[i++];
|
|
for (var n = i + boneCount; i < n; i++) {
|
|
var boneIndex = pathBones[i];
|
|
this.sortBone(bones[boneIndex]);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
Skeleton.prototype.sortBone = function (bone) {
|
|
if (bone.sorted)
|
|
return;
|
|
var parent = bone.parent;
|
|
if (parent != null)
|
|
this.sortBone(parent);
|
|
bone.sorted = true;
|
|
this._updateCache.push(bone);
|
|
};
|
|
Skeleton.prototype.sortReset = function (bones) {
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (!bone.active)
|
|
continue;
|
|
if (bone.sorted)
|
|
this.sortReset(bone.children);
|
|
bone.sorted = false;
|
|
}
|
|
};
|
|
Skeleton.prototype.updateWorldTransform = function () {
|
|
var updateCacheReset = this.updateCacheReset;
|
|
for (var i = 0, n = updateCacheReset.length; i < n; i++) {
|
|
var bone = updateCacheReset[i];
|
|
bone.ax = bone.x;
|
|
bone.ay = bone.y;
|
|
bone.arotation = bone.rotation;
|
|
bone.ascaleX = bone.scaleX;
|
|
bone.ascaleY = bone.scaleY;
|
|
bone.ashearX = bone.shearX;
|
|
bone.ashearY = bone.shearY;
|
|
bone.appliedValid = true;
|
|
}
|
|
var updateCache = this._updateCache;
|
|
for (var i = 0, n = updateCache.length; i < n; i++)
|
|
updateCache[i].update();
|
|
};
|
|
Skeleton.prototype.setToSetupPose = function () {
|
|
this.setBonesToSetupPose();
|
|
this.setSlotsToSetupPose();
|
|
};
|
|
Skeleton.prototype.setBonesToSetupPose = function () {
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++)
|
|
bones[i].setToSetupPose();
|
|
var ikConstraints = this.ikConstraints;
|
|
for (var i = 0, n = ikConstraints.length; i < n; i++) {
|
|
var constraint = ikConstraints[i];
|
|
constraint.mix = constraint.data.mix;
|
|
constraint.softness = constraint.data.softness;
|
|
constraint.bendDirection = constraint.data.bendDirection;
|
|
constraint.compress = constraint.data.compress;
|
|
constraint.stretch = constraint.data.stretch;
|
|
}
|
|
var transformConstraints = this.transformConstraints;
|
|
for (var i = 0, n = transformConstraints.length; i < n; i++) {
|
|
var constraint = transformConstraints[i];
|
|
var data = constraint.data;
|
|
constraint.rotateMix = data.rotateMix;
|
|
constraint.translateMix = data.translateMix;
|
|
constraint.scaleMix = data.scaleMix;
|
|
constraint.shearMix = data.shearMix;
|
|
}
|
|
var pathConstraints = this.pathConstraints;
|
|
for (var i = 0, n = pathConstraints.length; i < n; i++) {
|
|
var constraint = pathConstraints[i];
|
|
var data = constraint.data;
|
|
constraint.position = data.position;
|
|
constraint.spacing = data.spacing;
|
|
constraint.rotateMix = data.rotateMix;
|
|
constraint.translateMix = data.translateMix;
|
|
}
|
|
};
|
|
Skeleton.prototype.setSlotsToSetupPose = function () {
|
|
var slots = this.slots;
|
|
spine.Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length);
|
|
for (var i = 0, n = slots.length; i < n; i++)
|
|
slots[i].setToSetupPose();
|
|
};
|
|
Skeleton.prototype.getRootBone = function () {
|
|
if (this.bones.length == 0)
|
|
return null;
|
|
return this.bones[0];
|
|
};
|
|
Skeleton.prototype.findBone = function (boneName) {
|
|
if (boneName == null)
|
|
throw new Error("boneName cannot be null.");
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (bone.data.name == boneName)
|
|
return bone;
|
|
}
|
|
return null;
|
|
};
|
|
Skeleton.prototype.findBoneIndex = function (boneName) {
|
|
if (boneName == null)
|
|
throw new Error("boneName cannot be null.");
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++)
|
|
if (bones[i].data.name == boneName)
|
|
return i;
|
|
return -1;
|
|
};
|
|
Skeleton.prototype.findSlot = function (slotName) {
|
|
if (slotName == null)
|
|
throw new Error("slotName cannot be null.");
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (slot.data.name == slotName)
|
|
return slot;
|
|
}
|
|
return null;
|
|
};
|
|
Skeleton.prototype.findSlotIndex = function (slotName) {
|
|
if (slotName == null)
|
|
throw new Error("slotName cannot be null.");
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++)
|
|
if (slots[i].data.name == slotName)
|
|
return i;
|
|
return -1;
|
|
};
|
|
Skeleton.prototype.setSkinByName = function (skinName) {
|
|
var skin = this.data.findSkin(skinName);
|
|
if (skin == null)
|
|
throw new Error("Skin not found: " + skinName);
|
|
this.setSkin(skin);
|
|
};
|
|
Skeleton.prototype.setSkin = function (newSkin) {
|
|
if (newSkin == this.skin)
|
|
return;
|
|
if (newSkin != null) {
|
|
if (this.skin != null)
|
|
newSkin.attachAll(this, this.skin);
|
|
else {
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
var name_1 = slot.data.attachmentName;
|
|
if (name_1 != null) {
|
|
var attachment = newSkin.getAttachment(i, name_1);
|
|
if (attachment != null)
|
|
slot.setAttachment(attachment);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.skin = newSkin;
|
|
this.updateCache();
|
|
};
|
|
Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
|
|
return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
|
|
};
|
|
Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) {
|
|
if (attachmentName == null)
|
|
throw new Error("attachmentName cannot be null.");
|
|
if (this.skin != null) {
|
|
var attachment = this.skin.getAttachment(slotIndex, attachmentName);
|
|
if (attachment != null)
|
|
return attachment;
|
|
}
|
|
if (this.data.defaultSkin != null)
|
|
return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
|
|
return null;
|
|
};
|
|
Skeleton.prototype.setAttachment = function (slotName, attachmentName) {
|
|
if (slotName == null)
|
|
throw new Error("slotName cannot be null.");
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (slot.data.name == slotName) {
|
|
var attachment = null;
|
|
if (attachmentName != null) {
|
|
attachment = this.getAttachment(i, attachmentName);
|
|
if (attachment == null)
|
|
throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName);
|
|
}
|
|
slot.setAttachment(attachment);
|
|
return;
|
|
}
|
|
}
|
|
throw new Error("Slot not found: " + slotName);
|
|
};
|
|
Skeleton.prototype.findIkConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var ikConstraints = this.ikConstraints;
|
|
for (var i = 0, n = ikConstraints.length; i < n; i++) {
|
|
var ikConstraint = ikConstraints[i];
|
|
if (ikConstraint.data.name == constraintName)
|
|
return ikConstraint;
|
|
}
|
|
return null;
|
|
};
|
|
Skeleton.prototype.findTransformConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var transformConstraints = this.transformConstraints;
|
|
for (var i = 0, n = transformConstraints.length; i < n; i++) {
|
|
var constraint = transformConstraints[i];
|
|
if (constraint.data.name == constraintName)
|
|
return constraint;
|
|
}
|
|
return null;
|
|
};
|
|
Skeleton.prototype.findPathConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var pathConstraints = this.pathConstraints;
|
|
for (var i = 0, n = pathConstraints.length; i < n; i++) {
|
|
var constraint = pathConstraints[i];
|
|
if (constraint.data.name == constraintName)
|
|
return constraint;
|
|
}
|
|
return null;
|
|
};
|
|
Skeleton.prototype.getBounds = function (offset, size, temp) {
|
|
if (temp === void 0) { temp = new Array(2); }
|
|
if (offset == null)
|
|
throw new Error("offset cannot be null.");
|
|
if (size == null)
|
|
throw new Error("size cannot be null.");
|
|
var drawOrder = this.drawOrder;
|
|
var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
|
|
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
|
var slot = drawOrder[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var verticesLength = 0;
|
|
var vertices = null;
|
|
var attachment = slot.getAttachment();
|
|
if (attachment instanceof spine.RegionAttachment) {
|
|
verticesLength = 8;
|
|
vertices = spine.Utils.setArraySize(temp, verticesLength, 0);
|
|
attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
|
|
}
|
|
else if (attachment instanceof spine.MeshAttachment) {
|
|
var mesh = attachment;
|
|
verticesLength = mesh.worldVerticesLength;
|
|
vertices = spine.Utils.setArraySize(temp, verticesLength, 0);
|
|
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
|
|
}
|
|
if (vertices != null) {
|
|
for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) {
|
|
var x = vertices[ii], y = vertices[ii + 1];
|
|
minX = Math.min(minX, x);
|
|
minY = Math.min(minY, y);
|
|
maxX = Math.max(maxX, x);
|
|
maxY = Math.max(maxY, y);
|
|
}
|
|
}
|
|
}
|
|
offset.set(minX, minY);
|
|
size.set(maxX - minX, maxY - minY);
|
|
};
|
|
Skeleton.prototype.update = function (delta) {
|
|
this.time += delta;
|
|
};
|
|
return Skeleton;
|
|
}());
|
|
spine.Skeleton = Skeleton;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkeletonBinary = (function () {
|
|
function SkeletonBinary(attachmentLoader) {
|
|
this.scale = 1;
|
|
this.linkedMeshes = new Array();
|
|
this.attachmentLoader = attachmentLoader;
|
|
}
|
|
SkeletonBinary.prototype.readSkeletonData = function (binary) {
|
|
var scale = this.scale;
|
|
var skeletonData = new spine.SkeletonData();
|
|
skeletonData.name = "";
|
|
var input = new BinaryInput(binary);
|
|
skeletonData.hash = input.readString();
|
|
skeletonData.version = input.readString();
|
|
if ("3.8.75" == skeletonData.version)
|
|
throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
|
|
skeletonData.x = input.readFloat();
|
|
skeletonData.y = input.readFloat();
|
|
skeletonData.width = input.readFloat();
|
|
skeletonData.height = input.readFloat();
|
|
var nonessential = input.readBoolean();
|
|
if (nonessential) {
|
|
skeletonData.fps = input.readFloat();
|
|
skeletonData.imagesPath = input.readString();
|
|
skeletonData.audioPath = input.readString();
|
|
}
|
|
var n = 0;
|
|
n = input.readInt(true);
|
|
for (var i = 0; i < n; i++)
|
|
input.strings.push(input.readString());
|
|
n = input.readInt(true);
|
|
for (var i = 0; i < n; i++) {
|
|
var name_2 = input.readString();
|
|
var parent_2 = i == 0 ? null : skeletonData.bones[input.readInt(true)];
|
|
var data = new spine.BoneData(i, name_2, parent_2);
|
|
data.rotation = input.readFloat();
|
|
data.x = input.readFloat() * scale;
|
|
data.y = input.readFloat() * scale;
|
|
data.scaleX = input.readFloat();
|
|
data.scaleY = input.readFloat();
|
|
data.shearX = input.readFloat();
|
|
data.shearY = input.readFloat();
|
|
data.length = input.readFloat() * scale;
|
|
data.transformMode = SkeletonBinary.TransformModeValues[input.readInt(true)];
|
|
data.skinRequired = input.readBoolean();
|
|
if (nonessential)
|
|
spine.Color.rgba8888ToColor(data.color, input.readInt32());
|
|
skeletonData.bones.push(data);
|
|
}
|
|
n = input.readInt(true);
|
|
for (var i = 0; i < n; i++) {
|
|
var slotName = input.readString();
|
|
var boneData = skeletonData.bones[input.readInt(true)];
|
|
var data = new spine.SlotData(i, slotName, boneData);
|
|
spine.Color.rgba8888ToColor(data.color, input.readInt32());
|
|
var darkColor = input.readInt32();
|
|
if (darkColor != -1)
|
|
spine.Color.rgb888ToColor(data.darkColor = new spine.Color(), darkColor);
|
|
data.attachmentName = input.readStringRef();
|
|
data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)];
|
|
skeletonData.slots.push(data);
|
|
}
|
|
n = input.readInt(true);
|
|
for (var i = 0, nn = void 0; i < n; i++) {
|
|
var data = new spine.IkConstraintData(input.readString());
|
|
data.order = input.readInt(true);
|
|
data.skinRequired = input.readBoolean();
|
|
nn = input.readInt(true);
|
|
for (var ii = 0; ii < nn; ii++)
|
|
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
|
data.target = skeletonData.bones[input.readInt(true)];
|
|
data.mix = input.readFloat();
|
|
data.softness = input.readFloat() * scale;
|
|
data.bendDirection = input.readByte();
|
|
data.compress = input.readBoolean();
|
|
data.stretch = input.readBoolean();
|
|
data.uniform = input.readBoolean();
|
|
skeletonData.ikConstraints.push(data);
|
|
}
|
|
n = input.readInt(true);
|
|
for (var i = 0, nn = void 0; i < n; i++) {
|
|
var data = new spine.TransformConstraintData(input.readString());
|
|
data.order = input.readInt(true);
|
|
data.skinRequired = input.readBoolean();
|
|
nn = input.readInt(true);
|
|
for (var ii = 0; ii < nn; ii++)
|
|
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
|
data.target = skeletonData.bones[input.readInt(true)];
|
|
data.local = input.readBoolean();
|
|
data.relative = input.readBoolean();
|
|
data.offsetRotation = input.readFloat();
|
|
data.offsetX = input.readFloat() * scale;
|
|
data.offsetY = input.readFloat() * scale;
|
|
data.offsetScaleX = input.readFloat();
|
|
data.offsetScaleY = input.readFloat();
|
|
data.offsetShearY = input.readFloat();
|
|
data.rotateMix = input.readFloat();
|
|
data.translateMix = input.readFloat();
|
|
data.scaleMix = input.readFloat();
|
|
data.shearMix = input.readFloat();
|
|
skeletonData.transformConstraints.push(data);
|
|
}
|
|
n = input.readInt(true);
|
|
for (var i = 0, nn = void 0; i < n; i++) {
|
|
var data = new spine.PathConstraintData(input.readString());
|
|
data.order = input.readInt(true);
|
|
data.skinRequired = input.readBoolean();
|
|
nn = input.readInt(true);
|
|
for (var ii = 0; ii < nn; ii++)
|
|
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
|
data.target = skeletonData.slots[input.readInt(true)];
|
|
data.positionMode = SkeletonBinary.PositionModeValues[input.readInt(true)];
|
|
data.spacingMode = SkeletonBinary.SpacingModeValues[input.readInt(true)];
|
|
data.rotateMode = SkeletonBinary.RotateModeValues[input.readInt(true)];
|
|
data.offsetRotation = input.readFloat();
|
|
data.position = input.readFloat();
|
|
if (data.positionMode == spine.PositionMode.Fixed)
|
|
data.position *= scale;
|
|
data.spacing = input.readFloat();
|
|
if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
|
|
data.spacing *= scale;
|
|
data.rotateMix = input.readFloat();
|
|
data.translateMix = input.readFloat();
|
|
skeletonData.pathConstraints.push(data);
|
|
}
|
|
var defaultSkin = this.readSkin(input, skeletonData, true, nonessential);
|
|
if (defaultSkin != null) {
|
|
skeletonData.defaultSkin = defaultSkin;
|
|
skeletonData.skins.push(defaultSkin);
|
|
}
|
|
{
|
|
var i = skeletonData.skins.length;
|
|
spine.Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true));
|
|
for (; i < n; i++)
|
|
skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential);
|
|
}
|
|
n = this.linkedMeshes.length;
|
|
for (var i = 0; i < n; i++) {
|
|
var linkedMesh = this.linkedMeshes[i];
|
|
var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
|
|
if (skin == null)
|
|
throw new Error("Skin not found: " + linkedMesh.skin);
|
|
var parent_3 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
|
|
if (parent_3 == null)
|
|
throw new Error("Parent mesh not found: " + linkedMesh.parent);
|
|
linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_3 : linkedMesh.mesh;
|
|
linkedMesh.mesh.setParentMesh(parent_3);
|
|
linkedMesh.mesh.updateUVs();
|
|
}
|
|
this.linkedMeshes.length = 0;
|
|
n = input.readInt(true);
|
|
for (var i = 0; i < n; i++) {
|
|
var data = new spine.EventData(input.readStringRef());
|
|
data.intValue = input.readInt(false);
|
|
data.floatValue = input.readFloat();
|
|
data.stringValue = input.readString();
|
|
data.audioPath = input.readString();
|
|
if (data.audioPath != null) {
|
|
data.volume = input.readFloat();
|
|
data.balance = input.readFloat();
|
|
}
|
|
skeletonData.events.push(data);
|
|
}
|
|
n = input.readInt(true);
|
|
for (var i = 0; i < n; i++)
|
|
skeletonData.animations.push(this.readAnimation(input, input.readString(), skeletonData));
|
|
return skeletonData;
|
|
};
|
|
SkeletonBinary.prototype.readSkin = function (input, skeletonData, defaultSkin, nonessential) {
|
|
var skin = null;
|
|
var slotCount = 0;
|
|
if (defaultSkin) {
|
|
slotCount = input.readInt(true);
|
|
if (slotCount == 0)
|
|
return null;
|
|
skin = new spine.Skin("default");
|
|
}
|
|
else {
|
|
skin = new spine.Skin(input.readStringRef());
|
|
skin.bones.length = input.readInt(true);
|
|
for (var i = 0, n = skin.bones.length; i < n; i++)
|
|
skin.bones[i] = skeletonData.bones[input.readInt(true)];
|
|
for (var i = 0, n = input.readInt(true); i < n; i++)
|
|
skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]);
|
|
for (var i = 0, n = input.readInt(true); i < n; i++)
|
|
skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]);
|
|
for (var i = 0, n = input.readInt(true); i < n; i++)
|
|
skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]);
|
|
slotCount = input.readInt(true);
|
|
}
|
|
for (var i = 0; i < slotCount; i++) {
|
|
var slotIndex = input.readInt(true);
|
|
for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
var name_3 = input.readStringRef();
|
|
var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_3, nonessential);
|
|
if (attachment != null)
|
|
skin.setAttachment(slotIndex, name_3, attachment);
|
|
}
|
|
}
|
|
return skin;
|
|
};
|
|
SkeletonBinary.prototype.readAttachment = function (input, skeletonData, skin, slotIndex, attachmentName, nonessential) {
|
|
var scale = this.scale;
|
|
var name = input.readStringRef();
|
|
if (name == null)
|
|
name = attachmentName;
|
|
var typeIndex = input.readByte();
|
|
var type = SkeletonBinary.AttachmentTypeValues[typeIndex];
|
|
switch (type) {
|
|
case spine.AttachmentType.Region: {
|
|
var path = input.readStringRef();
|
|
var rotation = input.readFloat();
|
|
var x = input.readFloat();
|
|
var y = input.readFloat();
|
|
var scaleX = input.readFloat();
|
|
var scaleY = input.readFloat();
|
|
var width = input.readFloat();
|
|
var height = input.readFloat();
|
|
var color = input.readInt32();
|
|
if (path == null)
|
|
path = name;
|
|
var region = this.attachmentLoader.newRegionAttachment(skin, name, path);
|
|
if (region == null)
|
|
return null;
|
|
region.path = path;
|
|
region.x = x * scale;
|
|
region.y = y * scale;
|
|
region.scaleX = scaleX;
|
|
region.scaleY = scaleY;
|
|
region.rotation = rotation;
|
|
region.width = width * scale;
|
|
region.height = height * scale;
|
|
spine.Color.rgba8888ToColor(region.color, color);
|
|
region.updateOffset();
|
|
return region;
|
|
}
|
|
case spine.AttachmentType.BoundingBox: {
|
|
var vertexCount = input.readInt(true);
|
|
var vertices = this.readVertices(input, vertexCount);
|
|
var color = nonessential ? input.readInt32() : 0;
|
|
var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
|
|
if (box == null)
|
|
return null;
|
|
box.worldVerticesLength = vertexCount << 1;
|
|
box.vertices = vertices.vertices;
|
|
box.bones = vertices.bones;
|
|
if (nonessential)
|
|
spine.Color.rgba8888ToColor(box.color, color);
|
|
return box;
|
|
}
|
|
case spine.AttachmentType.Mesh: {
|
|
var path = input.readStringRef();
|
|
var color = input.readInt32();
|
|
var vertexCount = input.readInt(true);
|
|
var uvs = this.readFloatArray(input, vertexCount << 1, 1);
|
|
var triangles = this.readShortArray(input);
|
|
var vertices = this.readVertices(input, vertexCount);
|
|
var hullLength = input.readInt(true);
|
|
var edges = null;
|
|
var width = 0, height = 0;
|
|
if (nonessential) {
|
|
edges = this.readShortArray(input);
|
|
width = input.readFloat();
|
|
height = input.readFloat();
|
|
}
|
|
if (path == null)
|
|
path = name;
|
|
var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
|
|
if (mesh == null)
|
|
return null;
|
|
mesh.path = path;
|
|
spine.Color.rgba8888ToColor(mesh.color, color);
|
|
mesh.bones = vertices.bones;
|
|
mesh.vertices = vertices.vertices;
|
|
mesh.worldVerticesLength = vertexCount << 1;
|
|
mesh.triangles = triangles;
|
|
mesh.regionUVs = uvs;
|
|
mesh.updateUVs();
|
|
mesh.hullLength = hullLength << 1;
|
|
if (nonessential) {
|
|
mesh.edges = edges;
|
|
mesh.width = width * scale;
|
|
mesh.height = height * scale;
|
|
}
|
|
return mesh;
|
|
}
|
|
case spine.AttachmentType.LinkedMesh: {
|
|
var path = input.readStringRef();
|
|
var color = input.readInt32();
|
|
var skinName = input.readStringRef();
|
|
var parent_4 = input.readStringRef();
|
|
var inheritDeform = input.readBoolean();
|
|
var width = 0, height = 0;
|
|
if (nonessential) {
|
|
width = input.readFloat();
|
|
height = input.readFloat();
|
|
}
|
|
if (path == null)
|
|
path = name;
|
|
var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
|
|
if (mesh == null)
|
|
return null;
|
|
mesh.path = path;
|
|
spine.Color.rgba8888ToColor(mesh.color, color);
|
|
if (nonessential) {
|
|
mesh.width = width * scale;
|
|
mesh.height = height * scale;
|
|
}
|
|
this.linkedMeshes.push(new LinkedMesh(mesh, skinName, slotIndex, parent_4, inheritDeform));
|
|
return mesh;
|
|
}
|
|
case spine.AttachmentType.Path: {
|
|
var closed_1 = input.readBoolean();
|
|
var constantSpeed = input.readBoolean();
|
|
var vertexCount = input.readInt(true);
|
|
var vertices = this.readVertices(input, vertexCount);
|
|
var lengths = spine.Utils.newArray(vertexCount / 3, 0);
|
|
for (var i = 0, n = lengths.length; i < n; i++)
|
|
lengths[i] = input.readFloat() * scale;
|
|
var color = nonessential ? input.readInt32() : 0;
|
|
var path = this.attachmentLoader.newPathAttachment(skin, name);
|
|
if (path == null)
|
|
return null;
|
|
path.closed = closed_1;
|
|
path.constantSpeed = constantSpeed;
|
|
path.worldVerticesLength = vertexCount << 1;
|
|
path.vertices = vertices.vertices;
|
|
path.bones = vertices.bones;
|
|
path.lengths = lengths;
|
|
if (nonessential)
|
|
spine.Color.rgba8888ToColor(path.color, color);
|
|
return path;
|
|
}
|
|
case spine.AttachmentType.Point: {
|
|
var rotation = input.readFloat();
|
|
var x = input.readFloat();
|
|
var y = input.readFloat();
|
|
var color = nonessential ? input.readInt32() : 0;
|
|
var point = this.attachmentLoader.newPointAttachment(skin, name);
|
|
if (point == null)
|
|
return null;
|
|
point.x = x * scale;
|
|
point.y = y * scale;
|
|
point.rotation = rotation;
|
|
if (nonessential)
|
|
spine.Color.rgba8888ToColor(point.color, color);
|
|
return point;
|
|
}
|
|
case spine.AttachmentType.Clipping: {
|
|
var endSlotIndex = input.readInt(true);
|
|
var vertexCount = input.readInt(true);
|
|
var vertices = this.readVertices(input, vertexCount);
|
|
var color = nonessential ? input.readInt32() : 0;
|
|
var clip = this.attachmentLoader.newClippingAttachment(skin, name);
|
|
if (clip == null)
|
|
return null;
|
|
clip.endSlot = skeletonData.slots[endSlotIndex];
|
|
clip.worldVerticesLength = vertexCount << 1;
|
|
clip.vertices = vertices.vertices;
|
|
clip.bones = vertices.bones;
|
|
if (nonessential)
|
|
spine.Color.rgba8888ToColor(clip.color, color);
|
|
return clip;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonBinary.prototype.readVertices = function (input, vertexCount) {
|
|
var verticesLength = vertexCount << 1;
|
|
var vertices = new Vertices();
|
|
var scale = this.scale;
|
|
if (!input.readBoolean()) {
|
|
vertices.vertices = this.readFloatArray(input, verticesLength, scale);
|
|
return vertices;
|
|
}
|
|
var weights = new Array();
|
|
var bonesArray = new Array();
|
|
for (var i = 0; i < vertexCount; i++) {
|
|
var boneCount = input.readInt(true);
|
|
bonesArray.push(boneCount);
|
|
for (var ii = 0; ii < boneCount; ii++) {
|
|
bonesArray.push(input.readInt(true));
|
|
weights.push(input.readFloat() * scale);
|
|
weights.push(input.readFloat() * scale);
|
|
weights.push(input.readFloat());
|
|
}
|
|
}
|
|
vertices.vertices = spine.Utils.toFloatArray(weights);
|
|
vertices.bones = bonesArray;
|
|
return vertices;
|
|
};
|
|
SkeletonBinary.prototype.readFloatArray = function (input, n, scale) {
|
|
var array = new Array(n);
|
|
if (scale == 1) {
|
|
for (var i = 0; i < n; i++)
|
|
array[i] = input.readFloat();
|
|
}
|
|
else {
|
|
for (var i = 0; i < n; i++)
|
|
array[i] = input.readFloat() * scale;
|
|
}
|
|
return array;
|
|
};
|
|
SkeletonBinary.prototype.readShortArray = function (input) {
|
|
var n = input.readInt(true);
|
|
var array = new Array(n);
|
|
for (var i = 0; i < n; i++)
|
|
array[i] = input.readShort();
|
|
return array;
|
|
};
|
|
SkeletonBinary.prototype.readAnimation = function (input, name, skeletonData) {
|
|
var timelines = new Array();
|
|
var scale = this.scale;
|
|
var duration = 0;
|
|
var tempColor1 = new spine.Color();
|
|
var tempColor2 = new spine.Color();
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var slotIndex = input.readInt(true);
|
|
for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
var timelineType = input.readByte();
|
|
var frameCount = input.readInt(true);
|
|
switch (timelineType) {
|
|
case SkeletonBinary.SLOT_ATTACHMENT: {
|
|
var timeline = new spine.AttachmentTimeline(frameCount);
|
|
timeline.slotIndex = slotIndex;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[frameCount - 1]);
|
|
break;
|
|
}
|
|
case SkeletonBinary.SLOT_COLOR: {
|
|
var timeline = new spine.ColorTimeline(frameCount);
|
|
timeline.slotIndex = slotIndex;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
var time = input.readFloat();
|
|
spine.Color.rgba8888ToColor(tempColor1, input.readInt32());
|
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.ColorTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
case SkeletonBinary.SLOT_TWO_COLOR: {
|
|
var timeline = new spine.TwoColorTimeline(frameCount);
|
|
timeline.slotIndex = slotIndex;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
var time = input.readFloat();
|
|
spine.Color.rgba8888ToColor(tempColor1, input.readInt32());
|
|
spine.Color.rgb888ToColor(tempColor2, input.readInt32());
|
|
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, tempColor2.g, tempColor2.b);
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TwoColorTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var boneIndex = input.readInt(true);
|
|
for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
var timelineType = input.readByte();
|
|
var frameCount = input.readInt(true);
|
|
switch (timelineType) {
|
|
case SkeletonBinary.BONE_ROTATE: {
|
|
var timeline = new spine.RotateTimeline(frameCount);
|
|
timeline.boneIndex = boneIndex;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat());
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.RotateTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
case SkeletonBinary.BONE_TRANSLATE:
|
|
case SkeletonBinary.BONE_SCALE:
|
|
case SkeletonBinary.BONE_SHEAR: {
|
|
var timeline = void 0;
|
|
var timelineScale = 1;
|
|
if (timelineType == SkeletonBinary.BONE_SCALE)
|
|
timeline = new spine.ScaleTimeline(frameCount);
|
|
else if (timelineType == SkeletonBinary.BONE_SHEAR)
|
|
timeline = new spine.ShearTimeline(frameCount);
|
|
else {
|
|
timeline = new spine.TranslateTimeline(frameCount);
|
|
timelineScale = scale;
|
|
}
|
|
timeline.boneIndex = boneIndex;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale, input.readFloat() * timelineScale);
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TranslateTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var index = input.readInt(true);
|
|
var frameCount = input.readInt(true);
|
|
var timeline = new spine.IkConstraintTimeline(frameCount);
|
|
timeline.ikConstraintIndex = index;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(), input.readBoolean());
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.IkConstraintTimeline.ENTRIES]);
|
|
}
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var index = input.readInt(true);
|
|
var frameCount = input.readInt(true);
|
|
var timeline = new spine.TransformConstraintTimeline(frameCount);
|
|
timeline.transformConstraintIndex = index;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TransformConstraintTimeline.ENTRIES]);
|
|
}
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var index = input.readInt(true);
|
|
var data = skeletonData.pathConstraints[index];
|
|
for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
var timelineType = input.readByte();
|
|
var frameCount = input.readInt(true);
|
|
switch (timelineType) {
|
|
case SkeletonBinary.PATH_POSITION:
|
|
case SkeletonBinary.PATH_SPACING: {
|
|
var timeline = void 0;
|
|
var timelineScale = 1;
|
|
if (timelineType == SkeletonBinary.PATH_SPACING) {
|
|
timeline = new spine.PathConstraintSpacingTimeline(frameCount);
|
|
if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
|
|
timelineScale = scale;
|
|
}
|
|
else {
|
|
timeline = new spine.PathConstraintPositionTimeline(frameCount);
|
|
if (data.positionMode == spine.PositionMode.Fixed)
|
|
timelineScale = scale;
|
|
}
|
|
timeline.pathConstraintIndex = index;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.PathConstraintPositionTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
case SkeletonBinary.PATH_MIX: {
|
|
var timeline = new spine.PathConstraintMixTimeline(frameCount);
|
|
timeline.pathConstraintIndex = index;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.PathConstraintMixTimeline.ENTRIES]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (var i = 0, n = input.readInt(true); i < n; i++) {
|
|
var skin = skeletonData.skins[input.readInt(true)];
|
|
for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) {
|
|
var slotIndex = input.readInt(true);
|
|
for (var iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
|
|
var attachment = skin.getAttachment(slotIndex, input.readStringRef());
|
|
var weighted = attachment.bones != null;
|
|
var vertices = attachment.vertices;
|
|
var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
|
var frameCount = input.readInt(true);
|
|
var timeline = new spine.DeformTimeline(frameCount);
|
|
timeline.slotIndex = slotIndex;
|
|
timeline.attachment = attachment;
|
|
for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
var time = input.readFloat();
|
|
var deform = void 0;
|
|
var end = input.readInt(true);
|
|
if (end == 0)
|
|
deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices;
|
|
else {
|
|
deform = spine.Utils.newFloatArray(deformLength);
|
|
var start = input.readInt(true);
|
|
end += start;
|
|
if (scale == 1) {
|
|
for (var v = start; v < end; v++)
|
|
deform[v] = input.readFloat();
|
|
}
|
|
else {
|
|
for (var v = start; v < end; v++)
|
|
deform[v] = input.readFloat() * scale;
|
|
}
|
|
if (!weighted) {
|
|
for (var v = 0, vn = deform.length; v < vn; v++)
|
|
deform[v] += vertices[v];
|
|
}
|
|
}
|
|
timeline.setFrame(frameIndex, time, deform);
|
|
if (frameIndex < frameCount - 1)
|
|
this.readCurve(input, frameIndex, timeline);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[frameCount - 1]);
|
|
}
|
|
}
|
|
}
|
|
var drawOrderCount = input.readInt(true);
|
|
if (drawOrderCount > 0) {
|
|
var timeline = new spine.DrawOrderTimeline(drawOrderCount);
|
|
var slotCount = skeletonData.slots.length;
|
|
for (var i = 0; i < drawOrderCount; i++) {
|
|
var time = input.readFloat();
|
|
var offsetCount = input.readInt(true);
|
|
var drawOrder = spine.Utils.newArray(slotCount, 0);
|
|
for (var ii = slotCount - 1; ii >= 0; ii--)
|
|
drawOrder[ii] = -1;
|
|
var unchanged = spine.Utils.newArray(slotCount - offsetCount, 0);
|
|
var originalIndex = 0, unchangedIndex = 0;
|
|
for (var ii = 0; ii < offsetCount; ii++) {
|
|
var slotIndex = input.readInt(true);
|
|
while (originalIndex != slotIndex)
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
drawOrder[originalIndex + input.readInt(true)] = originalIndex++;
|
|
}
|
|
while (originalIndex < slotCount)
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
for (var ii = slotCount - 1; ii >= 0; ii--)
|
|
if (drawOrder[ii] == -1)
|
|
drawOrder[ii] = unchanged[--unchangedIndex];
|
|
timeline.setFrame(i, time, drawOrder);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[drawOrderCount - 1]);
|
|
}
|
|
var eventCount = input.readInt(true);
|
|
if (eventCount > 0) {
|
|
var timeline = new spine.EventTimeline(eventCount);
|
|
for (var i = 0; i < eventCount; i++) {
|
|
var time = input.readFloat();
|
|
var eventData = skeletonData.events[input.readInt(true)];
|
|
var event_4 = new spine.Event(time, eventData);
|
|
event_4.intValue = input.readInt(false);
|
|
event_4.floatValue = input.readFloat();
|
|
event_4.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
|
|
if (event_4.data.audioPath != null) {
|
|
event_4.volume = input.readFloat();
|
|
event_4.balance = input.readFloat();
|
|
}
|
|
timeline.setFrame(i, event_4);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[eventCount - 1]);
|
|
}
|
|
return new spine.Animation(name, timelines, duration);
|
|
};
|
|
SkeletonBinary.prototype.readCurve = function (input, frameIndex, timeline) {
|
|
switch (input.readByte()) {
|
|
case SkeletonBinary.CURVE_STEPPED:
|
|
timeline.setStepped(frameIndex);
|
|
break;
|
|
case SkeletonBinary.CURVE_BEZIER:
|
|
this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
|
|
break;
|
|
}
|
|
};
|
|
SkeletonBinary.prototype.setCurve = function (timeline, frameIndex, cx1, cy1, cx2, cy2) {
|
|
timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2);
|
|
};
|
|
SkeletonBinary.AttachmentTypeValues = [0, 1, 2, 3, 4, 5, 6];
|
|
SkeletonBinary.TransformModeValues = [spine.TransformMode.Normal, spine.TransformMode.OnlyTranslation, spine.TransformMode.NoRotationOrReflection, spine.TransformMode.NoScale, spine.TransformMode.NoScaleOrReflection];
|
|
SkeletonBinary.PositionModeValues = [spine.PositionMode.Fixed, spine.PositionMode.Percent];
|
|
SkeletonBinary.SpacingModeValues = [spine.SpacingMode.Length, spine.SpacingMode.Fixed, spine.SpacingMode.Percent];
|
|
SkeletonBinary.RotateModeValues = [spine.RotateMode.Tangent, spine.RotateMode.Chain, spine.RotateMode.ChainScale];
|
|
SkeletonBinary.BlendModeValues = [spine.BlendMode.Normal, spine.BlendMode.Additive, spine.BlendMode.Multiply, spine.BlendMode.Screen];
|
|
SkeletonBinary.BONE_ROTATE = 0;
|
|
SkeletonBinary.BONE_TRANSLATE = 1;
|
|
SkeletonBinary.BONE_SCALE = 2;
|
|
SkeletonBinary.BONE_SHEAR = 3;
|
|
SkeletonBinary.SLOT_ATTACHMENT = 0;
|
|
SkeletonBinary.SLOT_COLOR = 1;
|
|
SkeletonBinary.SLOT_TWO_COLOR = 2;
|
|
SkeletonBinary.PATH_POSITION = 0;
|
|
SkeletonBinary.PATH_SPACING = 1;
|
|
SkeletonBinary.PATH_MIX = 2;
|
|
SkeletonBinary.CURVE_LINEAR = 0;
|
|
SkeletonBinary.CURVE_STEPPED = 1;
|
|
SkeletonBinary.CURVE_BEZIER = 2;
|
|
return SkeletonBinary;
|
|
}());
|
|
spine.SkeletonBinary = SkeletonBinary;
|
|
var BinaryInput = (function () {
|
|
function BinaryInput(data, strings, index, buffer) {
|
|
if (strings === void 0) { strings = new Array(); }
|
|
if (index === void 0) { index = 0; }
|
|
if (buffer === void 0) { buffer = new DataView(data.buffer); }
|
|
this.strings = strings;
|
|
this.index = index;
|
|
this.buffer = buffer;
|
|
}
|
|
BinaryInput.prototype.readByte = function () {
|
|
return this.buffer.getInt8(this.index++);
|
|
};
|
|
BinaryInput.prototype.readShort = function () {
|
|
var value = this.buffer.getInt16(this.index);
|
|
this.index += 2;
|
|
return value;
|
|
};
|
|
BinaryInput.prototype.readInt32 = function () {
|
|
var value = this.buffer.getInt32(this.index);
|
|
this.index += 4;
|
|
return value;
|
|
};
|
|
BinaryInput.prototype.readInt = function (optimizePositive) {
|
|
var b = this.readByte();
|
|
var result = b & 0x7F;
|
|
if ((b & 0x80) != 0) {
|
|
b = this.readByte();
|
|
result |= (b & 0x7F) << 7;
|
|
if ((b & 0x80) != 0) {
|
|
b = this.readByte();
|
|
result |= (b & 0x7F) << 14;
|
|
if ((b & 0x80) != 0) {
|
|
b = this.readByte();
|
|
result |= (b & 0x7F) << 21;
|
|
if ((b & 0x80) != 0) {
|
|
b = this.readByte();
|
|
result |= (b & 0x7F) << 28;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
|
|
};
|
|
BinaryInput.prototype.readStringRef = function () {
|
|
var index = this.readInt(true);
|
|
return index == 0 ? null : this.strings[index - 1];
|
|
};
|
|
BinaryInput.prototype.readString = function () {
|
|
var byteCount = this.readInt(true);
|
|
switch (byteCount) {
|
|
case 0:
|
|
return null;
|
|
case 1:
|
|
return "";
|
|
}
|
|
byteCount--;
|
|
var chars = "";
|
|
var charCount = 0;
|
|
for (var i = 0; i < byteCount;) {
|
|
var b = this.readByte();
|
|
switch (b >> 4) {
|
|
case 12:
|
|
case 13:
|
|
chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F));
|
|
i += 2;
|
|
break;
|
|
case 14:
|
|
chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F));
|
|
i += 3;
|
|
break;
|
|
default:
|
|
chars += String.fromCharCode(b);
|
|
i++;
|
|
}
|
|
}
|
|
return chars;
|
|
};
|
|
BinaryInput.prototype.readFloat = function () {
|
|
var value = this.buffer.getFloat32(this.index);
|
|
this.index += 4;
|
|
return value;
|
|
};
|
|
BinaryInput.prototype.readBoolean = function () {
|
|
return this.readByte() != 0;
|
|
};
|
|
return BinaryInput;
|
|
}());
|
|
var LinkedMesh = (function () {
|
|
function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) {
|
|
this.mesh = mesh;
|
|
this.skin = skin;
|
|
this.slotIndex = slotIndex;
|
|
this.parent = parent;
|
|
this.inheritDeform = inheritDeform;
|
|
}
|
|
return LinkedMesh;
|
|
}());
|
|
var Vertices = (function () {
|
|
function Vertices(bones, vertices) {
|
|
if (bones === void 0) { bones = null; }
|
|
if (vertices === void 0) { vertices = null; }
|
|
this.bones = bones;
|
|
this.vertices = vertices;
|
|
}
|
|
return Vertices;
|
|
}());
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkeletonBounds = (function () {
|
|
function SkeletonBounds() {
|
|
this.minX = 0;
|
|
this.minY = 0;
|
|
this.maxX = 0;
|
|
this.maxY = 0;
|
|
this.boundingBoxes = new Array();
|
|
this.polygons = new Array();
|
|
this.polygonPool = new spine.Pool(function () {
|
|
return spine.Utils.newFloatArray(16);
|
|
});
|
|
}
|
|
SkeletonBounds.prototype.update = function (skeleton, updateAabb) {
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
var boundingBoxes = this.boundingBoxes;
|
|
var polygons = this.polygons;
|
|
var polygonPool = this.polygonPool;
|
|
var slots = skeleton.slots;
|
|
var slotCount = slots.length;
|
|
boundingBoxes.length = 0;
|
|
polygonPool.freeAll(polygons);
|
|
polygons.length = 0;
|
|
for (var i = 0; i < slotCount; i++) {
|
|
var slot = slots[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var attachment = slot.getAttachment();
|
|
if (attachment instanceof spine.BoundingBoxAttachment) {
|
|
var boundingBox = attachment;
|
|
boundingBoxes.push(boundingBox);
|
|
var polygon = polygonPool.obtain();
|
|
if (polygon.length != boundingBox.worldVerticesLength) {
|
|
polygon = spine.Utils.newFloatArray(boundingBox.worldVerticesLength);
|
|
}
|
|
polygons.push(polygon);
|
|
boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2);
|
|
}
|
|
}
|
|
if (updateAabb) {
|
|
this.aabbCompute();
|
|
}
|
|
else {
|
|
this.minX = Number.POSITIVE_INFINITY;
|
|
this.minY = Number.POSITIVE_INFINITY;
|
|
this.maxX = Number.NEGATIVE_INFINITY;
|
|
this.maxY = Number.NEGATIVE_INFINITY;
|
|
}
|
|
};
|
|
SkeletonBounds.prototype.aabbCompute = function () {
|
|
var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
|
|
var polygons = this.polygons;
|
|
for (var i = 0, n = polygons.length; i < n; i++) {
|
|
var polygon = polygons[i];
|
|
var vertices = polygon;
|
|
for (var ii = 0, nn = polygon.length; ii < nn; ii += 2) {
|
|
var x = vertices[ii];
|
|
var y = vertices[ii + 1];
|
|
minX = Math.min(minX, x);
|
|
minY = Math.min(minY, y);
|
|
maxX = Math.max(maxX, x);
|
|
maxY = Math.max(maxY, y);
|
|
}
|
|
}
|
|
this.minX = minX;
|
|
this.minY = minY;
|
|
this.maxX = maxX;
|
|
this.maxY = maxY;
|
|
};
|
|
SkeletonBounds.prototype.aabbContainsPoint = function (x, y) {
|
|
return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
|
|
};
|
|
SkeletonBounds.prototype.aabbIntersectsSegment = function (x1, y1, x2, y2) {
|
|
var minX = this.minX;
|
|
var minY = this.minY;
|
|
var maxX = this.maxX;
|
|
var maxY = this.maxY;
|
|
if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
|
|
return false;
|
|
var m = (y2 - y1) / (x2 - x1);
|
|
var y = m * (minX - x1) + y1;
|
|
if (y > minY && y < maxY)
|
|
return true;
|
|
y = m * (maxX - x1) + y1;
|
|
if (y > minY && y < maxY)
|
|
return true;
|
|
var x = (minY - y1) / m + x1;
|
|
if (x > minX && x < maxX)
|
|
return true;
|
|
x = (maxY - y1) / m + x1;
|
|
if (x > minX && x < maxX)
|
|
return true;
|
|
return false;
|
|
};
|
|
SkeletonBounds.prototype.aabbIntersectsSkeleton = function (bounds) {
|
|
return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
|
|
};
|
|
SkeletonBounds.prototype.containsPoint = function (x, y) {
|
|
var polygons = this.polygons;
|
|
for (var i = 0, n = polygons.length; i < n; i++)
|
|
if (this.containsPointPolygon(polygons[i], x, y))
|
|
return this.boundingBoxes[i];
|
|
return null;
|
|
};
|
|
SkeletonBounds.prototype.containsPointPolygon = function (polygon, x, y) {
|
|
var vertices = polygon;
|
|
var nn = polygon.length;
|
|
var prevIndex = nn - 2;
|
|
var inside = false;
|
|
for (var ii = 0; ii < nn; ii += 2) {
|
|
var vertexY = vertices[ii + 1];
|
|
var prevY = vertices[prevIndex + 1];
|
|
if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
|
|
var vertexX = vertices[ii];
|
|
if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x)
|
|
inside = !inside;
|
|
}
|
|
prevIndex = ii;
|
|
}
|
|
return inside;
|
|
};
|
|
SkeletonBounds.prototype.intersectsSegment = function (x1, y1, x2, y2) {
|
|
var polygons = this.polygons;
|
|
for (var i = 0, n = polygons.length; i < n; i++)
|
|
if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2))
|
|
return this.boundingBoxes[i];
|
|
return null;
|
|
};
|
|
SkeletonBounds.prototype.intersectsSegmentPolygon = function (polygon, x1, y1, x2, y2) {
|
|
var vertices = polygon;
|
|
var nn = polygon.length;
|
|
var width12 = x1 - x2, height12 = y1 - y2;
|
|
var det1 = x1 * y2 - y1 * x2;
|
|
var x3 = vertices[nn - 2], y3 = vertices[nn - 1];
|
|
for (var ii = 0; ii < nn; ii += 2) {
|
|
var x4 = vertices[ii], y4 = vertices[ii + 1];
|
|
var det2 = x3 * y4 - y3 * x4;
|
|
var width34 = x3 - x4, height34 = y3 - y4;
|
|
var det3 = width12 * height34 - height12 * width34;
|
|
var x = (det1 * width34 - width12 * det2) / det3;
|
|
if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
|
|
var y = (det1 * height34 - height12 * det2) / det3;
|
|
if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1)))
|
|
return true;
|
|
}
|
|
x3 = x4;
|
|
y3 = y4;
|
|
}
|
|
return false;
|
|
};
|
|
SkeletonBounds.prototype.getPolygon = function (boundingBox) {
|
|
if (boundingBox == null)
|
|
throw new Error("boundingBox cannot be null.");
|
|
var index = this.boundingBoxes.indexOf(boundingBox);
|
|
return index == -1 ? null : this.polygons[index];
|
|
};
|
|
SkeletonBounds.prototype.getWidth = function () {
|
|
return this.maxX - this.minX;
|
|
};
|
|
SkeletonBounds.prototype.getHeight = function () {
|
|
return this.maxY - this.minY;
|
|
};
|
|
return SkeletonBounds;
|
|
}());
|
|
spine.SkeletonBounds = SkeletonBounds;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkeletonClipping = (function () {
|
|
function SkeletonClipping() {
|
|
this.triangulator = new spine.Triangulator();
|
|
this.clippingPolygon = new Array();
|
|
this.clipOutput = new Array();
|
|
this.clippedVertices = new Array();
|
|
this.clippedTriangles = new Array();
|
|
this.scratch = new Array();
|
|
}
|
|
SkeletonClipping.prototype.clipStart = function (slot, clip) {
|
|
if (this.clipAttachment != null)
|
|
return 0;
|
|
this.clipAttachment = clip;
|
|
var n = clip.worldVerticesLength;
|
|
var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
|
|
clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
|
|
var clippingPolygon = this.clippingPolygon;
|
|
SkeletonClipping.makeClockwise(clippingPolygon);
|
|
var clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon));
|
|
for (var i = 0, n_2 = clippingPolygons.length; i < n_2; i++) {
|
|
var polygon = clippingPolygons[i];
|
|
SkeletonClipping.makeClockwise(polygon);
|
|
polygon.push(polygon[0]);
|
|
polygon.push(polygon[1]);
|
|
}
|
|
return clippingPolygons.length;
|
|
};
|
|
SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
|
|
if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
|
|
this.clipEnd();
|
|
};
|
|
SkeletonClipping.prototype.clipEnd = function () {
|
|
if (this.clipAttachment == null)
|
|
return;
|
|
this.clipAttachment = null;
|
|
this.clippingPolygons = null;
|
|
this.clippedVertices.length = 0;
|
|
this.clippedTriangles.length = 0;
|
|
this.clippingPolygon.length = 0;
|
|
};
|
|
SkeletonClipping.prototype.isClipping = function () {
|
|
return this.clipAttachment != null;
|
|
};
|
|
SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
|
|
var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
|
|
var clippedTriangles = this.clippedTriangles;
|
|
var polygons = this.clippingPolygons;
|
|
var polygonsCount = this.clippingPolygons.length;
|
|
var vertexSize = twoColor ? 12 : 8;
|
|
var index = 0;
|
|
clippedVertices.length = 0;
|
|
clippedTriangles.length = 0;
|
|
outer: for (var i = 0; i < trianglesLength; i += 3) {
|
|
var vertexOffset = triangles[i] << 1;
|
|
var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
|
|
var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
|
|
vertexOffset = triangles[i + 1] << 1;
|
|
var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
|
|
var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
|
|
vertexOffset = triangles[i + 2] << 1;
|
|
var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
|
|
var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
|
|
for (var p = 0; p < polygonsCount; p++) {
|
|
var s = clippedVertices.length;
|
|
if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
|
|
var clipOutputLength = clipOutput.length;
|
|
if (clipOutputLength == 0)
|
|
continue;
|
|
var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
|
|
var d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
|
var clipOutputCount = clipOutputLength >> 1;
|
|
var clipOutputItems = this.clipOutput;
|
|
var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
|
|
for (var ii = 0; ii < clipOutputLength; ii += 2) {
|
|
var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
|
|
clippedVerticesItems[s] = x;
|
|
clippedVerticesItems[s + 1] = y;
|
|
clippedVerticesItems[s + 2] = light.r;
|
|
clippedVerticesItems[s + 3] = light.g;
|
|
clippedVerticesItems[s + 4] = light.b;
|
|
clippedVerticesItems[s + 5] = light.a;
|
|
var c0 = x - x3, c1 = y - y3;
|
|
var a = (d0 * c0 + d1 * c1) * d;
|
|
var b = (d4 * c0 + d2 * c1) * d;
|
|
var c = 1 - a - b;
|
|
clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
|
|
clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
|
|
if (twoColor) {
|
|
clippedVerticesItems[s + 8] = dark.r;
|
|
clippedVerticesItems[s + 9] = dark.g;
|
|
clippedVerticesItems[s + 10] = dark.b;
|
|
clippedVerticesItems[s + 11] = dark.a;
|
|
}
|
|
s += vertexSize;
|
|
}
|
|
s = clippedTriangles.length;
|
|
var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
|
|
clipOutputCount--;
|
|
for (var ii = 1; ii < clipOutputCount; ii++) {
|
|
clippedTrianglesItems[s] = index;
|
|
clippedTrianglesItems[s + 1] = (index + ii);
|
|
clippedTrianglesItems[s + 2] = (index + ii + 1);
|
|
s += 3;
|
|
}
|
|
index += clipOutputCount + 1;
|
|
}
|
|
else {
|
|
var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
|
|
clippedVerticesItems[s] = x1;
|
|
clippedVerticesItems[s + 1] = y1;
|
|
clippedVerticesItems[s + 2] = light.r;
|
|
clippedVerticesItems[s + 3] = light.g;
|
|
clippedVerticesItems[s + 4] = light.b;
|
|
clippedVerticesItems[s + 5] = light.a;
|
|
if (!twoColor) {
|
|
clippedVerticesItems[s + 6] = u1;
|
|
clippedVerticesItems[s + 7] = v1;
|
|
clippedVerticesItems[s + 8] = x2;
|
|
clippedVerticesItems[s + 9] = y2;
|
|
clippedVerticesItems[s + 10] = light.r;
|
|
clippedVerticesItems[s + 11] = light.g;
|
|
clippedVerticesItems[s + 12] = light.b;
|
|
clippedVerticesItems[s + 13] = light.a;
|
|
clippedVerticesItems[s + 14] = u2;
|
|
clippedVerticesItems[s + 15] = v2;
|
|
clippedVerticesItems[s + 16] = x3;
|
|
clippedVerticesItems[s + 17] = y3;
|
|
clippedVerticesItems[s + 18] = light.r;
|
|
clippedVerticesItems[s + 19] = light.g;
|
|
clippedVerticesItems[s + 20] = light.b;
|
|
clippedVerticesItems[s + 21] = light.a;
|
|
clippedVerticesItems[s + 22] = u3;
|
|
clippedVerticesItems[s + 23] = v3;
|
|
}
|
|
else {
|
|
clippedVerticesItems[s + 6] = u1;
|
|
clippedVerticesItems[s + 7] = v1;
|
|
clippedVerticesItems[s + 8] = dark.r;
|
|
clippedVerticesItems[s + 9] = dark.g;
|
|
clippedVerticesItems[s + 10] = dark.b;
|
|
clippedVerticesItems[s + 11] = dark.a;
|
|
clippedVerticesItems[s + 12] = x2;
|
|
clippedVerticesItems[s + 13] = y2;
|
|
clippedVerticesItems[s + 14] = light.r;
|
|
clippedVerticesItems[s + 15] = light.g;
|
|
clippedVerticesItems[s + 16] = light.b;
|
|
clippedVerticesItems[s + 17] = light.a;
|
|
clippedVerticesItems[s + 18] = u2;
|
|
clippedVerticesItems[s + 19] = v2;
|
|
clippedVerticesItems[s + 20] = dark.r;
|
|
clippedVerticesItems[s + 21] = dark.g;
|
|
clippedVerticesItems[s + 22] = dark.b;
|
|
clippedVerticesItems[s + 23] = dark.a;
|
|
clippedVerticesItems[s + 24] = x3;
|
|
clippedVerticesItems[s + 25] = y3;
|
|
clippedVerticesItems[s + 26] = light.r;
|
|
clippedVerticesItems[s + 27] = light.g;
|
|
clippedVerticesItems[s + 28] = light.b;
|
|
clippedVerticesItems[s + 29] = light.a;
|
|
clippedVerticesItems[s + 30] = u3;
|
|
clippedVerticesItems[s + 31] = v3;
|
|
clippedVerticesItems[s + 32] = dark.r;
|
|
clippedVerticesItems[s + 33] = dark.g;
|
|
clippedVerticesItems[s + 34] = dark.b;
|
|
clippedVerticesItems[s + 35] = dark.a;
|
|
}
|
|
s = clippedTriangles.length;
|
|
var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
|
|
clippedTrianglesItems[s] = index;
|
|
clippedTrianglesItems[s + 1] = (index + 1);
|
|
clippedTrianglesItems[s + 2] = (index + 2);
|
|
index += 3;
|
|
continue outer;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
|
|
var originalOutput = output;
|
|
var clipped = false;
|
|
var input = null;
|
|
if (clippingArea.length % 4 >= 2) {
|
|
input = output;
|
|
output = this.scratch;
|
|
}
|
|
else
|
|
input = this.scratch;
|
|
input.length = 0;
|
|
input.push(x1);
|
|
input.push(y1);
|
|
input.push(x2);
|
|
input.push(y2);
|
|
input.push(x3);
|
|
input.push(y3);
|
|
input.push(x1);
|
|
input.push(y1);
|
|
output.length = 0;
|
|
var clippingVertices = clippingArea;
|
|
var clippingVerticesLast = clippingArea.length - 4;
|
|
for (var i = 0;; i += 2) {
|
|
var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
|
|
var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
|
|
var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
|
|
var inputVertices = input;
|
|
var inputVerticesLength = input.length - 2, outputStart = output.length;
|
|
for (var ii = 0; ii < inputVerticesLength; ii += 2) {
|
|
var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
|
|
var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
|
|
var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
|
|
if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
|
|
if (side2) {
|
|
output.push(inputX2);
|
|
output.push(inputY2);
|
|
continue;
|
|
}
|
|
var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
|
var s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);
|
|
if (Math.abs(s) > 0.000001) {
|
|
var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;
|
|
output.push(edgeX + (edgeX2 - edgeX) * ua);
|
|
output.push(edgeY + (edgeY2 - edgeY) * ua);
|
|
}
|
|
else {
|
|
output.push(edgeX);
|
|
output.push(edgeY);
|
|
}
|
|
}
|
|
else if (side2) {
|
|
var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
|
var s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);
|
|
if (Math.abs(s) > 0.000001) {
|
|
var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;
|
|
output.push(edgeX + (edgeX2 - edgeX) * ua);
|
|
output.push(edgeY + (edgeY2 - edgeY) * ua);
|
|
}
|
|
else {
|
|
output.push(edgeX);
|
|
output.push(edgeY);
|
|
}
|
|
output.push(inputX2);
|
|
output.push(inputY2);
|
|
}
|
|
clipped = true;
|
|
}
|
|
if (outputStart == output.length) {
|
|
originalOutput.length = 0;
|
|
return true;
|
|
}
|
|
output.push(output[0]);
|
|
output.push(output[1]);
|
|
if (i == clippingVerticesLast)
|
|
break;
|
|
var temp = output;
|
|
output = input;
|
|
output.length = 0;
|
|
input = temp;
|
|
}
|
|
if (originalOutput != output) {
|
|
originalOutput.length = 0;
|
|
for (var i = 0, n = output.length - 2; i < n; i++)
|
|
originalOutput[i] = output[i];
|
|
}
|
|
else
|
|
originalOutput.length = originalOutput.length - 2;
|
|
return clipped;
|
|
};
|
|
SkeletonClipping.makeClockwise = function (polygon) {
|
|
var vertices = polygon;
|
|
var verticeslength = polygon.length;
|
|
var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
|
|
for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
|
|
p1x = vertices[i];
|
|
p1y = vertices[i + 1];
|
|
p2x = vertices[i + 2];
|
|
p2y = vertices[i + 3];
|
|
area += p1x * p2y - p2x * p1y;
|
|
}
|
|
if (area < 0)
|
|
return;
|
|
for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
|
|
var x = vertices[i], y = vertices[i + 1];
|
|
var other = lastX - i;
|
|
vertices[i] = vertices[other];
|
|
vertices[i + 1] = vertices[other + 1];
|
|
vertices[other] = x;
|
|
vertices[other + 1] = y;
|
|
}
|
|
};
|
|
return SkeletonClipping;
|
|
}());
|
|
spine.SkeletonClipping = SkeletonClipping;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkeletonData = (function () {
|
|
function SkeletonData() {
|
|
this.bones = new Array();
|
|
this.slots = new Array();
|
|
this.skins = new Array();
|
|
this.events = new Array();
|
|
this.animations = new Array();
|
|
this.ikConstraints = new Array();
|
|
this.transformConstraints = new Array();
|
|
this.pathConstraints = new Array();
|
|
this.fps = 0;
|
|
}
|
|
SkeletonData.prototype.findBone = function (boneName) {
|
|
if (boneName == null)
|
|
throw new Error("boneName cannot be null.");
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (bone.name == boneName)
|
|
return bone;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findBoneIndex = function (boneName) {
|
|
if (boneName == null)
|
|
throw new Error("boneName cannot be null.");
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++)
|
|
if (bones[i].name == boneName)
|
|
return i;
|
|
return -1;
|
|
};
|
|
SkeletonData.prototype.findSlot = function (slotName) {
|
|
if (slotName == null)
|
|
throw new Error("slotName cannot be null.");
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (slot.name == slotName)
|
|
return slot;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findSlotIndex = function (slotName) {
|
|
if (slotName == null)
|
|
throw new Error("slotName cannot be null.");
|
|
var slots = this.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++)
|
|
if (slots[i].name == slotName)
|
|
return i;
|
|
return -1;
|
|
};
|
|
SkeletonData.prototype.findSkin = function (skinName) {
|
|
if (skinName == null)
|
|
throw new Error("skinName cannot be null.");
|
|
var skins = this.skins;
|
|
for (var i = 0, n = skins.length; i < n; i++) {
|
|
var skin = skins[i];
|
|
if (skin.name == skinName)
|
|
return skin;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findEvent = function (eventDataName) {
|
|
if (eventDataName == null)
|
|
throw new Error("eventDataName cannot be null.");
|
|
var events = this.events;
|
|
for (var i = 0, n = events.length; i < n; i++) {
|
|
var event_5 = events[i];
|
|
if (event_5.name == eventDataName)
|
|
return event_5;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findAnimation = function (animationName) {
|
|
if (animationName == null)
|
|
throw new Error("animationName cannot be null.");
|
|
var animations = this.animations;
|
|
for (var i = 0, n = animations.length; i < n; i++) {
|
|
var animation = animations[i];
|
|
if (animation.name == animationName)
|
|
return animation;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findIkConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var ikConstraints = this.ikConstraints;
|
|
for (var i = 0, n = ikConstraints.length; i < n; i++) {
|
|
var constraint = ikConstraints[i];
|
|
if (constraint.name == constraintName)
|
|
return constraint;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findTransformConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var transformConstraints = this.transformConstraints;
|
|
for (var i = 0, n = transformConstraints.length; i < n; i++) {
|
|
var constraint = transformConstraints[i];
|
|
if (constraint.name == constraintName)
|
|
return constraint;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findPathConstraint = function (constraintName) {
|
|
if (constraintName == null)
|
|
throw new Error("constraintName cannot be null.");
|
|
var pathConstraints = this.pathConstraints;
|
|
for (var i = 0, n = pathConstraints.length; i < n; i++) {
|
|
var constraint = pathConstraints[i];
|
|
if (constraint.name == constraintName)
|
|
return constraint;
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) {
|
|
if (pathConstraintName == null)
|
|
throw new Error("pathConstraintName cannot be null.");
|
|
var pathConstraints = this.pathConstraints;
|
|
for (var i = 0, n = pathConstraints.length; i < n; i++)
|
|
if (pathConstraints[i].name == pathConstraintName)
|
|
return i;
|
|
return -1;
|
|
};
|
|
return SkeletonData;
|
|
}());
|
|
spine.SkeletonData = SkeletonData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkeletonJson = (function () {
|
|
function SkeletonJson(attachmentLoader) {
|
|
this.scale = 1;
|
|
this.linkedMeshes = new Array();
|
|
this.attachmentLoader = attachmentLoader;
|
|
}
|
|
SkeletonJson.prototype.readSkeletonData = function (json) {
|
|
var scale = this.scale;
|
|
var skeletonData = new spine.SkeletonData();
|
|
var root = typeof (json) === "string" ? JSON.parse(json) : json;
|
|
var skeletonMap = root.skeleton;
|
|
if (skeletonMap != null) {
|
|
skeletonData.hash = skeletonMap.hash;
|
|
skeletonData.version = skeletonMap.spine;
|
|
if ("3.8.75" == skeletonData.version)
|
|
throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
|
|
skeletonData.x = skeletonMap.x;
|
|
skeletonData.y = skeletonMap.y;
|
|
skeletonData.width = skeletonMap.width;
|
|
skeletonData.height = skeletonMap.height;
|
|
skeletonData.fps = skeletonMap.fps;
|
|
skeletonData.imagesPath = skeletonMap.images;
|
|
}
|
|
if (root.bones) {
|
|
for (var i = 0; i < root.bones.length; i++) {
|
|
var boneMap = root.bones[i];
|
|
var parent_5 = null;
|
|
var parentName = this.getValue(boneMap, "parent", null);
|
|
if (parentName != null) {
|
|
parent_5 = skeletonData.findBone(parentName);
|
|
if (parent_5 == null)
|
|
throw new Error("Parent bone not found: " + parentName);
|
|
}
|
|
var data = new spine.BoneData(skeletonData.bones.length, boneMap.name, parent_5);
|
|
data.length = this.getValue(boneMap, "length", 0) * scale;
|
|
data.x = this.getValue(boneMap, "x", 0) * scale;
|
|
data.y = this.getValue(boneMap, "y", 0) * scale;
|
|
data.rotation = this.getValue(boneMap, "rotation", 0);
|
|
data.scaleX = this.getValue(boneMap, "scaleX", 1);
|
|
data.scaleY = this.getValue(boneMap, "scaleY", 1);
|
|
data.shearX = this.getValue(boneMap, "shearX", 0);
|
|
data.shearY = this.getValue(boneMap, "shearY", 0);
|
|
data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
|
|
data.skinRequired = this.getValue(boneMap, "skin", false);
|
|
skeletonData.bones.push(data);
|
|
}
|
|
}
|
|
if (root.slots) {
|
|
for (var i = 0; i < root.slots.length; i++) {
|
|
var slotMap = root.slots[i];
|
|
var slotName = slotMap.name;
|
|
var boneName = slotMap.bone;
|
|
var boneData = skeletonData.findBone(boneName);
|
|
if (boneData == null)
|
|
throw new Error("Slot bone not found: " + boneName);
|
|
var data = new spine.SlotData(skeletonData.slots.length, slotName, boneData);
|
|
var color = this.getValue(slotMap, "color", null);
|
|
if (color != null)
|
|
data.color.setFromString(color);
|
|
var dark = this.getValue(slotMap, "dark", null);
|
|
if (dark != null) {
|
|
data.darkColor = new spine.Color(1, 1, 1, 1);
|
|
data.darkColor.setFromString(dark);
|
|
}
|
|
data.attachmentName = this.getValue(slotMap, "attachment", null);
|
|
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
|
|
skeletonData.slots.push(data);
|
|
}
|
|
}
|
|
if (root.ik) {
|
|
for (var i = 0; i < root.ik.length; i++) {
|
|
var constraintMap = root.ik[i];
|
|
var data = new spine.IkConstraintData(constraintMap.name);
|
|
data.order = this.getValue(constraintMap, "order", 0);
|
|
data.skinRequired = this.getValue(constraintMap, "skin", false);
|
|
for (var j = 0; j < constraintMap.bones.length; j++) {
|
|
var boneName = constraintMap.bones[j];
|
|
var bone = skeletonData.findBone(boneName);
|
|
if (bone == null)
|
|
throw new Error("IK bone not found: " + boneName);
|
|
data.bones.push(bone);
|
|
}
|
|
var targetName = constraintMap.target;
|
|
data.target = skeletonData.findBone(targetName);
|
|
if (data.target == null)
|
|
throw new Error("IK target bone not found: " + targetName);
|
|
data.mix = this.getValue(constraintMap, "mix", 1);
|
|
data.softness = this.getValue(constraintMap, "softness", 0) * scale;
|
|
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
|
|
data.compress = this.getValue(constraintMap, "compress", false);
|
|
data.stretch = this.getValue(constraintMap, "stretch", false);
|
|
data.uniform = this.getValue(constraintMap, "uniform", false);
|
|
skeletonData.ikConstraints.push(data);
|
|
}
|
|
}
|
|
if (root.transform) {
|
|
for (var i = 0; i < root.transform.length; i++) {
|
|
var constraintMap = root.transform[i];
|
|
var data = new spine.TransformConstraintData(constraintMap.name);
|
|
data.order = this.getValue(constraintMap, "order", 0);
|
|
data.skinRequired = this.getValue(constraintMap, "skin", false);
|
|
for (var j = 0; j < constraintMap.bones.length; j++) {
|
|
var boneName = constraintMap.bones[j];
|
|
var bone = skeletonData.findBone(boneName);
|
|
if (bone == null)
|
|
throw new Error("Transform constraint bone not found: " + boneName);
|
|
data.bones.push(bone);
|
|
}
|
|
var targetName = constraintMap.target;
|
|
data.target = skeletonData.findBone(targetName);
|
|
if (data.target == null)
|
|
throw new Error("Transform constraint target bone not found: " + targetName);
|
|
data.local = this.getValue(constraintMap, "local", false);
|
|
data.relative = this.getValue(constraintMap, "relative", false);
|
|
data.offsetRotation = this.getValue(constraintMap, "rotation", 0);
|
|
data.offsetX = this.getValue(constraintMap, "x", 0) * scale;
|
|
data.offsetY = this.getValue(constraintMap, "y", 0) * scale;
|
|
data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0);
|
|
data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0);
|
|
data.offsetShearY = this.getValue(constraintMap, "shearY", 0);
|
|
data.rotateMix = this.getValue(constraintMap, "rotateMix", 1);
|
|
data.translateMix = this.getValue(constraintMap, "translateMix", 1);
|
|
data.scaleMix = this.getValue(constraintMap, "scaleMix", 1);
|
|
data.shearMix = this.getValue(constraintMap, "shearMix", 1);
|
|
skeletonData.transformConstraints.push(data);
|
|
}
|
|
}
|
|
if (root.path) {
|
|
for (var i = 0; i < root.path.length; i++) {
|
|
var constraintMap = root.path[i];
|
|
var data = new spine.PathConstraintData(constraintMap.name);
|
|
data.order = this.getValue(constraintMap, "order", 0);
|
|
data.skinRequired = this.getValue(constraintMap, "skin", false);
|
|
for (var j = 0; j < constraintMap.bones.length; j++) {
|
|
var boneName = constraintMap.bones[j];
|
|
var bone = skeletonData.findBone(boneName);
|
|
if (bone == null)
|
|
throw new Error("Transform constraint bone not found: " + boneName);
|
|
data.bones.push(bone);
|
|
}
|
|
var targetName = constraintMap.target;
|
|
data.target = skeletonData.findSlot(targetName);
|
|
if (data.target == null)
|
|
throw new Error("Path target slot not found: " + targetName);
|
|
data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent"));
|
|
data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length"));
|
|
data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent"));
|
|
data.offsetRotation = this.getValue(constraintMap, "rotation", 0);
|
|
data.position = this.getValue(constraintMap, "position", 0);
|
|
if (data.positionMode == spine.PositionMode.Fixed)
|
|
data.position *= scale;
|
|
data.spacing = this.getValue(constraintMap, "spacing", 0);
|
|
if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
|
|
data.spacing *= scale;
|
|
data.rotateMix = this.getValue(constraintMap, "rotateMix", 1);
|
|
data.translateMix = this.getValue(constraintMap, "translateMix", 1);
|
|
skeletonData.pathConstraints.push(data);
|
|
}
|
|
}
|
|
if (root.skins) {
|
|
for (var i = 0; i < root.skins.length; i++) {
|
|
var skinMap = root.skins[i];
|
|
var skin = new spine.Skin(skinMap.name);
|
|
if (skinMap.bones) {
|
|
for (var ii = 0; ii < skinMap.bones.length; ii++) {
|
|
var bone = skeletonData.findBone(skinMap.bones[ii]);
|
|
if (bone == null)
|
|
throw new Error("Skin bone not found: " + skinMap.bones[i]);
|
|
skin.bones.push(bone);
|
|
}
|
|
}
|
|
if (skinMap.ik) {
|
|
for (var ii = 0; ii < skinMap.ik.length; ii++) {
|
|
var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
|
|
if (constraint == null)
|
|
throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
|
|
skin.constraints.push(constraint);
|
|
}
|
|
}
|
|
if (skinMap.transform) {
|
|
for (var ii = 0; ii < skinMap.transform.length; ii++) {
|
|
var constraint = skeletonData.findTransformConstraint(skinMap.transform[ii]);
|
|
if (constraint == null)
|
|
throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
|
|
skin.constraints.push(constraint);
|
|
}
|
|
}
|
|
if (skinMap.path) {
|
|
for (var ii = 0; ii < skinMap.path.length; ii++) {
|
|
var constraint = skeletonData.findPathConstraint(skinMap.path[ii]);
|
|
if (constraint == null)
|
|
throw new Error("Skin path constraint not found: " + skinMap.path[i]);
|
|
skin.constraints.push(constraint);
|
|
}
|
|
}
|
|
for (var slotName in skinMap.attachments) {
|
|
var slot = skeletonData.findSlot(slotName);
|
|
if (slot == null)
|
|
throw new Error("Slot not found: " + slotName);
|
|
var slotMap = skinMap.attachments[slotName];
|
|
for (var entryName in slotMap) {
|
|
var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
|
|
if (attachment != null)
|
|
skin.setAttachment(slot.index, entryName, attachment);
|
|
}
|
|
}
|
|
skeletonData.skins.push(skin);
|
|
if (skin.name == "default")
|
|
skeletonData.defaultSkin = skin;
|
|
}
|
|
}
|
|
for (var i = 0, n = this.linkedMeshes.length; i < n; i++) {
|
|
var linkedMesh = this.linkedMeshes[i];
|
|
var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
|
|
if (skin == null)
|
|
throw new Error("Skin not found: " + linkedMesh.skin);
|
|
var parent_6 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
|
|
if (parent_6 == null)
|
|
throw new Error("Parent mesh not found: " + linkedMesh.parent);
|
|
linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_6 : linkedMesh.mesh;
|
|
linkedMesh.mesh.setParentMesh(parent_6);
|
|
linkedMesh.mesh.updateUVs();
|
|
}
|
|
this.linkedMeshes.length = 0;
|
|
if (root.events) {
|
|
for (var eventName in root.events) {
|
|
var eventMap = root.events[eventName];
|
|
var data = new spine.EventData(eventName);
|
|
data.intValue = this.getValue(eventMap, "int", 0);
|
|
data.floatValue = this.getValue(eventMap, "float", 0);
|
|
data.stringValue = this.getValue(eventMap, "string", "");
|
|
data.audioPath = this.getValue(eventMap, "audio", null);
|
|
if (data.audioPath != null) {
|
|
data.volume = this.getValue(eventMap, "volume", 1);
|
|
data.balance = this.getValue(eventMap, "balance", 0);
|
|
}
|
|
skeletonData.events.push(data);
|
|
}
|
|
}
|
|
if (root.animations) {
|
|
for (var animationName in root.animations) {
|
|
var animationMap = root.animations[animationName];
|
|
this.readAnimation(animationMap, animationName, skeletonData);
|
|
}
|
|
}
|
|
return skeletonData;
|
|
};
|
|
SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
|
|
var scale = this.scale;
|
|
name = this.getValue(map, "name", name);
|
|
var type = this.getValue(map, "type", "region");
|
|
switch (type) {
|
|
case "region": {
|
|
var path = this.getValue(map, "path", name);
|
|
var region = this.attachmentLoader.newRegionAttachment(skin, name, path);
|
|
if (region == null)
|
|
return null;
|
|
region.path = path;
|
|
region.x = this.getValue(map, "x", 0) * scale;
|
|
region.y = this.getValue(map, "y", 0) * scale;
|
|
region.scaleX = this.getValue(map, "scaleX", 1);
|
|
region.scaleY = this.getValue(map, "scaleY", 1);
|
|
region.rotation = this.getValue(map, "rotation", 0);
|
|
region.width = map.width * scale;
|
|
region.height = map.height * scale;
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
region.color.setFromString(color);
|
|
region.updateOffset();
|
|
return region;
|
|
}
|
|
case "boundingbox": {
|
|
var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
|
|
if (box == null)
|
|
return null;
|
|
this.readVertices(map, box, map.vertexCount << 1);
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
box.color.setFromString(color);
|
|
return box;
|
|
}
|
|
case "mesh":
|
|
case "linkedmesh": {
|
|
var path = this.getValue(map, "path", name);
|
|
var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
|
|
if (mesh == null)
|
|
return null;
|
|
mesh.path = path;
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
mesh.color.setFromString(color);
|
|
mesh.width = this.getValue(map, "width", 0) * scale;
|
|
mesh.height = this.getValue(map, "height", 0) * scale;
|
|
var parent_7 = this.getValue(map, "parent", null);
|
|
if (parent_7 != null) {
|
|
this.linkedMeshes.push(new LinkedMesh(mesh, this.getValue(map, "skin", null), slotIndex, parent_7, this.getValue(map, "deform", true)));
|
|
return mesh;
|
|
}
|
|
var uvs = map.uvs;
|
|
this.readVertices(map, mesh, uvs.length);
|
|
mesh.triangles = map.triangles;
|
|
mesh.regionUVs = uvs;
|
|
mesh.updateUVs();
|
|
mesh.edges = this.getValue(map, "edges", null);
|
|
mesh.hullLength = this.getValue(map, "hull", 0) * 2;
|
|
return mesh;
|
|
}
|
|
case "path": {
|
|
var path = this.attachmentLoader.newPathAttachment(skin, name);
|
|
if (path == null)
|
|
return null;
|
|
path.closed = this.getValue(map, "closed", false);
|
|
path.constantSpeed = this.getValue(map, "constantSpeed", true);
|
|
var vertexCount = map.vertexCount;
|
|
this.readVertices(map, path, vertexCount << 1);
|
|
var lengths = spine.Utils.newArray(vertexCount / 3, 0);
|
|
for (var i = 0; i < map.lengths.length; i++)
|
|
lengths[i] = map.lengths[i] * scale;
|
|
path.lengths = lengths;
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
path.color.setFromString(color);
|
|
return path;
|
|
}
|
|
case "point": {
|
|
var point = this.attachmentLoader.newPointAttachment(skin, name);
|
|
if (point == null)
|
|
return null;
|
|
point.x = this.getValue(map, "x", 0) * scale;
|
|
point.y = this.getValue(map, "y", 0) * scale;
|
|
point.rotation = this.getValue(map, "rotation", 0);
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
point.color.setFromString(color);
|
|
return point;
|
|
}
|
|
case "clipping": {
|
|
var clip = this.attachmentLoader.newClippingAttachment(skin, name);
|
|
if (clip == null)
|
|
return null;
|
|
var end = this.getValue(map, "end", null);
|
|
if (end != null) {
|
|
var slot = skeletonData.findSlot(end);
|
|
if (slot == null)
|
|
throw new Error("Clipping end slot not found: " + end);
|
|
clip.endSlot = slot;
|
|
}
|
|
var vertexCount = map.vertexCount;
|
|
this.readVertices(map, clip, vertexCount << 1);
|
|
var color = this.getValue(map, "color", null);
|
|
if (color != null)
|
|
clip.color.setFromString(color);
|
|
return clip;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) {
|
|
var scale = this.scale;
|
|
attachment.worldVerticesLength = verticesLength;
|
|
var vertices = map.vertices;
|
|
if (verticesLength == vertices.length) {
|
|
var scaledVertices = spine.Utils.toFloatArray(vertices);
|
|
if (scale != 1) {
|
|
for (var i = 0, n = vertices.length; i < n; i++)
|
|
scaledVertices[i] *= scale;
|
|
}
|
|
attachment.vertices = scaledVertices;
|
|
return;
|
|
}
|
|
var weights = new Array();
|
|
var bones = new Array();
|
|
for (var i = 0, n = vertices.length; i < n;) {
|
|
var boneCount = vertices[i++];
|
|
bones.push(boneCount);
|
|
for (var nn = i + boneCount * 4; i < nn; i += 4) {
|
|
bones.push(vertices[i]);
|
|
weights.push(vertices[i + 1] * scale);
|
|
weights.push(vertices[i + 2] * scale);
|
|
weights.push(vertices[i + 3]);
|
|
}
|
|
}
|
|
attachment.bones = bones;
|
|
attachment.vertices = spine.Utils.toFloatArray(weights);
|
|
};
|
|
SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) {
|
|
var scale = this.scale;
|
|
var timelines = new Array();
|
|
var duration = 0;
|
|
if (map.slots) {
|
|
for (var slotName in map.slots) {
|
|
var slotMap = map.slots[slotName];
|
|
var slotIndex = skeletonData.findSlotIndex(slotName);
|
|
if (slotIndex == -1)
|
|
throw new Error("Slot not found: " + slotName);
|
|
for (var timelineName in slotMap) {
|
|
var timelineMap = slotMap[timelineName];
|
|
if (timelineName == "attachment") {
|
|
var timeline = new spine.AttachmentTimeline(timelineMap.length);
|
|
timeline.slotIndex = slotIndex;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
|
|
}
|
|
else if (timelineName == "color") {
|
|
var timeline = new spine.ColorTimeline(timelineMap.length);
|
|
timeline.slotIndex = slotIndex;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
var color = new spine.Color();
|
|
color.setFromString(valueMap.color);
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.ColorTimeline.ENTRIES]);
|
|
}
|
|
else if (timelineName == "twoColor") {
|
|
var timeline = new spine.TwoColorTimeline(timelineMap.length);
|
|
timeline.slotIndex = slotIndex;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
var light = new spine.Color();
|
|
var dark = new spine.Color();
|
|
light.setFromString(valueMap.light);
|
|
dark.setFromString(valueMap.dark);
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TwoColorTimeline.ENTRIES]);
|
|
}
|
|
else
|
|
throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
|
|
}
|
|
}
|
|
}
|
|
if (map.bones) {
|
|
for (var boneName in map.bones) {
|
|
var boneMap = map.bones[boneName];
|
|
var boneIndex = skeletonData.findBoneIndex(boneName);
|
|
if (boneIndex == -1)
|
|
throw new Error("Bone not found: " + boneName);
|
|
for (var timelineName in boneMap) {
|
|
var timelineMap = boneMap[timelineName];
|
|
if (timelineName === "rotate") {
|
|
var timeline = new spine.RotateTimeline(timelineMap.length);
|
|
timeline.boneIndex = boneIndex;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.RotateTimeline.ENTRIES]);
|
|
}
|
|
else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
|
|
var timeline = null;
|
|
var timelineScale = 1, defaultValue = 0;
|
|
if (timelineName === "scale") {
|
|
timeline = new spine.ScaleTimeline(timelineMap.length);
|
|
defaultValue = 1;
|
|
}
|
|
else if (timelineName === "shear")
|
|
timeline = new spine.ShearTimeline(timelineMap.length);
|
|
else {
|
|
timeline = new spine.TranslateTimeline(timelineMap.length);
|
|
timelineScale = scale;
|
|
}
|
|
timeline.boneIndex = boneIndex;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TranslateTimeline.ENTRIES]);
|
|
}
|
|
else
|
|
throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
|
|
}
|
|
}
|
|
}
|
|
if (map.ik) {
|
|
for (var constraintName in map.ik) {
|
|
var constraintMap = map.ik[constraintName];
|
|
var constraint = skeletonData.findIkConstraint(constraintName);
|
|
var timeline = new spine.IkConstraintTimeline(constraintMap.length);
|
|
timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint);
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < constraintMap.length; i++) {
|
|
var valueMap = constraintMap[i];
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "softness", 0) * scale, this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.IkConstraintTimeline.ENTRIES]);
|
|
}
|
|
}
|
|
if (map.transform) {
|
|
for (var constraintName in map.transform) {
|
|
var constraintMap = map.transform[constraintName];
|
|
var constraint = skeletonData.findTransformConstraint(constraintName);
|
|
var timeline = new spine.TransformConstraintTimeline(constraintMap.length);
|
|
timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint);
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < constraintMap.length; i++) {
|
|
var valueMap = constraintMap[i];
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
|
|
}
|
|
}
|
|
if (map.path) {
|
|
for (var constraintName in map.path) {
|
|
var constraintMap = map.path[constraintName];
|
|
var index = skeletonData.findPathConstraintIndex(constraintName);
|
|
if (index == -1)
|
|
throw new Error("Path constraint not found: " + constraintName);
|
|
var data = skeletonData.pathConstraints[index];
|
|
for (var timelineName in constraintMap) {
|
|
var timelineMap = constraintMap[timelineName];
|
|
if (timelineName === "position" || timelineName === "spacing") {
|
|
var timeline = null;
|
|
var timelineScale = 1;
|
|
if (timelineName === "spacing") {
|
|
timeline = new spine.PathConstraintSpacingTimeline(timelineMap.length);
|
|
if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
|
|
timelineScale = scale;
|
|
}
|
|
else {
|
|
timeline = new spine.PathConstraintPositionTimeline(timelineMap.length);
|
|
if (data.positionMode == spine.PositionMode.Fixed)
|
|
timelineScale = scale;
|
|
}
|
|
timeline.pathConstraintIndex = index;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintPositionTimeline.ENTRIES]);
|
|
}
|
|
else if (timelineName === "mix") {
|
|
var timeline = new spine.PathConstraintMixTimeline(timelineMap.length);
|
|
timeline.pathConstraintIndex = index;
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < timelineMap.length; i++) {
|
|
var valueMap = timelineMap[i];
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintMixTimeline.ENTRIES]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (map.deform) {
|
|
for (var deformName in map.deform) {
|
|
var deformMap = map.deform[deformName];
|
|
var skin = skeletonData.findSkin(deformName);
|
|
if (skin == null)
|
|
throw new Error("Skin not found: " + deformName);
|
|
for (var slotName in deformMap) {
|
|
var slotMap = deformMap[slotName];
|
|
var slotIndex = skeletonData.findSlotIndex(slotName);
|
|
if (slotIndex == -1)
|
|
throw new Error("Slot not found: " + slotMap.name);
|
|
for (var timelineName in slotMap) {
|
|
var timelineMap = slotMap[timelineName];
|
|
var attachment = skin.getAttachment(slotIndex, timelineName);
|
|
if (attachment == null)
|
|
throw new Error("Deform attachment not found: " + timelineMap.name);
|
|
var weighted = attachment.bones != null;
|
|
var vertices = attachment.vertices;
|
|
var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
|
|
var timeline = new spine.DeformTimeline(timelineMap.length);
|
|
timeline.slotIndex = slotIndex;
|
|
timeline.attachment = attachment;
|
|
var frameIndex = 0;
|
|
for (var j = 0; j < timelineMap.length; j++) {
|
|
var valueMap = timelineMap[j];
|
|
var deform = void 0;
|
|
var verticesValue = this.getValue(valueMap, "vertices", null);
|
|
if (verticesValue == null)
|
|
deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices;
|
|
else {
|
|
deform = spine.Utils.newFloatArray(deformLength);
|
|
var start = this.getValue(valueMap, "offset", 0);
|
|
spine.Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length);
|
|
if (scale != 1) {
|
|
for (var i = start, n = i + verticesValue.length; i < n; i++)
|
|
deform[i] *= scale;
|
|
}
|
|
if (!weighted) {
|
|
for (var i = 0; i < deformLength; i++)
|
|
deform[i] += vertices[i];
|
|
}
|
|
}
|
|
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
|
|
this.readCurve(valueMap, timeline, frameIndex);
|
|
frameIndex++;
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var drawOrderNode = map.drawOrder;
|
|
if (drawOrderNode == null)
|
|
drawOrderNode = map.draworder;
|
|
if (drawOrderNode != null) {
|
|
var timeline = new spine.DrawOrderTimeline(drawOrderNode.length);
|
|
var slotCount = skeletonData.slots.length;
|
|
var frameIndex = 0;
|
|
for (var j = 0; j < drawOrderNode.length; j++) {
|
|
var drawOrderMap = drawOrderNode[j];
|
|
var drawOrder = null;
|
|
var offsets = this.getValue(drawOrderMap, "offsets", null);
|
|
if (offsets != null) {
|
|
drawOrder = spine.Utils.newArray(slotCount, -1);
|
|
var unchanged = spine.Utils.newArray(slotCount - offsets.length, 0);
|
|
var originalIndex = 0, unchangedIndex = 0;
|
|
for (var i = 0; i < offsets.length; i++) {
|
|
var offsetMap = offsets[i];
|
|
var slotIndex = skeletonData.findSlotIndex(offsetMap.slot);
|
|
if (slotIndex == -1)
|
|
throw new Error("Slot not found: " + offsetMap.slot);
|
|
while (originalIndex != slotIndex)
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
drawOrder[originalIndex + offsetMap.offset] = originalIndex++;
|
|
}
|
|
while (originalIndex < slotCount)
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
for (var i = slotCount - 1; i >= 0; i--)
|
|
if (drawOrder[i] == -1)
|
|
drawOrder[i] = unchanged[--unchangedIndex];
|
|
}
|
|
timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
|
|
}
|
|
if (map.events) {
|
|
var timeline = new spine.EventTimeline(map.events.length);
|
|
var frameIndex = 0;
|
|
for (var i = 0; i < map.events.length; i++) {
|
|
var eventMap = map.events[i];
|
|
var eventData = skeletonData.findEvent(eventMap.name);
|
|
if (eventData == null)
|
|
throw new Error("Event not found: " + eventMap.name);
|
|
var event_6 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
|
|
event_6.intValue = this.getValue(eventMap, "int", eventData.intValue);
|
|
event_6.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
|
|
event_6.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
|
|
if (event_6.data.audioPath != null) {
|
|
event_6.volume = this.getValue(eventMap, "volume", 1);
|
|
event_6.balance = this.getValue(eventMap, "balance", 0);
|
|
}
|
|
timeline.setFrame(frameIndex++, event_6);
|
|
}
|
|
timelines.push(timeline);
|
|
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
|
|
}
|
|
if (isNaN(duration)) {
|
|
throw new Error("Error while parsing animation, duration is NaN");
|
|
}
|
|
skeletonData.animations.push(new spine.Animation(name, timelines, duration));
|
|
};
|
|
SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
|
|
if (!map.hasOwnProperty("curve"))
|
|
return;
|
|
if (map.curve == "stepped")
|
|
timeline.setStepped(frameIndex);
|
|
else {
|
|
var curve = map.curve;
|
|
timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
|
|
}
|
|
};
|
|
SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
|
|
return map[prop] !== undefined ? map[prop] : defaultValue;
|
|
};
|
|
SkeletonJson.blendModeFromString = function (str) {
|
|
str = str.toLowerCase();
|
|
if (str == "normal")
|
|
return spine.BlendMode.Normal;
|
|
if (str == "additive")
|
|
return spine.BlendMode.Additive;
|
|
if (str == "multiply")
|
|
return spine.BlendMode.Multiply;
|
|
if (str == "screen")
|
|
return spine.BlendMode.Screen;
|
|
throw new Error("Unknown blend mode: " + str);
|
|
};
|
|
SkeletonJson.positionModeFromString = function (str) {
|
|
str = str.toLowerCase();
|
|
if (str == "fixed")
|
|
return spine.PositionMode.Fixed;
|
|
if (str == "percent")
|
|
return spine.PositionMode.Percent;
|
|
throw new Error("Unknown position mode: " + str);
|
|
};
|
|
SkeletonJson.spacingModeFromString = function (str) {
|
|
str = str.toLowerCase();
|
|
if (str == "length")
|
|
return spine.SpacingMode.Length;
|
|
if (str == "fixed")
|
|
return spine.SpacingMode.Fixed;
|
|
if (str == "percent")
|
|
return spine.SpacingMode.Percent;
|
|
throw new Error("Unknown position mode: " + str);
|
|
};
|
|
SkeletonJson.rotateModeFromString = function (str) {
|
|
str = str.toLowerCase();
|
|
if (str == "tangent")
|
|
return spine.RotateMode.Tangent;
|
|
if (str == "chain")
|
|
return spine.RotateMode.Chain;
|
|
if (str == "chainscale")
|
|
return spine.RotateMode.ChainScale;
|
|
throw new Error("Unknown rotate mode: " + str);
|
|
};
|
|
SkeletonJson.transformModeFromString = function (str) {
|
|
str = str.toLowerCase();
|
|
if (str == "normal")
|
|
return spine.TransformMode.Normal;
|
|
if (str == "onlytranslation")
|
|
return spine.TransformMode.OnlyTranslation;
|
|
if (str == "norotationorreflection")
|
|
return spine.TransformMode.NoRotationOrReflection;
|
|
if (str == "noscale")
|
|
return spine.TransformMode.NoScale;
|
|
if (str == "noscaleorreflection")
|
|
return spine.TransformMode.NoScaleOrReflection;
|
|
throw new Error("Unknown transform mode: " + str);
|
|
};
|
|
return SkeletonJson;
|
|
}());
|
|
spine.SkeletonJson = SkeletonJson;
|
|
var LinkedMesh = (function () {
|
|
function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) {
|
|
this.mesh = mesh;
|
|
this.skin = skin;
|
|
this.slotIndex = slotIndex;
|
|
this.parent = parent;
|
|
this.inheritDeform = inheritDeform;
|
|
}
|
|
return LinkedMesh;
|
|
}());
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SkinEntry = (function () {
|
|
function SkinEntry(slotIndex, name, attachment) {
|
|
this.slotIndex = slotIndex;
|
|
this.name = name;
|
|
this.attachment = attachment;
|
|
}
|
|
return SkinEntry;
|
|
}());
|
|
spine.SkinEntry = SkinEntry;
|
|
var Skin = (function () {
|
|
function Skin(name) {
|
|
this.attachments = new Array();
|
|
this.bones = Array();
|
|
this.constraints = new Array();
|
|
if (name == null)
|
|
throw new Error("name cannot be null.");
|
|
this.name = name;
|
|
}
|
|
Skin.prototype.setAttachment = function (slotIndex, name, attachment) {
|
|
if (attachment == null)
|
|
throw new Error("attachment cannot be null.");
|
|
var attachments = this.attachments;
|
|
if (slotIndex >= attachments.length)
|
|
attachments.length = slotIndex + 1;
|
|
if (!attachments[slotIndex])
|
|
attachments[slotIndex] = {};
|
|
attachments[slotIndex][name] = attachment;
|
|
};
|
|
Skin.prototype.addSkin = function (skin) {
|
|
for (var i = 0; i < skin.bones.length; i++) {
|
|
var bone = skin.bones[i];
|
|
var contained = false;
|
|
for (var j = 0; j < this.bones.length; j++) {
|
|
if (this.bones[j] == bone) {
|
|
contained = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!contained)
|
|
this.bones.push(bone);
|
|
}
|
|
for (var i = 0; i < skin.constraints.length; i++) {
|
|
var constraint = skin.constraints[i];
|
|
var contained = false;
|
|
for (var j = 0; j < this.constraints.length; j++) {
|
|
if (this.constraints[j] == constraint) {
|
|
contained = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!contained)
|
|
this.constraints.push(constraint);
|
|
}
|
|
var attachments = skin.getAttachments();
|
|
for (var i = 0; i < attachments.length; i++) {
|
|
var attachment = attachments[i];
|
|
this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);
|
|
}
|
|
};
|
|
Skin.prototype.copySkin = function (skin) {
|
|
for (var i = 0; i < skin.bones.length; i++) {
|
|
var bone = skin.bones[i];
|
|
var contained = false;
|
|
for (var j = 0; j < this.bones.length; j++) {
|
|
if (this.bones[j] == bone) {
|
|
contained = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!contained)
|
|
this.bones.push(bone);
|
|
}
|
|
for (var i = 0; i < skin.constraints.length; i++) {
|
|
var constraint = skin.constraints[i];
|
|
var contained = false;
|
|
for (var j = 0; j < this.constraints.length; j++) {
|
|
if (this.constraints[j] == constraint) {
|
|
contained = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!contained)
|
|
this.constraints.push(constraint);
|
|
}
|
|
var attachments = skin.getAttachments();
|
|
for (var i = 0; i < attachments.length; i++) {
|
|
var attachment = attachments[i];
|
|
if (attachment.attachment == null)
|
|
continue;
|
|
if (attachment.attachment instanceof spine.MeshAttachment) {
|
|
attachment.attachment = attachment.attachment.newLinkedMesh();
|
|
this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);
|
|
}
|
|
else {
|
|
attachment.attachment = attachment.attachment.copy();
|
|
this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);
|
|
}
|
|
}
|
|
};
|
|
Skin.prototype.getAttachment = function (slotIndex, name) {
|
|
var dictionary = this.attachments[slotIndex];
|
|
return dictionary ? dictionary[name] : null;
|
|
};
|
|
Skin.prototype.removeAttachment = function (slotIndex, name) {
|
|
var dictionary = this.attachments[slotIndex];
|
|
if (dictionary)
|
|
dictionary[name] = null;
|
|
};
|
|
Skin.prototype.getAttachments = function () {
|
|
var entries = new Array();
|
|
for (var i = 0; i < this.attachments.length; i++) {
|
|
var slotAttachments = this.attachments[i];
|
|
if (slotAttachments) {
|
|
for (var name_4 in slotAttachments) {
|
|
var attachment = slotAttachments[name_4];
|
|
if (attachment)
|
|
entries.push(new SkinEntry(i, name_4, attachment));
|
|
}
|
|
}
|
|
}
|
|
return entries;
|
|
};
|
|
Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) {
|
|
var slotAttachments = this.attachments[slotIndex];
|
|
if (slotAttachments) {
|
|
for (var name_5 in slotAttachments) {
|
|
var attachment = slotAttachments[name_5];
|
|
if (attachment)
|
|
attachments.push(new SkinEntry(slotIndex, name_5, attachment));
|
|
}
|
|
}
|
|
};
|
|
Skin.prototype.clear = function () {
|
|
this.attachments.length = 0;
|
|
this.bones.length = 0;
|
|
this.constraints.length = 0;
|
|
};
|
|
Skin.prototype.attachAll = function (skeleton, oldSkin) {
|
|
var slotIndex = 0;
|
|
for (var i = 0; i < skeleton.slots.length; i++) {
|
|
var slot = skeleton.slots[i];
|
|
var slotAttachment = slot.getAttachment();
|
|
if (slotAttachment && slotIndex < oldSkin.attachments.length) {
|
|
var dictionary = oldSkin.attachments[slotIndex];
|
|
for (var key in dictionary) {
|
|
var skinAttachment = dictionary[key];
|
|
if (slotAttachment == skinAttachment) {
|
|
var attachment = this.getAttachment(slotIndex, key);
|
|
if (attachment != null)
|
|
slot.setAttachment(attachment);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
slotIndex++;
|
|
}
|
|
};
|
|
return Skin;
|
|
}());
|
|
spine.Skin = Skin;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Slot = (function () {
|
|
function Slot(data, bone) {
|
|
this.deform = new Array();
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
if (bone == null)
|
|
throw new Error("bone cannot be null.");
|
|
this.data = data;
|
|
this.bone = bone;
|
|
this.color = new spine.Color();
|
|
this.darkColor = data.darkColor == null ? null : new spine.Color();
|
|
this.setToSetupPose();
|
|
}
|
|
Slot.prototype.getSkeleton = function () {
|
|
return this.bone.skeleton;
|
|
};
|
|
Slot.prototype.getAttachment = function () {
|
|
return this.attachment;
|
|
};
|
|
Slot.prototype.setAttachment = function (attachment) {
|
|
if (this.attachment == attachment)
|
|
return;
|
|
this.attachment = attachment;
|
|
this.attachmentTime = this.bone.skeleton.time;
|
|
this.deform.length = 0;
|
|
};
|
|
Slot.prototype.setAttachmentTime = function (time) {
|
|
this.attachmentTime = this.bone.skeleton.time - time;
|
|
};
|
|
Slot.prototype.getAttachmentTime = function () {
|
|
return this.bone.skeleton.time - this.attachmentTime;
|
|
};
|
|
Slot.prototype.setToSetupPose = function () {
|
|
this.color.setFromColor(this.data.color);
|
|
if (this.darkColor != null)
|
|
this.darkColor.setFromColor(this.data.darkColor);
|
|
if (this.data.attachmentName == null)
|
|
this.attachment = null;
|
|
else {
|
|
this.attachment = null;
|
|
this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName));
|
|
}
|
|
};
|
|
return Slot;
|
|
}());
|
|
spine.Slot = Slot;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SlotData = (function () {
|
|
function SlotData(index, name, boneData) {
|
|
this.color = new spine.Color(1, 1, 1, 1);
|
|
if (index < 0)
|
|
throw new Error("index must be >= 0.");
|
|
if (name == null)
|
|
throw new Error("name cannot be null.");
|
|
if (boneData == null)
|
|
throw new Error("boneData cannot be null.");
|
|
this.index = index;
|
|
this.name = name;
|
|
this.boneData = boneData;
|
|
}
|
|
return SlotData;
|
|
}());
|
|
spine.SlotData = SlotData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Texture = (function () {
|
|
function Texture(image) {
|
|
this._image = image;
|
|
}
|
|
Texture.prototype.getImage = function () {
|
|
return this._image;
|
|
};
|
|
Texture.filterFromString = function (text) {
|
|
switch (text.toLowerCase()) {
|
|
case "nearest": return TextureFilter.Nearest;
|
|
case "linear": return TextureFilter.Linear;
|
|
case "mipmap": return TextureFilter.MipMap;
|
|
case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest;
|
|
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
|
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
|
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
|
default: throw new Error("Unknown texture filter " + text);
|
|
}
|
|
};
|
|
Texture.wrapFromString = function (text) {
|
|
switch (text.toLowerCase()) {
|
|
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
|
case "clamptoedge": return TextureWrap.ClampToEdge;
|
|
case "repeat": return TextureWrap.Repeat;
|
|
default: throw new Error("Unknown texture wrap " + text);
|
|
}
|
|
};
|
|
return Texture;
|
|
}());
|
|
spine.Texture = Texture;
|
|
var TextureFilter;
|
|
(function (TextureFilter) {
|
|
TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest";
|
|
TextureFilter[TextureFilter["Linear"] = 9729] = "Linear";
|
|
TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap";
|
|
TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest";
|
|
TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest";
|
|
TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear";
|
|
TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear";
|
|
})(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {}));
|
|
var TextureWrap;
|
|
(function (TextureWrap) {
|
|
TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat";
|
|
TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge";
|
|
TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat";
|
|
})(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {}));
|
|
var TextureRegion = (function () {
|
|
function TextureRegion() {
|
|
this.u = 0;
|
|
this.v = 0;
|
|
this.u2 = 0;
|
|
this.v2 = 0;
|
|
this.width = 0;
|
|
this.height = 0;
|
|
this.rotate = false;
|
|
this.offsetX = 0;
|
|
this.offsetY = 0;
|
|
this.originalWidth = 0;
|
|
this.originalHeight = 0;
|
|
}
|
|
return TextureRegion;
|
|
}());
|
|
spine.TextureRegion = TextureRegion;
|
|
var FakeTexture = (function (_super) {
|
|
__extends(FakeTexture, _super);
|
|
function FakeTexture() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
FakeTexture.prototype.setFilters = function (minFilter, magFilter) { };
|
|
FakeTexture.prototype.setWraps = function (uWrap, vWrap) { };
|
|
FakeTexture.prototype.dispose = function () { };
|
|
return FakeTexture;
|
|
}(Texture));
|
|
spine.FakeTexture = FakeTexture;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var TextureAtlas = (function () {
|
|
function TextureAtlas(atlasText, textureLoader) {
|
|
this.pages = new Array();
|
|
this.regions = new Array();
|
|
this.load(atlasText, textureLoader);
|
|
}
|
|
TextureAtlas.prototype.load = function (atlasText, textureLoader) {
|
|
if (textureLoader == null)
|
|
throw new Error("textureLoader cannot be null.");
|
|
var reader = new TextureAtlasReader(atlasText);
|
|
var tuple = new Array(4);
|
|
var page = null;
|
|
while (true) {
|
|
var line = reader.readLine();
|
|
if (line == null)
|
|
break;
|
|
line = line.trim();
|
|
if (line.length == 0)
|
|
page = null;
|
|
else if (!page) {
|
|
page = new TextureAtlasPage();
|
|
page.name = line;
|
|
if (reader.readTuple(tuple) == 2) {
|
|
page.width = parseInt(tuple[0]);
|
|
page.height = parseInt(tuple[1]);
|
|
reader.readTuple(tuple);
|
|
}
|
|
reader.readTuple(tuple);
|
|
page.minFilter = spine.Texture.filterFromString(tuple[0]);
|
|
page.magFilter = spine.Texture.filterFromString(tuple[1]);
|
|
var direction = reader.readValue();
|
|
page.uWrap = spine.TextureWrap.ClampToEdge;
|
|
page.vWrap = spine.TextureWrap.ClampToEdge;
|
|
if (direction == "x")
|
|
page.uWrap = spine.TextureWrap.Repeat;
|
|
else if (direction == "y")
|
|
page.vWrap = spine.TextureWrap.Repeat;
|
|
else if (direction == "xy")
|
|
page.uWrap = page.vWrap = spine.TextureWrap.Repeat;
|
|
page.texture = textureLoader(line);
|
|
page.texture.setFilters(page.minFilter, page.magFilter);
|
|
page.texture.setWraps(page.uWrap, page.vWrap);
|
|
page.width = page.texture.getImage().width;
|
|
page.height = page.texture.getImage().height;
|
|
this.pages.push(page);
|
|
}
|
|
else {
|
|
var region = new TextureAtlasRegion();
|
|
region.name = line;
|
|
region.page = page;
|
|
var rotateValue = reader.readValue();
|
|
if (rotateValue.toLocaleLowerCase() == "true") {
|
|
region.degrees = 90;
|
|
}
|
|
else if (rotateValue.toLocaleLowerCase() == "false") {
|
|
region.degrees = 0;
|
|
}
|
|
else {
|
|
region.degrees = parseFloat(rotateValue);
|
|
}
|
|
region.rotate = region.degrees == 90;
|
|
reader.readTuple(tuple);
|
|
var x = parseInt(tuple[0]);
|
|
var y = parseInt(tuple[1]);
|
|
reader.readTuple(tuple);
|
|
var width = parseInt(tuple[0]);
|
|
var height = parseInt(tuple[1]);
|
|
region.u = x / page.width;
|
|
region.v = y / page.height;
|
|
if (region.rotate) {
|
|
region.u2 = (x + height) / page.width;
|
|
region.v2 = (y + width) / page.height;
|
|
}
|
|
else {
|
|
region.u2 = (x + width) / page.width;
|
|
region.v2 = (y + height) / page.height;
|
|
}
|
|
region.x = x;
|
|
region.y = y;
|
|
region.width = Math.abs(width);
|
|
region.height = Math.abs(height);
|
|
if (reader.readTuple(tuple) == 4) {
|
|
if (reader.readTuple(tuple) == 4) {
|
|
reader.readTuple(tuple);
|
|
}
|
|
}
|
|
region.originalWidth = parseInt(tuple[0]);
|
|
region.originalHeight = parseInt(tuple[1]);
|
|
reader.readTuple(tuple);
|
|
region.offsetX = parseInt(tuple[0]);
|
|
region.offsetY = parseInt(tuple[1]);
|
|
region.index = parseInt(reader.readValue());
|
|
region.texture = page.texture;
|
|
this.regions.push(region);
|
|
}
|
|
}
|
|
};
|
|
TextureAtlas.prototype.findRegion = function (name) {
|
|
for (var i = 0; i < this.regions.length; i++) {
|
|
if (this.regions[i].name == name) {
|
|
return this.regions[i];
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
TextureAtlas.prototype.dispose = function () {
|
|
for (var i = 0; i < this.pages.length; i++) {
|
|
this.pages[i].texture.dispose();
|
|
}
|
|
};
|
|
return TextureAtlas;
|
|
}());
|
|
spine.TextureAtlas = TextureAtlas;
|
|
var TextureAtlasReader = (function () {
|
|
function TextureAtlasReader(text) {
|
|
this.index = 0;
|
|
this.lines = text.split(/\r\n|\r|\n/);
|
|
}
|
|
TextureAtlasReader.prototype.readLine = function () {
|
|
if (this.index >= this.lines.length)
|
|
return null;
|
|
return this.lines[this.index++];
|
|
};
|
|
TextureAtlasReader.prototype.readValue = function () {
|
|
var line = this.readLine();
|
|
var colon = line.indexOf(":");
|
|
if (colon == -1)
|
|
throw new Error("Invalid line: " + line);
|
|
return line.substring(colon + 1).trim();
|
|
};
|
|
TextureAtlasReader.prototype.readTuple = function (tuple) {
|
|
var line = this.readLine();
|
|
var colon = line.indexOf(":");
|
|
if (colon == -1)
|
|
throw new Error("Invalid line: " + line);
|
|
var i = 0, lastMatch = colon + 1;
|
|
for (; i < 3; i++) {
|
|
var comma = line.indexOf(",", lastMatch);
|
|
if (comma == -1)
|
|
break;
|
|
tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
|
|
lastMatch = comma + 1;
|
|
}
|
|
tuple[i] = line.substring(lastMatch).trim();
|
|
return i + 1;
|
|
};
|
|
return TextureAtlasReader;
|
|
}());
|
|
var TextureAtlasPage = (function () {
|
|
function TextureAtlasPage() {
|
|
}
|
|
return TextureAtlasPage;
|
|
}());
|
|
spine.TextureAtlasPage = TextureAtlasPage;
|
|
var TextureAtlasRegion = (function (_super) {
|
|
__extends(TextureAtlasRegion, _super);
|
|
function TextureAtlasRegion() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return TextureAtlasRegion;
|
|
}(spine.TextureRegion));
|
|
spine.TextureAtlasRegion = TextureAtlasRegion;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var TransformConstraint = (function () {
|
|
function TransformConstraint(data, skeleton) {
|
|
this.rotateMix = 0;
|
|
this.translateMix = 0;
|
|
this.scaleMix = 0;
|
|
this.shearMix = 0;
|
|
this.temp = new spine.Vector2();
|
|
this.active = false;
|
|
if (data == null)
|
|
throw new Error("data cannot be null.");
|
|
if (skeleton == null)
|
|
throw new Error("skeleton cannot be null.");
|
|
this.data = data;
|
|
this.rotateMix = data.rotateMix;
|
|
this.translateMix = data.translateMix;
|
|
this.scaleMix = data.scaleMix;
|
|
this.shearMix = data.shearMix;
|
|
this.bones = new Array();
|
|
for (var i = 0; i < data.bones.length; i++)
|
|
this.bones.push(skeleton.findBone(data.bones[i].name));
|
|
this.target = skeleton.findBone(data.target.name);
|
|
}
|
|
TransformConstraint.prototype.isActive = function () {
|
|
return this.active;
|
|
};
|
|
TransformConstraint.prototype.apply = function () {
|
|
this.update();
|
|
};
|
|
TransformConstraint.prototype.update = function () {
|
|
if (this.data.local) {
|
|
if (this.data.relative)
|
|
this.applyRelativeLocal();
|
|
else
|
|
this.applyAbsoluteLocal();
|
|
}
|
|
else {
|
|
if (this.data.relative)
|
|
this.applyRelativeWorld();
|
|
else
|
|
this.applyAbsoluteWorld();
|
|
}
|
|
};
|
|
TransformConstraint.prototype.applyAbsoluteWorld = function () {
|
|
var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
|
|
var target = this.target;
|
|
var ta = target.a, tb = target.b, tc = target.c, td = target.d;
|
|
var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
|
|
var offsetRotation = this.data.offsetRotation * degRadReflect;
|
|
var offsetShearY = this.data.offsetShearY * degRadReflect;
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
var modified = false;
|
|
if (rotateMix != 0) {
|
|
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
|
var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation;
|
|
if (r > spine.MathUtils.PI)
|
|
r -= spine.MathUtils.PI2;
|
|
else if (r < -spine.MathUtils.PI)
|
|
r += spine.MathUtils.PI2;
|
|
r *= rotateMix;
|
|
var cos = Math.cos(r), sin = Math.sin(r);
|
|
bone.a = cos * a - sin * c;
|
|
bone.b = cos * b - sin * d;
|
|
bone.c = sin * a + cos * c;
|
|
bone.d = sin * b + cos * d;
|
|
modified = true;
|
|
}
|
|
if (translateMix != 0) {
|
|
var temp = this.temp;
|
|
target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
|
|
bone.worldX += (temp.x - bone.worldX) * translateMix;
|
|
bone.worldY += (temp.y - bone.worldY) * translateMix;
|
|
modified = true;
|
|
}
|
|
if (scaleMix > 0) {
|
|
var s = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
|
|
var ts = Math.sqrt(ta * ta + tc * tc);
|
|
if (s > 0.00001)
|
|
s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s;
|
|
bone.a *= s;
|
|
bone.c *= s;
|
|
s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
|
|
ts = Math.sqrt(tb * tb + td * td);
|
|
if (s > 0.00001)
|
|
s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s;
|
|
bone.b *= s;
|
|
bone.d *= s;
|
|
modified = true;
|
|
}
|
|
if (shearMix > 0) {
|
|
var b = bone.b, d = bone.d;
|
|
var by = Math.atan2(d, b);
|
|
var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));
|
|
if (r > spine.MathUtils.PI)
|
|
r -= spine.MathUtils.PI2;
|
|
else if (r < -spine.MathUtils.PI)
|
|
r += spine.MathUtils.PI2;
|
|
r = by + (r + offsetShearY) * shearMix;
|
|
var s = Math.sqrt(b * b + d * d);
|
|
bone.b = Math.cos(r) * s;
|
|
bone.d = Math.sin(r) * s;
|
|
modified = true;
|
|
}
|
|
if (modified)
|
|
bone.appliedValid = false;
|
|
}
|
|
};
|
|
TransformConstraint.prototype.applyRelativeWorld = function () {
|
|
var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
|
|
var target = this.target;
|
|
var ta = target.a, tb = target.b, tc = target.c, td = target.d;
|
|
var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
|
|
var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect;
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
var modified = false;
|
|
if (rotateMix != 0) {
|
|
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
|
var r = Math.atan2(tc, ta) + offsetRotation;
|
|
if (r > spine.MathUtils.PI)
|
|
r -= spine.MathUtils.PI2;
|
|
else if (r < -spine.MathUtils.PI)
|
|
r += spine.MathUtils.PI2;
|
|
r *= rotateMix;
|
|
var cos = Math.cos(r), sin = Math.sin(r);
|
|
bone.a = cos * a - sin * c;
|
|
bone.b = cos * b - sin * d;
|
|
bone.c = sin * a + cos * c;
|
|
bone.d = sin * b + cos * d;
|
|
modified = true;
|
|
}
|
|
if (translateMix != 0) {
|
|
var temp = this.temp;
|
|
target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
|
|
bone.worldX += temp.x * translateMix;
|
|
bone.worldY += temp.y * translateMix;
|
|
modified = true;
|
|
}
|
|
if (scaleMix > 0) {
|
|
var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1;
|
|
bone.a *= s;
|
|
bone.c *= s;
|
|
s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1;
|
|
bone.b *= s;
|
|
bone.d *= s;
|
|
modified = true;
|
|
}
|
|
if (shearMix > 0) {
|
|
var r = Math.atan2(td, tb) - Math.atan2(tc, ta);
|
|
if (r > spine.MathUtils.PI)
|
|
r -= spine.MathUtils.PI2;
|
|
else if (r < -spine.MathUtils.PI)
|
|
r += spine.MathUtils.PI2;
|
|
var b = bone.b, d = bone.d;
|
|
r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix;
|
|
var s = Math.sqrt(b * b + d * d);
|
|
bone.b = Math.cos(r) * s;
|
|
bone.d = Math.sin(r) * s;
|
|
modified = true;
|
|
}
|
|
if (modified)
|
|
bone.appliedValid = false;
|
|
}
|
|
};
|
|
TransformConstraint.prototype.applyAbsoluteLocal = function () {
|
|
var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
|
|
var target = this.target;
|
|
if (!target.appliedValid)
|
|
target.updateAppliedTransform();
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (!bone.appliedValid)
|
|
bone.updateAppliedTransform();
|
|
var rotation = bone.arotation;
|
|
if (rotateMix != 0) {
|
|
var r = target.arotation - rotation + this.data.offsetRotation;
|
|
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
|
|
rotation += r * rotateMix;
|
|
}
|
|
var x = bone.ax, y = bone.ay;
|
|
if (translateMix != 0) {
|
|
x += (target.ax - x + this.data.offsetX) * translateMix;
|
|
y += (target.ay - y + this.data.offsetY) * translateMix;
|
|
}
|
|
var scaleX = bone.ascaleX, scaleY = bone.ascaleY;
|
|
if (scaleMix != 0) {
|
|
if (scaleX > 0.00001)
|
|
scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX;
|
|
if (scaleY > 0.00001)
|
|
scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY;
|
|
}
|
|
var shearY = bone.ashearY;
|
|
if (shearMix != 0) {
|
|
var r = target.ashearY - shearY + this.data.offsetShearY;
|
|
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
|
|
bone.shearY += r * shearMix;
|
|
}
|
|
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
|
}
|
|
};
|
|
TransformConstraint.prototype.applyRelativeLocal = function () {
|
|
var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
|
|
var target = this.target;
|
|
if (!target.appliedValid)
|
|
target.updateAppliedTransform();
|
|
var bones = this.bones;
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (!bone.appliedValid)
|
|
bone.updateAppliedTransform();
|
|
var rotation = bone.arotation;
|
|
if (rotateMix != 0)
|
|
rotation += (target.arotation + this.data.offsetRotation) * rotateMix;
|
|
var x = bone.ax, y = bone.ay;
|
|
if (translateMix != 0) {
|
|
x += (target.ax + this.data.offsetX) * translateMix;
|
|
y += (target.ay + this.data.offsetY) * translateMix;
|
|
}
|
|
var scaleX = bone.ascaleX, scaleY = bone.ascaleY;
|
|
if (scaleMix != 0) {
|
|
if (scaleX > 0.00001)
|
|
scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1;
|
|
if (scaleY > 0.00001)
|
|
scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1;
|
|
}
|
|
var shearY = bone.ashearY;
|
|
if (shearMix != 0)
|
|
shearY += (target.ashearY + this.data.offsetShearY) * shearMix;
|
|
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
|
}
|
|
};
|
|
return TransformConstraint;
|
|
}());
|
|
spine.TransformConstraint = TransformConstraint;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var TransformConstraintData = (function (_super) {
|
|
__extends(TransformConstraintData, _super);
|
|
function TransformConstraintData(name) {
|
|
var _this = _super.call(this, name, 0, false) || this;
|
|
_this.bones = new Array();
|
|
_this.rotateMix = 0;
|
|
_this.translateMix = 0;
|
|
_this.scaleMix = 0;
|
|
_this.shearMix = 0;
|
|
_this.offsetRotation = 0;
|
|
_this.offsetX = 0;
|
|
_this.offsetY = 0;
|
|
_this.offsetScaleX = 0;
|
|
_this.offsetScaleY = 0;
|
|
_this.offsetShearY = 0;
|
|
_this.relative = false;
|
|
_this.local = false;
|
|
return _this;
|
|
}
|
|
return TransformConstraintData;
|
|
}(spine.ConstraintData));
|
|
spine.TransformConstraintData = TransformConstraintData;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var Triangulator = (function () {
|
|
function Triangulator() {
|
|
this.convexPolygons = new Array();
|
|
this.convexPolygonsIndices = new Array();
|
|
this.indicesArray = new Array();
|
|
this.isConcaveArray = new Array();
|
|
this.triangles = new Array();
|
|
this.polygonPool = new spine.Pool(function () {
|
|
return new Array();
|
|
});
|
|
this.polygonIndicesPool = new spine.Pool(function () {
|
|
return new Array();
|
|
});
|
|
}
|
|
Triangulator.prototype.triangulate = function (verticesArray) {
|
|
var vertices = verticesArray;
|
|
var vertexCount = verticesArray.length >> 1;
|
|
var indices = this.indicesArray;
|
|
indices.length = 0;
|
|
for (var i = 0; i < vertexCount; i++)
|
|
indices[i] = i;
|
|
var isConcave = this.isConcaveArray;
|
|
isConcave.length = 0;
|
|
for (var i = 0, n = vertexCount; i < n; ++i)
|
|
isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices);
|
|
var triangles = this.triangles;
|
|
triangles.length = 0;
|
|
while (vertexCount > 3) {
|
|
var previous = vertexCount - 1, i = 0, next = 1;
|
|
while (true) {
|
|
outer: if (!isConcave[i]) {
|
|
var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
|
|
var p1x = vertices[p1], p1y = vertices[p1 + 1];
|
|
var p2x = vertices[p2], p2y = vertices[p2 + 1];
|
|
var p3x = vertices[p3], p3y = vertices[p3 + 1];
|
|
for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
|
|
if (!isConcave[ii])
|
|
continue;
|
|
var v = indices[ii] << 1;
|
|
var vx = vertices[v], vy = vertices[v + 1];
|
|
if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
|
|
if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
|
|
if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (next == 0) {
|
|
do {
|
|
if (!isConcave[i])
|
|
break;
|
|
i--;
|
|
} while (i > 0);
|
|
break;
|
|
}
|
|
previous = i;
|
|
i = next;
|
|
next = (next + 1) % vertexCount;
|
|
}
|
|
triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
|
|
triangles.push(indices[i]);
|
|
triangles.push(indices[(i + 1) % vertexCount]);
|
|
indices.splice(i, 1);
|
|
isConcave.splice(i, 1);
|
|
vertexCount--;
|
|
var previousIndex = (vertexCount + i - 1) % vertexCount;
|
|
var nextIndex = i == vertexCount ? 0 : i;
|
|
isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices);
|
|
isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices);
|
|
}
|
|
if (vertexCount == 3) {
|
|
triangles.push(indices[2]);
|
|
triangles.push(indices[0]);
|
|
triangles.push(indices[1]);
|
|
}
|
|
return triangles;
|
|
};
|
|
Triangulator.prototype.decompose = function (verticesArray, triangles) {
|
|
var vertices = verticesArray;
|
|
var convexPolygons = this.convexPolygons;
|
|
this.polygonPool.freeAll(convexPolygons);
|
|
convexPolygons.length = 0;
|
|
var convexPolygonsIndices = this.convexPolygonsIndices;
|
|
this.polygonIndicesPool.freeAll(convexPolygonsIndices);
|
|
convexPolygonsIndices.length = 0;
|
|
var polygonIndices = this.polygonIndicesPool.obtain();
|
|
polygonIndices.length = 0;
|
|
var polygon = this.polygonPool.obtain();
|
|
polygon.length = 0;
|
|
var fanBaseIndex = -1, lastWinding = 0;
|
|
for (var i = 0, n = triangles.length; i < n; i += 3) {
|
|
var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
|
|
var x1 = vertices[t1], y1 = vertices[t1 + 1];
|
|
var x2 = vertices[t2], y2 = vertices[t2 + 1];
|
|
var x3 = vertices[t3], y3 = vertices[t3 + 1];
|
|
var merged = false;
|
|
if (fanBaseIndex == t1) {
|
|
var o = polygon.length - 4;
|
|
var winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
|
|
var winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
|
|
if (winding1 == lastWinding && winding2 == lastWinding) {
|
|
polygon.push(x3);
|
|
polygon.push(y3);
|
|
polygonIndices.push(t3);
|
|
merged = true;
|
|
}
|
|
}
|
|
if (!merged) {
|
|
if (polygon.length > 0) {
|
|
convexPolygons.push(polygon);
|
|
convexPolygonsIndices.push(polygonIndices);
|
|
}
|
|
else {
|
|
this.polygonPool.free(polygon);
|
|
this.polygonIndicesPool.free(polygonIndices);
|
|
}
|
|
polygon = this.polygonPool.obtain();
|
|
polygon.length = 0;
|
|
polygon.push(x1);
|
|
polygon.push(y1);
|
|
polygon.push(x2);
|
|
polygon.push(y2);
|
|
polygon.push(x3);
|
|
polygon.push(y3);
|
|
polygonIndices = this.polygonIndicesPool.obtain();
|
|
polygonIndices.length = 0;
|
|
polygonIndices.push(t1);
|
|
polygonIndices.push(t2);
|
|
polygonIndices.push(t3);
|
|
lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3);
|
|
fanBaseIndex = t1;
|
|
}
|
|
}
|
|
if (polygon.length > 0) {
|
|
convexPolygons.push(polygon);
|
|
convexPolygonsIndices.push(polygonIndices);
|
|
}
|
|
for (var i = 0, n = convexPolygons.length; i < n; i++) {
|
|
polygonIndices = convexPolygonsIndices[i];
|
|
if (polygonIndices.length == 0)
|
|
continue;
|
|
var firstIndex = polygonIndices[0];
|
|
var lastIndex = polygonIndices[polygonIndices.length - 1];
|
|
polygon = convexPolygons[i];
|
|
var o = polygon.length - 4;
|
|
var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
|
|
var prevX = polygon[o + 2], prevY = polygon[o + 3];
|
|
var firstX = polygon[0], firstY = polygon[1];
|
|
var secondX = polygon[2], secondY = polygon[3];
|
|
var winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
|
|
for (var ii = 0; ii < n; ii++) {
|
|
if (ii == i)
|
|
continue;
|
|
var otherIndices = convexPolygonsIndices[ii];
|
|
if (otherIndices.length != 3)
|
|
continue;
|
|
var otherFirstIndex = otherIndices[0];
|
|
var otherSecondIndex = otherIndices[1];
|
|
var otherLastIndex = otherIndices[2];
|
|
var otherPoly = convexPolygons[ii];
|
|
var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
|
|
if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
|
|
continue;
|
|
var winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
|
|
var winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY);
|
|
if (winding1 == winding && winding2 == winding) {
|
|
otherPoly.length = 0;
|
|
otherIndices.length = 0;
|
|
polygon.push(x3);
|
|
polygon.push(y3);
|
|
polygonIndices.push(otherLastIndex);
|
|
prevPrevX = prevX;
|
|
prevPrevY = prevY;
|
|
prevX = x3;
|
|
prevY = y3;
|
|
ii = 0;
|
|
}
|
|
}
|
|
}
|
|
for (var i = convexPolygons.length - 1; i >= 0; i--) {
|
|
polygon = convexPolygons[i];
|
|
if (polygon.length == 0) {
|
|
convexPolygons.splice(i, 1);
|
|
this.polygonPool.free(polygon);
|
|
polygonIndices = convexPolygonsIndices[i];
|
|
convexPolygonsIndices.splice(i, 1);
|
|
this.polygonIndicesPool.free(polygonIndices);
|
|
}
|
|
}
|
|
return convexPolygons;
|
|
};
|
|
Triangulator.isConcave = function (index, vertexCount, vertices, indices) {
|
|
var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
|
|
var current = indices[index] << 1;
|
|
var next = indices[(index + 1) % vertexCount] << 1;
|
|
return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
|
|
};
|
|
Triangulator.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
|
|
};
|
|
Triangulator.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
var px = p2x - p1x, py = p2y - p1y;
|
|
return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
|
|
};
|
|
return Triangulator;
|
|
}());
|
|
spine.Triangulator = Triangulator;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var IntSet = (function () {
|
|
function IntSet() {
|
|
this.array = new Array();
|
|
}
|
|
IntSet.prototype.add = function (value) {
|
|
var contains = this.contains(value);
|
|
this.array[value | 0] = value | 0;
|
|
return !contains;
|
|
};
|
|
IntSet.prototype.contains = function (value) {
|
|
return this.array[value | 0] != undefined;
|
|
};
|
|
IntSet.prototype.remove = function (value) {
|
|
this.array[value | 0] = undefined;
|
|
};
|
|
IntSet.prototype.clear = function () {
|
|
this.array.length = 0;
|
|
};
|
|
return IntSet;
|
|
}());
|
|
spine.IntSet = IntSet;
|
|
var Color = (function () {
|
|
function Color(r, g, b, a) {
|
|
if (r === void 0) { r = 0; }
|
|
if (g === void 0) { g = 0; }
|
|
if (b === void 0) { b = 0; }
|
|
if (a === void 0) { a = 0; }
|
|
this.r = r;
|
|
this.g = g;
|
|
this.b = b;
|
|
this.a = a;
|
|
}
|
|
Color.prototype.set = function (r, g, b, a) {
|
|
this.r = r;
|
|
this.g = g;
|
|
this.b = b;
|
|
this.a = a;
|
|
this.clamp();
|
|
return this;
|
|
};
|
|
Color.prototype.setFromColor = function (c) {
|
|
this.r = c.r;
|
|
this.g = c.g;
|
|
this.b = c.b;
|
|
this.a = c.a;
|
|
return this;
|
|
};
|
|
Color.prototype.setFromString = function (hex) {
|
|
hex = hex.charAt(0) == '#' ? hex.substr(1) : hex;
|
|
this.r = parseInt(hex.substr(0, 2), 16) / 255.0;
|
|
this.g = parseInt(hex.substr(2, 2), 16) / 255.0;
|
|
this.b = parseInt(hex.substr(4, 2), 16) / 255.0;
|
|
this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0;
|
|
return this;
|
|
};
|
|
Color.prototype.add = function (r, g, b, a) {
|
|
this.r += r;
|
|
this.g += g;
|
|
this.b += b;
|
|
this.a += a;
|
|
this.clamp();
|
|
return this;
|
|
};
|
|
Color.prototype.clamp = function () {
|
|
if (this.r < 0)
|
|
this.r = 0;
|
|
else if (this.r > 1)
|
|
this.r = 1;
|
|
if (this.g < 0)
|
|
this.g = 0;
|
|
else if (this.g > 1)
|
|
this.g = 1;
|
|
if (this.b < 0)
|
|
this.b = 0;
|
|
else if (this.b > 1)
|
|
this.b = 1;
|
|
if (this.a < 0)
|
|
this.a = 0;
|
|
else if (this.a > 1)
|
|
this.a = 1;
|
|
return this;
|
|
};
|
|
Color.rgba8888ToColor = function (color, value) {
|
|
color.r = ((value & 0xff000000) >>> 24) / 255;
|
|
color.g = ((value & 0x00ff0000) >>> 16) / 255;
|
|
color.b = ((value & 0x0000ff00) >>> 8) / 255;
|
|
color.a = ((value & 0x000000ff)) / 255;
|
|
};
|
|
Color.rgb888ToColor = function (color, value) {
|
|
color.r = ((value & 0x00ff0000) >>> 16) / 255;
|
|
color.g = ((value & 0x0000ff00) >>> 8) / 255;
|
|
color.b = ((value & 0x000000ff)) / 255;
|
|
};
|
|
Color.WHITE = new Color(1, 1, 1, 1);
|
|
Color.RED = new Color(1, 0, 0, 1);
|
|
Color.GREEN = new Color(0, 1, 0, 1);
|
|
Color.BLUE = new Color(0, 0, 1, 1);
|
|
Color.MAGENTA = new Color(1, 0, 1, 1);
|
|
return Color;
|
|
}());
|
|
spine.Color = Color;
|
|
var MathUtils = (function () {
|
|
function MathUtils() {
|
|
}
|
|
MathUtils.clamp = function (value, min, max) {
|
|
if (value < min)
|
|
return min;
|
|
if (value > max)
|
|
return max;
|
|
return value;
|
|
};
|
|
MathUtils.cosDeg = function (degrees) {
|
|
return Math.cos(degrees * MathUtils.degRad);
|
|
};
|
|
MathUtils.sinDeg = function (degrees) {
|
|
return Math.sin(degrees * MathUtils.degRad);
|
|
};
|
|
MathUtils.signum = function (value) {
|
|
return value > 0 ? 1 : value < 0 ? -1 : 0;
|
|
};
|
|
MathUtils.toInt = function (x) {
|
|
return x > 0 ? Math.floor(x) : Math.ceil(x);
|
|
};
|
|
MathUtils.cbrt = function (x) {
|
|
var y = Math.pow(Math.abs(x), 1 / 3);
|
|
return x < 0 ? -y : y;
|
|
};
|
|
MathUtils.randomTriangular = function (min, max) {
|
|
return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5);
|
|
};
|
|
MathUtils.randomTriangularWith = function (min, max, mode) {
|
|
var u = Math.random();
|
|
var d = max - min;
|
|
if (u <= (mode - min) / d)
|
|
return min + Math.sqrt(u * d * (mode - min));
|
|
return max - Math.sqrt((1 - u) * d * (max - mode));
|
|
};
|
|
MathUtils.PI = 3.1415927;
|
|
MathUtils.PI2 = MathUtils.PI * 2;
|
|
MathUtils.radiansToDegrees = 180 / MathUtils.PI;
|
|
MathUtils.radDeg = MathUtils.radiansToDegrees;
|
|
MathUtils.degreesToRadians = MathUtils.PI / 180;
|
|
MathUtils.degRad = MathUtils.degreesToRadians;
|
|
return MathUtils;
|
|
}());
|
|
spine.MathUtils = MathUtils;
|
|
var Interpolation = (function () {
|
|
function Interpolation() {
|
|
}
|
|
Interpolation.prototype.apply = function (start, end, a) {
|
|
return start + (end - start) * this.applyInternal(a);
|
|
};
|
|
return Interpolation;
|
|
}());
|
|
spine.Interpolation = Interpolation;
|
|
var Pow = (function (_super) {
|
|
__extends(Pow, _super);
|
|
function Pow(power) {
|
|
var _this = _super.call(this) || this;
|
|
_this.power = 2;
|
|
_this.power = power;
|
|
return _this;
|
|
}
|
|
Pow.prototype.applyInternal = function (a) {
|
|
if (a <= 0.5)
|
|
return Math.pow(a * 2, this.power) / 2;
|
|
return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1;
|
|
};
|
|
return Pow;
|
|
}(Interpolation));
|
|
spine.Pow = Pow;
|
|
var PowOut = (function (_super) {
|
|
__extends(PowOut, _super);
|
|
function PowOut(power) {
|
|
return _super.call(this, power) || this;
|
|
}
|
|
PowOut.prototype.applyInternal = function (a) {
|
|
return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1;
|
|
};
|
|
return PowOut;
|
|
}(Pow));
|
|
spine.PowOut = PowOut;
|
|
var Utils = (function () {
|
|
function Utils() {
|
|
}
|
|
Utils.arrayCopy = function (source, sourceStart, dest, destStart, numElements) {
|
|
for (var i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) {
|
|
dest[j] = source[i];
|
|
}
|
|
};
|
|
Utils.setArraySize = function (array, size, value) {
|
|
if (value === void 0) { value = 0; }
|
|
var oldSize = array.length;
|
|
if (oldSize == size)
|
|
return array;
|
|
array.length = size;
|
|
if (oldSize < size) {
|
|
for (var i = oldSize; i < size; i++)
|
|
array[i] = value;
|
|
}
|
|
return array;
|
|
};
|
|
Utils.ensureArrayCapacity = function (array, size, value) {
|
|
if (value === void 0) { value = 0; }
|
|
if (array.length >= size)
|
|
return array;
|
|
return Utils.setArraySize(array, size, value);
|
|
};
|
|
Utils.newArray = function (size, defaultValue) {
|
|
var array = new Array(size);
|
|
for (var i = 0; i < size; i++)
|
|
array[i] = defaultValue;
|
|
return array;
|
|
};
|
|
Utils.newFloatArray = function (size) {
|
|
if (Utils.SUPPORTS_TYPED_ARRAYS) {
|
|
return new Float32Array(size);
|
|
}
|
|
else {
|
|
var array = new Array(size);
|
|
for (var i = 0; i < array.length; i++)
|
|
array[i] = 0;
|
|
return array;
|
|
}
|
|
};
|
|
Utils.newShortArray = function (size) {
|
|
if (Utils.SUPPORTS_TYPED_ARRAYS) {
|
|
return new Int16Array(size);
|
|
}
|
|
else {
|
|
var array = new Array(size);
|
|
for (var i = 0; i < array.length; i++)
|
|
array[i] = 0;
|
|
return array;
|
|
}
|
|
};
|
|
Utils.toFloatArray = function (array) {
|
|
return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
|
|
};
|
|
Utils.toSinglePrecision = function (value) {
|
|
return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value;
|
|
};
|
|
Utils.webkit602BugfixHelper = function (alpha, blend) {
|
|
};
|
|
Utils.contains = function (array, element, identity) {
|
|
if (identity === void 0) { identity = true; }
|
|
for (var i = 0; i < array.length; i++) {
|
|
if (array[i] == element)
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
|
|
return Utils;
|
|
}());
|
|
spine.Utils = Utils;
|
|
var DebugUtils = (function () {
|
|
function DebugUtils() {
|
|
}
|
|
DebugUtils.logBones = function (skeleton) {
|
|
for (var i = 0; i < skeleton.bones.length; i++) {
|
|
var bone = skeleton.bones[i];
|
|
console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY);
|
|
}
|
|
};
|
|
return DebugUtils;
|
|
}());
|
|
spine.DebugUtils = DebugUtils;
|
|
var Pool = (function () {
|
|
function Pool(instantiator) {
|
|
this.items = new Array();
|
|
this.instantiator = instantiator;
|
|
}
|
|
Pool.prototype.obtain = function () {
|
|
return this.items.length > 0 ? this.items.pop() : this.instantiator();
|
|
};
|
|
Pool.prototype.free = function (item) {
|
|
if (item.reset)
|
|
item.reset();
|
|
this.items.push(item);
|
|
};
|
|
Pool.prototype.freeAll = function (items) {
|
|
for (var i = 0; i < items.length; i++) {
|
|
this.free(items[i]);
|
|
}
|
|
};
|
|
Pool.prototype.clear = function () {
|
|
this.items.length = 0;
|
|
};
|
|
return Pool;
|
|
}());
|
|
spine.Pool = Pool;
|
|
var Vector2 = (function () {
|
|
function Vector2(x, y) {
|
|
if (x === void 0) { x = 0; }
|
|
if (y === void 0) { y = 0; }
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
Vector2.prototype.set = function (x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
return this;
|
|
};
|
|
Vector2.prototype.length = function () {
|
|
var x = this.x;
|
|
var y = this.y;
|
|
return Math.sqrt(x * x + y * y);
|
|
};
|
|
Vector2.prototype.normalize = function () {
|
|
var len = this.length();
|
|
if (len != 0) {
|
|
this.x /= len;
|
|
this.y /= len;
|
|
}
|
|
return this;
|
|
};
|
|
return Vector2;
|
|
}());
|
|
spine.Vector2 = Vector2;
|
|
var TimeKeeper = (function () {
|
|
function TimeKeeper() {
|
|
this.maxDelta = 0.064;
|
|
this.framesPerSecond = 0;
|
|
this.delta = 0;
|
|
this.totalTime = 0;
|
|
this.lastTime = Date.now() / 1000;
|
|
this.frameCount = 0;
|
|
this.frameTime = 0;
|
|
}
|
|
TimeKeeper.prototype.update = function () {
|
|
var now = Date.now() / 1000;
|
|
this.delta = now - this.lastTime;
|
|
this.frameTime += this.delta;
|
|
this.totalTime += this.delta;
|
|
if (this.delta > this.maxDelta)
|
|
this.delta = this.maxDelta;
|
|
this.lastTime = now;
|
|
this.frameCount++;
|
|
if (this.frameTime > 1) {
|
|
this.framesPerSecond = this.frameCount / this.frameTime;
|
|
this.frameTime = 0;
|
|
this.frameCount = 0;
|
|
}
|
|
};
|
|
return TimeKeeper;
|
|
}());
|
|
spine.TimeKeeper = TimeKeeper;
|
|
var WindowedMean = (function () {
|
|
function WindowedMean(windowSize) {
|
|
if (windowSize === void 0) { windowSize = 32; }
|
|
this.addedValues = 0;
|
|
this.lastValue = 0;
|
|
this.mean = 0;
|
|
this.dirty = true;
|
|
this.values = new Array(windowSize);
|
|
}
|
|
WindowedMean.prototype.hasEnoughData = function () {
|
|
return this.addedValues >= this.values.length;
|
|
};
|
|
WindowedMean.prototype.addValue = function (value) {
|
|
if (this.addedValues < this.values.length)
|
|
this.addedValues++;
|
|
this.values[this.lastValue++] = value;
|
|
if (this.lastValue > this.values.length - 1)
|
|
this.lastValue = 0;
|
|
this.dirty = true;
|
|
};
|
|
WindowedMean.prototype.getMean = function () {
|
|
if (this.hasEnoughData()) {
|
|
if (this.dirty) {
|
|
var mean = 0;
|
|
for (var i = 0; i < this.values.length; i++) {
|
|
mean += this.values[i];
|
|
}
|
|
this.mean = mean / this.values.length;
|
|
this.dirty = false;
|
|
}
|
|
return this.mean;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
};
|
|
return WindowedMean;
|
|
}());
|
|
spine.WindowedMean = WindowedMean;
|
|
})(spine || (spine = {}));
|
|
(function () {
|
|
if (!Math.fround) {
|
|
Math.fround = (function (array) {
|
|
return function (x) {
|
|
return array[0] = x, array[0];
|
|
};
|
|
})(new Float32Array(1));
|
|
}
|
|
})();
|
|
var spine;
|
|
(function (spine) {
|
|
var Attachment = (function () {
|
|
function Attachment(name) {
|
|
if (name == null)
|
|
throw new Error("name cannot be null.");
|
|
this.name = name;
|
|
}
|
|
return Attachment;
|
|
}());
|
|
spine.Attachment = Attachment;
|
|
var VertexAttachment = (function (_super) {
|
|
__extends(VertexAttachment, _super);
|
|
function VertexAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.id = (VertexAttachment.nextID++ & 65535) << 11;
|
|
_this.worldVerticesLength = 0;
|
|
_this.deformAttachment = _this;
|
|
return _this;
|
|
}
|
|
VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) {
|
|
count = offset + (count >> 1) * stride;
|
|
var skeleton = slot.bone.skeleton;
|
|
var deformArray = slot.deform;
|
|
var vertices = this.vertices;
|
|
var bones = this.bones;
|
|
if (bones == null) {
|
|
if (deformArray.length > 0)
|
|
vertices = deformArray;
|
|
var bone = slot.bone;
|
|
var x = bone.worldX;
|
|
var y = bone.worldY;
|
|
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
|
for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) {
|
|
var vx = vertices[v_1], vy = vertices[v_1 + 1];
|
|
worldVertices[w] = vx * a + vy * b + x;
|
|
worldVertices[w + 1] = vx * c + vy * d + y;
|
|
}
|
|
return;
|
|
}
|
|
var v = 0, skip = 0;
|
|
for (var i = 0; i < start; i += 2) {
|
|
var n = bones[v];
|
|
v += n + 1;
|
|
skip += n;
|
|
}
|
|
var skeletonBones = skeleton.bones;
|
|
if (deformArray.length == 0) {
|
|
for (var w = offset, b = skip * 3; w < count; w += stride) {
|
|
var wx = 0, wy = 0;
|
|
var n = bones[v++];
|
|
n += v;
|
|
for (; v < n; v++, b += 3) {
|
|
var bone = skeletonBones[bones[v]];
|
|
var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
|
|
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
|
|
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
|
|
}
|
|
worldVertices[w] = wx;
|
|
worldVertices[w + 1] = wy;
|
|
}
|
|
}
|
|
else {
|
|
var deform = deformArray;
|
|
for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
|
|
var wx = 0, wy = 0;
|
|
var n = bones[v++];
|
|
n += v;
|
|
for (; v < n; v++, b += 3, f += 2) {
|
|
var bone = skeletonBones[bones[v]];
|
|
var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
|
|
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
|
|
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
|
|
}
|
|
worldVertices[w] = wx;
|
|
worldVertices[w + 1] = wy;
|
|
}
|
|
}
|
|
};
|
|
VertexAttachment.prototype.copyTo = function (attachment) {
|
|
if (this.bones != null) {
|
|
attachment.bones = new Array(this.bones.length);
|
|
spine.Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);
|
|
}
|
|
else
|
|
attachment.bones = null;
|
|
if (this.vertices != null) {
|
|
attachment.vertices = spine.Utils.newFloatArray(this.vertices.length);
|
|
spine.Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length);
|
|
}
|
|
else
|
|
attachment.vertices = null;
|
|
attachment.worldVerticesLength = this.worldVerticesLength;
|
|
attachment.deformAttachment = this.deformAttachment;
|
|
};
|
|
VertexAttachment.nextID = 0;
|
|
return VertexAttachment;
|
|
}(Attachment));
|
|
spine.VertexAttachment = VertexAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var AttachmentType;
|
|
(function (AttachmentType) {
|
|
AttachmentType[AttachmentType["Region"] = 0] = "Region";
|
|
AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox";
|
|
AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh";
|
|
AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh";
|
|
AttachmentType[AttachmentType["Path"] = 4] = "Path";
|
|
AttachmentType[AttachmentType["Point"] = 5] = "Point";
|
|
AttachmentType[AttachmentType["Clipping"] = 6] = "Clipping";
|
|
})(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var BoundingBoxAttachment = (function (_super) {
|
|
__extends(BoundingBoxAttachment, _super);
|
|
function BoundingBoxAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.color = new spine.Color(1, 1, 1, 1);
|
|
return _this;
|
|
}
|
|
BoundingBoxAttachment.prototype.copy = function () {
|
|
var copy = new BoundingBoxAttachment(name);
|
|
this.copyTo(copy);
|
|
copy.color.setFromColor(this.color);
|
|
return copy;
|
|
};
|
|
return BoundingBoxAttachment;
|
|
}(spine.VertexAttachment));
|
|
spine.BoundingBoxAttachment = BoundingBoxAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var ClippingAttachment = (function (_super) {
|
|
__extends(ClippingAttachment, _super);
|
|
function ClippingAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
|
|
return _this;
|
|
}
|
|
ClippingAttachment.prototype.copy = function () {
|
|
var copy = new ClippingAttachment(name);
|
|
this.copyTo(copy);
|
|
copy.endSlot = this.endSlot;
|
|
copy.color.setFromColor(this.color);
|
|
return copy;
|
|
};
|
|
return ClippingAttachment;
|
|
}(spine.VertexAttachment));
|
|
spine.ClippingAttachment = ClippingAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var MeshAttachment = (function (_super) {
|
|
__extends(MeshAttachment, _super);
|
|
function MeshAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.color = new spine.Color(1, 1, 1, 1);
|
|
_this.tempColor = new spine.Color(0, 0, 0, 0);
|
|
return _this;
|
|
}
|
|
MeshAttachment.prototype.updateUVs = function () {
|
|
var regionUVs = this.regionUVs;
|
|
if (this.uvs == null || this.uvs.length != regionUVs.length)
|
|
this.uvs = spine.Utils.newFloatArray(regionUVs.length);
|
|
var uvs = this.uvs;
|
|
var n = this.uvs.length;
|
|
var u = this.region.u, v = this.region.v, width = 0, height = 0;
|
|
if (this.region instanceof spine.TextureAtlasRegion) {
|
|
var region = this.region;
|
|
var textureWidth = region.texture.getImage().width, textureHeight = region.texture.getImage().height;
|
|
switch (region.degrees) {
|
|
case 90:
|
|
u -= (region.originalHeight - region.offsetY - region.height) / textureWidth;
|
|
v -= (region.originalWidth - region.offsetX - region.width) / textureHeight;
|
|
width = region.originalHeight / textureWidth;
|
|
height = region.originalWidth / textureHeight;
|
|
for (var i = 0; i < n; i += 2) {
|
|
uvs[i] = u + regionUVs[i + 1] * width;
|
|
uvs[i + 1] = v + (1 - regionUVs[i]) * height;
|
|
}
|
|
return;
|
|
case 180:
|
|
u -= (region.originalWidth - region.offsetX - region.width) / textureWidth;
|
|
v -= region.offsetY / textureHeight;
|
|
width = region.originalWidth / textureWidth;
|
|
height = region.originalHeight / textureHeight;
|
|
for (var i = 0; i < n; i += 2) {
|
|
uvs[i] = u + (1 - regionUVs[i]) * width;
|
|
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
|
|
}
|
|
return;
|
|
case 270:
|
|
u -= region.offsetY / textureWidth;
|
|
v -= region.offsetX / textureHeight;
|
|
width = region.originalHeight / textureWidth;
|
|
height = region.originalWidth / textureHeight;
|
|
for (var i = 0; i < n; i += 2) {
|
|
uvs[i] = u + (1 - regionUVs[i + 1]) * width;
|
|
uvs[i + 1] = v + regionUVs[i] * height;
|
|
}
|
|
return;
|
|
}
|
|
u -= region.offsetX / textureWidth;
|
|
v -= (region.originalHeight - region.offsetY - region.height) / textureHeight;
|
|
width = region.originalWidth / textureWidth;
|
|
height = region.originalHeight / textureHeight;
|
|
}
|
|
else if (this.region == null) {
|
|
u = v = 0;
|
|
width = height = 1;
|
|
}
|
|
else {
|
|
width = this.region.u2 - u;
|
|
height = this.region.v2 - v;
|
|
}
|
|
for (var i = 0; i < n; i += 2) {
|
|
uvs[i] = u + regionUVs[i] * width;
|
|
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
|
}
|
|
};
|
|
MeshAttachment.prototype.getParentMesh = function () {
|
|
return this.parentMesh;
|
|
};
|
|
MeshAttachment.prototype.setParentMesh = function (parentMesh) {
|
|
this.parentMesh = parentMesh;
|
|
if (parentMesh != null) {
|
|
this.bones = parentMesh.bones;
|
|
this.vertices = parentMesh.vertices;
|
|
this.worldVerticesLength = parentMesh.worldVerticesLength;
|
|
this.regionUVs = parentMesh.regionUVs;
|
|
this.triangles = parentMesh.triangles;
|
|
this.hullLength = parentMesh.hullLength;
|
|
this.worldVerticesLength = parentMesh.worldVerticesLength;
|
|
}
|
|
};
|
|
MeshAttachment.prototype.copy = function () {
|
|
if (this.parentMesh != null)
|
|
return this.newLinkedMesh();
|
|
var copy = new MeshAttachment(this.name);
|
|
copy.region = this.region;
|
|
copy.path = this.path;
|
|
copy.color.setFromColor(this.color);
|
|
this.copyTo(copy);
|
|
copy.regionUVs = new Array(this.regionUVs.length);
|
|
spine.Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length);
|
|
copy.uvs = new Array(this.uvs.length);
|
|
spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length);
|
|
copy.triangles = new Array(this.triangles.length);
|
|
spine.Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length);
|
|
copy.hullLength = this.hullLength;
|
|
if (this.edges != null) {
|
|
copy.edges = new Array(this.edges.length);
|
|
spine.Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length);
|
|
}
|
|
copy.width = this.width;
|
|
copy.height = this.height;
|
|
return copy;
|
|
};
|
|
MeshAttachment.prototype.newLinkedMesh = function () {
|
|
var copy = new MeshAttachment(this.name);
|
|
copy.region = this.region;
|
|
copy.path = this.path;
|
|
copy.color.setFromColor(this.color);
|
|
copy.deformAttachment = this.deformAttachment;
|
|
copy.setParentMesh(this.parentMesh != null ? this.parentMesh : this);
|
|
copy.updateUVs();
|
|
return copy;
|
|
};
|
|
return MeshAttachment;
|
|
}(spine.VertexAttachment));
|
|
spine.MeshAttachment = MeshAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var PathAttachment = (function (_super) {
|
|
__extends(PathAttachment, _super);
|
|
function PathAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.closed = false;
|
|
_this.constantSpeed = false;
|
|
_this.color = new spine.Color(1, 1, 1, 1);
|
|
return _this;
|
|
}
|
|
PathAttachment.prototype.copy = function () {
|
|
var copy = new PathAttachment(name);
|
|
this.copyTo(copy);
|
|
copy.lengths = new Array(this.lengths.length);
|
|
spine.Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length);
|
|
copy.closed = closed;
|
|
copy.constantSpeed = this.constantSpeed;
|
|
copy.color.setFromColor(this.color);
|
|
return copy;
|
|
};
|
|
return PathAttachment;
|
|
}(spine.VertexAttachment));
|
|
spine.PathAttachment = PathAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var PointAttachment = (function (_super) {
|
|
__extends(PointAttachment, _super);
|
|
function PointAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.color = new spine.Color(0.38, 0.94, 0, 1);
|
|
return _this;
|
|
}
|
|
PointAttachment.prototype.computeWorldPosition = function (bone, point) {
|
|
point.x = this.x * bone.a + this.y * bone.b + bone.worldX;
|
|
point.y = this.x * bone.c + this.y * bone.d + bone.worldY;
|
|
return point;
|
|
};
|
|
PointAttachment.prototype.computeWorldRotation = function (bone) {
|
|
var cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation);
|
|
var x = cos * bone.a + sin * bone.b;
|
|
var y = cos * bone.c + sin * bone.d;
|
|
return Math.atan2(y, x) * spine.MathUtils.radDeg;
|
|
};
|
|
PointAttachment.prototype.copy = function () {
|
|
var copy = new PointAttachment(name);
|
|
copy.x = this.x;
|
|
copy.y = this.y;
|
|
copy.rotation = this.rotation;
|
|
copy.color.setFromColor(this.color);
|
|
return copy;
|
|
};
|
|
return PointAttachment;
|
|
}(spine.VertexAttachment));
|
|
spine.PointAttachment = PointAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var RegionAttachment = (function (_super) {
|
|
__extends(RegionAttachment, _super);
|
|
function RegionAttachment(name) {
|
|
var _this = _super.call(this, name) || this;
|
|
_this.x = 0;
|
|
_this.y = 0;
|
|
_this.scaleX = 1;
|
|
_this.scaleY = 1;
|
|
_this.rotation = 0;
|
|
_this.width = 0;
|
|
_this.height = 0;
|
|
_this.color = new spine.Color(1, 1, 1, 1);
|
|
_this.offset = spine.Utils.newFloatArray(8);
|
|
_this.uvs = spine.Utils.newFloatArray(8);
|
|
_this.tempColor = new spine.Color(1, 1, 1, 1);
|
|
return _this;
|
|
}
|
|
RegionAttachment.prototype.updateOffset = function () {
|
|
var regionScaleX = this.width / this.region.originalWidth * this.scaleX;
|
|
var regionScaleY = this.height / this.region.originalHeight * this.scaleY;
|
|
var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX;
|
|
var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY;
|
|
var localX2 = localX + this.region.width * regionScaleX;
|
|
var localY2 = localY + this.region.height * regionScaleY;
|
|
var radians = this.rotation * Math.PI / 180;
|
|
var cos = Math.cos(radians);
|
|
var sin = Math.sin(radians);
|
|
var localXCos = localX * cos + this.x;
|
|
var localXSin = localX * sin;
|
|
var localYCos = localY * cos + this.y;
|
|
var localYSin = localY * sin;
|
|
var localX2Cos = localX2 * cos + this.x;
|
|
var localX2Sin = localX2 * sin;
|
|
var localY2Cos = localY2 * cos + this.y;
|
|
var localY2Sin = localY2 * sin;
|
|
var offset = this.offset;
|
|
offset[RegionAttachment.OX1] = localXCos - localYSin;
|
|
offset[RegionAttachment.OY1] = localYCos + localXSin;
|
|
offset[RegionAttachment.OX2] = localXCos - localY2Sin;
|
|
offset[RegionAttachment.OY2] = localY2Cos + localXSin;
|
|
offset[RegionAttachment.OX3] = localX2Cos - localY2Sin;
|
|
offset[RegionAttachment.OY3] = localY2Cos + localX2Sin;
|
|
offset[RegionAttachment.OX4] = localX2Cos - localYSin;
|
|
offset[RegionAttachment.OY4] = localYCos + localX2Sin;
|
|
};
|
|
RegionAttachment.prototype.setRegion = function (region) {
|
|
this.region = region;
|
|
var uvs = this.uvs;
|
|
if (region.rotate) {
|
|
uvs[2] = region.u;
|
|
uvs[3] = region.v2;
|
|
uvs[4] = region.u;
|
|
uvs[5] = region.v;
|
|
uvs[6] = region.u2;
|
|
uvs[7] = region.v;
|
|
uvs[0] = region.u2;
|
|
uvs[1] = region.v2;
|
|
}
|
|
else {
|
|
uvs[0] = region.u;
|
|
uvs[1] = region.v2;
|
|
uvs[2] = region.u;
|
|
uvs[3] = region.v;
|
|
uvs[4] = region.u2;
|
|
uvs[5] = region.v;
|
|
uvs[6] = region.u2;
|
|
uvs[7] = region.v2;
|
|
}
|
|
};
|
|
RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) {
|
|
var vertexOffset = this.offset;
|
|
var x = bone.worldX, y = bone.worldY;
|
|
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
|
var offsetX = 0, offsetY = 0;
|
|
offsetX = vertexOffset[RegionAttachment.OX1];
|
|
offsetY = vertexOffset[RegionAttachment.OY1];
|
|
worldVertices[offset] = offsetX * a + offsetY * b + x;
|
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
|
offset += stride;
|
|
offsetX = vertexOffset[RegionAttachment.OX2];
|
|
offsetY = vertexOffset[RegionAttachment.OY2];
|
|
worldVertices[offset] = offsetX * a + offsetY * b + x;
|
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
|
offset += stride;
|
|
offsetX = vertexOffset[RegionAttachment.OX3];
|
|
offsetY = vertexOffset[RegionAttachment.OY3];
|
|
worldVertices[offset] = offsetX * a + offsetY * b + x;
|
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
|
offset += stride;
|
|
offsetX = vertexOffset[RegionAttachment.OX4];
|
|
offsetY = vertexOffset[RegionAttachment.OY4];
|
|
worldVertices[offset] = offsetX * a + offsetY * b + x;
|
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
|
};
|
|
RegionAttachment.prototype.copy = function () {
|
|
var copy = new RegionAttachment(this.name);
|
|
copy.region = this.region;
|
|
copy.rendererObject = this.rendererObject;
|
|
copy.path = this.path;
|
|
copy.x = this.x;
|
|
copy.y = this.y;
|
|
copy.scaleX = this.scaleX;
|
|
copy.scaleY = this.scaleY;
|
|
copy.rotation = this.rotation;
|
|
copy.width = this.width;
|
|
copy.height = this.height;
|
|
spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8);
|
|
spine.Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8);
|
|
copy.color.setFromColor(this.color);
|
|
return copy;
|
|
};
|
|
RegionAttachment.OX1 = 0;
|
|
RegionAttachment.OY1 = 1;
|
|
RegionAttachment.OX2 = 2;
|
|
RegionAttachment.OY2 = 3;
|
|
RegionAttachment.OX3 = 4;
|
|
RegionAttachment.OY3 = 5;
|
|
RegionAttachment.OX4 = 6;
|
|
RegionAttachment.OY4 = 7;
|
|
RegionAttachment.X1 = 0;
|
|
RegionAttachment.Y1 = 1;
|
|
RegionAttachment.C1R = 2;
|
|
RegionAttachment.C1G = 3;
|
|
RegionAttachment.C1B = 4;
|
|
RegionAttachment.C1A = 5;
|
|
RegionAttachment.U1 = 6;
|
|
RegionAttachment.V1 = 7;
|
|
RegionAttachment.X2 = 8;
|
|
RegionAttachment.Y2 = 9;
|
|
RegionAttachment.C2R = 10;
|
|
RegionAttachment.C2G = 11;
|
|
RegionAttachment.C2B = 12;
|
|
RegionAttachment.C2A = 13;
|
|
RegionAttachment.U2 = 14;
|
|
RegionAttachment.V2 = 15;
|
|
RegionAttachment.X3 = 16;
|
|
RegionAttachment.Y3 = 17;
|
|
RegionAttachment.C3R = 18;
|
|
RegionAttachment.C3G = 19;
|
|
RegionAttachment.C3B = 20;
|
|
RegionAttachment.C3A = 21;
|
|
RegionAttachment.U3 = 22;
|
|
RegionAttachment.V3 = 23;
|
|
RegionAttachment.X4 = 24;
|
|
RegionAttachment.Y4 = 25;
|
|
RegionAttachment.C4R = 26;
|
|
RegionAttachment.C4G = 27;
|
|
RegionAttachment.C4B = 28;
|
|
RegionAttachment.C4A = 29;
|
|
RegionAttachment.U4 = 30;
|
|
RegionAttachment.V4 = 31;
|
|
return RegionAttachment;
|
|
}(spine.Attachment));
|
|
spine.RegionAttachment = RegionAttachment;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var JitterEffect = (function () {
|
|
function JitterEffect(jitterX, jitterY) {
|
|
this.jitterX = 0;
|
|
this.jitterY = 0;
|
|
this.jitterX = jitterX;
|
|
this.jitterY = jitterY;
|
|
}
|
|
JitterEffect.prototype.begin = function (skeleton) {
|
|
};
|
|
JitterEffect.prototype.transform = function (position, uv, light, dark) {
|
|
position.x += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
|
|
position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
|
|
};
|
|
JitterEffect.prototype.end = function () {
|
|
};
|
|
return JitterEffect;
|
|
}());
|
|
spine.JitterEffect = JitterEffect;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var SwirlEffect = (function () {
|
|
function SwirlEffect(radius) {
|
|
this.centerX = 0;
|
|
this.centerY = 0;
|
|
this.radius = 0;
|
|
this.angle = 0;
|
|
this.worldX = 0;
|
|
this.worldY = 0;
|
|
this.radius = radius;
|
|
}
|
|
SwirlEffect.prototype.begin = function (skeleton) {
|
|
this.worldX = skeleton.x + this.centerX;
|
|
this.worldY = skeleton.y + this.centerY;
|
|
};
|
|
SwirlEffect.prototype.transform = function (position, uv, light, dark) {
|
|
var radAngle = this.angle * spine.MathUtils.degreesToRadians;
|
|
var x = position.x - this.worldX;
|
|
var y = position.y - this.worldY;
|
|
var dist = Math.sqrt(x * x + y * y);
|
|
if (dist < this.radius) {
|
|
var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius);
|
|
var cos = Math.cos(theta);
|
|
var sin = Math.sin(theta);
|
|
position.x = cos * x - sin * y + this.worldX;
|
|
position.y = sin * x + cos * y + this.worldY;
|
|
}
|
|
};
|
|
SwirlEffect.prototype.end = function () {
|
|
};
|
|
SwirlEffect.interpolation = new spine.PowOut(2);
|
|
return SwirlEffect;
|
|
}());
|
|
spine.SwirlEffect = SwirlEffect;
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var canvas;
|
|
(function (canvas) {
|
|
var AssetManager = (function (_super) {
|
|
__extends(AssetManager, _super);
|
|
function AssetManager(pathPrefix) {
|
|
if (pathPrefix === void 0) { pathPrefix = ""; }
|
|
return _super.call(this, function (image) { return new spine.canvas.CanvasTexture(image); }, pathPrefix) || this;
|
|
}
|
|
return AssetManager;
|
|
}(spine.AssetManager));
|
|
canvas.AssetManager = AssetManager;
|
|
})(canvas = spine.canvas || (spine.canvas = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var canvas;
|
|
(function (canvas) {
|
|
var CanvasTexture = (function (_super) {
|
|
__extends(CanvasTexture, _super);
|
|
function CanvasTexture(image) {
|
|
return _super.call(this, image) || this;
|
|
}
|
|
CanvasTexture.prototype.setFilters = function (minFilter, magFilter) { };
|
|
CanvasTexture.prototype.setWraps = function (uWrap, vWrap) { };
|
|
CanvasTexture.prototype.dispose = function () { };
|
|
return CanvasTexture;
|
|
}(spine.Texture));
|
|
canvas.CanvasTexture = CanvasTexture;
|
|
})(canvas = spine.canvas || (spine.canvas = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var canvas;
|
|
(function (canvas) {
|
|
var SkeletonRenderer = (function () {
|
|
function SkeletonRenderer(context) {
|
|
this.triangleRendering = false;
|
|
this.debugRendering = false;
|
|
this.vertices = spine.Utils.newFloatArray(8 * 1024);
|
|
this.tempColor = new spine.Color();
|
|
this.ctx = context;
|
|
}
|
|
SkeletonRenderer.prototype.draw = function (skeleton) {
|
|
if (this.triangleRendering)
|
|
this.drawTriangles(skeleton);
|
|
else
|
|
this.drawImages(skeleton);
|
|
};
|
|
SkeletonRenderer.prototype.drawImages = function (skeleton) {
|
|
var ctx = this.ctx;
|
|
var drawOrder = skeleton.drawOrder;
|
|
if (this.debugRendering)
|
|
ctx.strokeStyle = "green";
|
|
ctx.save();
|
|
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
|
var slot = drawOrder[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var attachment = slot.getAttachment();
|
|
var regionAttachment = null;
|
|
var region = null;
|
|
var image = null;
|
|
if (attachment instanceof spine.RegionAttachment) {
|
|
regionAttachment = attachment;
|
|
region = regionAttachment.region;
|
|
image = region.texture.getImage();
|
|
}
|
|
else
|
|
continue;
|
|
var skeleton_1 = slot.bone.skeleton;
|
|
var skeletonColor = skeleton_1.color;
|
|
var slotColor = slot.color;
|
|
var regionColor = regionAttachment.color;
|
|
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
|
|
var color = this.tempColor;
|
|
color.set(skeletonColor.r * slotColor.r * regionColor.r, skeletonColor.g * slotColor.g * regionColor.g, skeletonColor.b * slotColor.b * regionColor.b, alpha);
|
|
var att = attachment;
|
|
var bone = slot.bone;
|
|
var w = region.width;
|
|
var h = region.height;
|
|
ctx.save();
|
|
ctx.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
|
|
ctx.translate(attachment.offset[0], attachment.offset[1]);
|
|
ctx.rotate(attachment.rotation * Math.PI / 180);
|
|
var atlasScale = att.width / w;
|
|
ctx.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY);
|
|
ctx.translate(w / 2, h / 2);
|
|
if (attachment.region.rotate) {
|
|
var t = w;
|
|
w = h;
|
|
h = t;
|
|
ctx.rotate(-Math.PI / 2);
|
|
}
|
|
ctx.scale(1, -1);
|
|
ctx.translate(-w / 2, -h / 2);
|
|
if (color.r != 1 || color.g != 1 || color.b != 1 || color.a != 1) {
|
|
ctx.globalAlpha = color.a;
|
|
}
|
|
ctx.drawImage(image, region.x, region.y, w, h, 0, 0, w, h);
|
|
if (this.debugRendering)
|
|
ctx.strokeRect(0, 0, w, h);
|
|
ctx.restore();
|
|
}
|
|
ctx.restore();
|
|
};
|
|
SkeletonRenderer.prototype.drawTriangles = function (skeleton) {
|
|
var blendMode = null;
|
|
var vertices = this.vertices;
|
|
var triangles = null;
|
|
var drawOrder = skeleton.drawOrder;
|
|
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
|
var slot = drawOrder[i];
|
|
var attachment = slot.getAttachment();
|
|
var texture = null;
|
|
var region = null;
|
|
if (attachment instanceof spine.RegionAttachment) {
|
|
var regionAttachment = attachment;
|
|
vertices = this.computeRegionVertices(slot, regionAttachment, false);
|
|
triangles = SkeletonRenderer.QUAD_TRIANGLES;
|
|
region = regionAttachment.region;
|
|
texture = region.texture.getImage();
|
|
}
|
|
else if (attachment instanceof spine.MeshAttachment) {
|
|
var mesh = attachment;
|
|
vertices = this.computeMeshVertices(slot, mesh, false);
|
|
triangles = mesh.triangles;
|
|
texture = mesh.region.renderObject.texture.getImage();
|
|
}
|
|
else
|
|
continue;
|
|
if (texture != null) {
|
|
var slotBlendMode = slot.data.blendMode;
|
|
if (slotBlendMode != blendMode) {
|
|
blendMode = slotBlendMode;
|
|
}
|
|
var skeleton_2 = slot.bone.skeleton;
|
|
var skeletonColor = skeleton_2.color;
|
|
var slotColor = slot.color;
|
|
var attachmentColor = attachment.color;
|
|
var alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
|
|
var color = this.tempColor;
|
|
color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, alpha);
|
|
var ctx = this.ctx;
|
|
if (color.r != 1 || color.g != 1 || color.b != 1 || color.a != 1) {
|
|
ctx.globalAlpha = color.a;
|
|
}
|
|
for (var j = 0; j < triangles.length; j += 3) {
|
|
var t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 2] * 8;
|
|
var x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
|
|
var x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
|
|
var x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
|
|
this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
|
|
if (this.debugRendering) {
|
|
ctx.strokeStyle = "green";
|
|
ctx.beginPath();
|
|
ctx.moveTo(x0, y0);
|
|
ctx.lineTo(x1, y1);
|
|
ctx.lineTo(x2, y2);
|
|
ctx.lineTo(x0, y0);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.ctx.globalAlpha = 1;
|
|
};
|
|
SkeletonRenderer.prototype.drawTriangle = function (img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
|
|
var ctx = this.ctx;
|
|
u0 *= img.width;
|
|
v0 *= img.height;
|
|
u1 *= img.width;
|
|
v1 *= img.height;
|
|
u2 *= img.width;
|
|
v2 *= img.height;
|
|
ctx.beginPath();
|
|
ctx.moveTo(x0, y0);
|
|
ctx.lineTo(x1, y1);
|
|
ctx.lineTo(x2, y2);
|
|
ctx.closePath();
|
|
x1 -= x0;
|
|
y1 -= y0;
|
|
x2 -= x0;
|
|
y2 -= y0;
|
|
u1 -= u0;
|
|
v1 -= v0;
|
|
u2 -= u0;
|
|
v2 -= v0;
|
|
var det = 1 / (u1 * v2 - u2 * v1), a = (v2 * x1 - v1 * x2) * det, b = (v2 * y1 - v1 * y2) * det, c = (u1 * x2 - u2 * x1) * det, d = (u1 * y2 - u2 * y1) * det, e = x0 - a * u0 - c * v0, f = y0 - b * u0 - d * v0;
|
|
ctx.save();
|
|
ctx.transform(a, b, c, d, e, f);
|
|
ctx.clip();
|
|
ctx.drawImage(img, 0, 0);
|
|
ctx.restore();
|
|
};
|
|
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma) {
|
|
var skeleton = slot.bone.skeleton;
|
|
var skeletonColor = skeleton.color;
|
|
var slotColor = slot.color;
|
|
var regionColor = region.color;
|
|
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
|
|
var multiplier = pma ? alpha : 1;
|
|
var color = this.tempColor;
|
|
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
|
|
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
|
|
var vertices = this.vertices;
|
|
var uvs = region.uvs;
|
|
vertices[spine.RegionAttachment.C1R] = color.r;
|
|
vertices[spine.RegionAttachment.C1G] = color.g;
|
|
vertices[spine.RegionAttachment.C1B] = color.b;
|
|
vertices[spine.RegionAttachment.C1A] = color.a;
|
|
vertices[spine.RegionAttachment.U1] = uvs[0];
|
|
vertices[spine.RegionAttachment.V1] = uvs[1];
|
|
vertices[spine.RegionAttachment.C2R] = color.r;
|
|
vertices[spine.RegionAttachment.C2G] = color.g;
|
|
vertices[spine.RegionAttachment.C2B] = color.b;
|
|
vertices[spine.RegionAttachment.C2A] = color.a;
|
|
vertices[spine.RegionAttachment.U2] = uvs[2];
|
|
vertices[spine.RegionAttachment.V2] = uvs[3];
|
|
vertices[spine.RegionAttachment.C3R] = color.r;
|
|
vertices[spine.RegionAttachment.C3G] = color.g;
|
|
vertices[spine.RegionAttachment.C3B] = color.b;
|
|
vertices[spine.RegionAttachment.C3A] = color.a;
|
|
vertices[spine.RegionAttachment.U3] = uvs[4];
|
|
vertices[spine.RegionAttachment.V3] = uvs[5];
|
|
vertices[spine.RegionAttachment.C4R] = color.r;
|
|
vertices[spine.RegionAttachment.C4G] = color.g;
|
|
vertices[spine.RegionAttachment.C4B] = color.b;
|
|
vertices[spine.RegionAttachment.C4A] = color.a;
|
|
vertices[spine.RegionAttachment.U4] = uvs[6];
|
|
vertices[spine.RegionAttachment.V4] = uvs[7];
|
|
return vertices;
|
|
};
|
|
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma) {
|
|
var skeleton = slot.bone.skeleton;
|
|
var skeletonColor = skeleton.color;
|
|
var slotColor = slot.color;
|
|
var regionColor = mesh.color;
|
|
var alpha = skeletonColor.a * slotColor.a * regionColor.a;
|
|
var multiplier = pma ? alpha : 1;
|
|
var color = this.tempColor;
|
|
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
|
|
var numVertices = mesh.worldVerticesLength / 2;
|
|
if (this.vertices.length < mesh.worldVerticesLength) {
|
|
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
|
|
}
|
|
var vertices = this.vertices;
|
|
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
|
|
var uvs = mesh.uvs;
|
|
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
|
|
vertices[v++] = color.r;
|
|
vertices[v++] = color.g;
|
|
vertices[v++] = color.b;
|
|
vertices[v++] = color.a;
|
|
vertices[v++] = uvs[u++];
|
|
vertices[v++] = uvs[u++];
|
|
v += 2;
|
|
}
|
|
return vertices;
|
|
};
|
|
SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
|
SkeletonRenderer.VERTEX_SIZE = 2 + 2 + 4;
|
|
return SkeletonRenderer;
|
|
}());
|
|
canvas.SkeletonRenderer = SkeletonRenderer;
|
|
})(canvas = spine.canvas || (spine.canvas = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var AssetManager = (function (_super) {
|
|
__extends(AssetManager, _super);
|
|
function AssetManager(context, pathPrefix) {
|
|
if (pathPrefix === void 0) { pathPrefix = ""; }
|
|
return _super.call(this, function (image) {
|
|
return new spine.webgl.GLTexture(context, image);
|
|
}, pathPrefix) || this;
|
|
}
|
|
return AssetManager;
|
|
}(spine.AssetManager));
|
|
webgl.AssetManager = AssetManager;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var OrthoCamera = (function () {
|
|
function OrthoCamera(viewportWidth, viewportHeight) {
|
|
this.position = new webgl.Vector3(0, 0, 0);
|
|
this.direction = new webgl.Vector3(0, 0, -1);
|
|
this.up = new webgl.Vector3(0, 1, 0);
|
|
this.near = 0;
|
|
this.far = 100;
|
|
this.zoom = 1;
|
|
this.viewportWidth = 0;
|
|
this.viewportHeight = 0;
|
|
this.projectionView = new webgl.Matrix4();
|
|
this.inverseProjectionView = new webgl.Matrix4();
|
|
this.projection = new webgl.Matrix4();
|
|
this.view = new webgl.Matrix4();
|
|
this.tmp = new webgl.Vector3();
|
|
this.viewportWidth = viewportWidth;
|
|
this.viewportHeight = viewportHeight;
|
|
this.update();
|
|
}
|
|
OrthoCamera.prototype.update = function () {
|
|
var projection = this.projection;
|
|
var view = this.view;
|
|
var projectionView = this.projectionView;
|
|
var inverseProjectionView = this.inverseProjectionView;
|
|
var zoom = this.zoom, viewportWidth = this.viewportWidth, viewportHeight = this.viewportHeight;
|
|
projection.ortho(zoom * (-viewportWidth / 2), zoom * (viewportWidth / 2), zoom * (-viewportHeight / 2), zoom * (viewportHeight / 2), this.near, this.far);
|
|
view.lookAt(this.position, this.direction, this.up);
|
|
projectionView.set(projection.values);
|
|
projectionView.multiply(view);
|
|
inverseProjectionView.set(projectionView.values).invert();
|
|
};
|
|
OrthoCamera.prototype.screenToWorld = function (screenCoords, screenWidth, screenHeight) {
|
|
var x = screenCoords.x, y = screenHeight - screenCoords.y - 1;
|
|
var tmp = this.tmp;
|
|
tmp.x = (2 * x) / screenWidth - 1;
|
|
tmp.y = (2 * y) / screenHeight - 1;
|
|
tmp.z = (2 * screenCoords.z) - 1;
|
|
tmp.project(this.inverseProjectionView);
|
|
screenCoords.set(tmp.x, tmp.y, tmp.z);
|
|
return screenCoords;
|
|
};
|
|
OrthoCamera.prototype.setViewport = function (viewportWidth, viewportHeight) {
|
|
this.viewportWidth = viewportWidth;
|
|
this.viewportHeight = viewportHeight;
|
|
};
|
|
return OrthoCamera;
|
|
}());
|
|
webgl.OrthoCamera = OrthoCamera;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var GLTexture = (function (_super) {
|
|
__extends(GLTexture, _super);
|
|
function GLTexture(context, image, useMipMaps) {
|
|
if (useMipMaps === void 0) { useMipMaps = false; }
|
|
var _this = _super.call(this, image) || this;
|
|
_this.texture = null;
|
|
_this.boundUnit = 0;
|
|
_this.useMipMaps = false;
|
|
_this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
_this.useMipMaps = useMipMaps;
|
|
_this.restore();
|
|
_this.context.addRestorable(_this);
|
|
return _this;
|
|
}
|
|
GLTexture.prototype.setFilters = function (minFilter, magFilter) {
|
|
var gl = this.context.gl;
|
|
this.bind();
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, GLTexture.validateMagFilter(magFilter));
|
|
};
|
|
GLTexture.validateMagFilter = function (magFilter) {
|
|
switch (magFilter) {
|
|
case spine.TextureFilter.MipMap:
|
|
case spine.TextureFilter.MipMapLinearLinear:
|
|
case spine.TextureFilter.MipMapLinearNearest:
|
|
case spine.TextureFilter.MipMapNearestLinear:
|
|
case spine.TextureFilter.MipMapNearestNearest:
|
|
return spine.TextureFilter.Linear;
|
|
default:
|
|
return magFilter;
|
|
}
|
|
};
|
|
GLTexture.prototype.setWraps = function (uWrap, vWrap) {
|
|
var gl = this.context.gl;
|
|
this.bind();
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
|
|
};
|
|
GLTexture.prototype.update = function (useMipMaps) {
|
|
var gl = this.context.gl;
|
|
if (!this.texture) {
|
|
this.texture = this.context.gl.createTexture();
|
|
}
|
|
this.bind();
|
|
if (GLTexture.DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL)
|
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
if (useMipMaps)
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
};
|
|
GLTexture.prototype.restore = function () {
|
|
this.texture = null;
|
|
this.update(this.useMipMaps);
|
|
};
|
|
GLTexture.prototype.bind = function (unit) {
|
|
if (unit === void 0) { unit = 0; }
|
|
var gl = this.context.gl;
|
|
this.boundUnit = unit;
|
|
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
gl.bindTexture(gl.TEXTURE_2D, this.texture);
|
|
};
|
|
GLTexture.prototype.unbind = function () {
|
|
var gl = this.context.gl;
|
|
gl.activeTexture(gl.TEXTURE0 + this.boundUnit);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
};
|
|
GLTexture.prototype.dispose = function () {
|
|
this.context.removeRestorable(this);
|
|
var gl = this.context.gl;
|
|
gl.deleteTexture(this.texture);
|
|
};
|
|
GLTexture.DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL = false;
|
|
return GLTexture;
|
|
}(spine.Texture));
|
|
webgl.GLTexture = GLTexture;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
webgl.M00 = 0;
|
|
webgl.M01 = 4;
|
|
webgl.M02 = 8;
|
|
webgl.M03 = 12;
|
|
webgl.M10 = 1;
|
|
webgl.M11 = 5;
|
|
webgl.M12 = 9;
|
|
webgl.M13 = 13;
|
|
webgl.M20 = 2;
|
|
webgl.M21 = 6;
|
|
webgl.M22 = 10;
|
|
webgl.M23 = 14;
|
|
webgl.M30 = 3;
|
|
webgl.M31 = 7;
|
|
webgl.M32 = 11;
|
|
webgl.M33 = 15;
|
|
var Matrix4 = (function () {
|
|
function Matrix4() {
|
|
this.temp = new Float32Array(16);
|
|
this.values = new Float32Array(16);
|
|
var v = this.values;
|
|
v[webgl.M00] = 1;
|
|
v[webgl.M11] = 1;
|
|
v[webgl.M22] = 1;
|
|
v[webgl.M33] = 1;
|
|
}
|
|
Matrix4.prototype.set = function (values) {
|
|
this.values.set(values);
|
|
return this;
|
|
};
|
|
Matrix4.prototype.transpose = function () {
|
|
var t = this.temp;
|
|
var v = this.values;
|
|
t[webgl.M00] = v[webgl.M00];
|
|
t[webgl.M01] = v[webgl.M10];
|
|
t[webgl.M02] = v[webgl.M20];
|
|
t[webgl.M03] = v[webgl.M30];
|
|
t[webgl.M10] = v[webgl.M01];
|
|
t[webgl.M11] = v[webgl.M11];
|
|
t[webgl.M12] = v[webgl.M21];
|
|
t[webgl.M13] = v[webgl.M31];
|
|
t[webgl.M20] = v[webgl.M02];
|
|
t[webgl.M21] = v[webgl.M12];
|
|
t[webgl.M22] = v[webgl.M22];
|
|
t[webgl.M23] = v[webgl.M32];
|
|
t[webgl.M30] = v[webgl.M03];
|
|
t[webgl.M31] = v[webgl.M13];
|
|
t[webgl.M32] = v[webgl.M23];
|
|
t[webgl.M33] = v[webgl.M33];
|
|
return this.set(t);
|
|
};
|
|
Matrix4.prototype.identity = function () {
|
|
var v = this.values;
|
|
v[webgl.M00] = 1;
|
|
v[webgl.M01] = 0;
|
|
v[webgl.M02] = 0;
|
|
v[webgl.M03] = 0;
|
|
v[webgl.M10] = 0;
|
|
v[webgl.M11] = 1;
|
|
v[webgl.M12] = 0;
|
|
v[webgl.M13] = 0;
|
|
v[webgl.M20] = 0;
|
|
v[webgl.M21] = 0;
|
|
v[webgl.M22] = 1;
|
|
v[webgl.M23] = 0;
|
|
v[webgl.M30] = 0;
|
|
v[webgl.M31] = 0;
|
|
v[webgl.M32] = 0;
|
|
v[webgl.M33] = 1;
|
|
return this;
|
|
};
|
|
Matrix4.prototype.invert = function () {
|
|
var v = this.values;
|
|
var t = this.temp;
|
|
var l_det = v[webgl.M30] * v[webgl.M21] * v[webgl.M12] * v[webgl.M03] - v[webgl.M20] * v[webgl.M31] * v[webgl.M12] * v[webgl.M03] - v[webgl.M30] * v[webgl.M11] * v[webgl.M22] * v[webgl.M03]
|
|
+ v[webgl.M10] * v[webgl.M31] * v[webgl.M22] * v[webgl.M03] + v[webgl.M20] * v[webgl.M11] * v[webgl.M32] * v[webgl.M03] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32] * v[webgl.M03]
|
|
- v[webgl.M30] * v[webgl.M21] * v[webgl.M02] * v[webgl.M13] + v[webgl.M20] * v[webgl.M31] * v[webgl.M02] * v[webgl.M13] + v[webgl.M30] * v[webgl.M01] * v[webgl.M22] * v[webgl.M13]
|
|
- v[webgl.M00] * v[webgl.M31] * v[webgl.M22] * v[webgl.M13] - v[webgl.M20] * v[webgl.M01] * v[webgl.M32] * v[webgl.M13] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32] * v[webgl.M13]
|
|
+ v[webgl.M30] * v[webgl.M11] * v[webgl.M02] * v[webgl.M23] - v[webgl.M10] * v[webgl.M31] * v[webgl.M02] * v[webgl.M23] - v[webgl.M30] * v[webgl.M01] * v[webgl.M12] * v[webgl.M23]
|
|
+ v[webgl.M00] * v[webgl.M31] * v[webgl.M12] * v[webgl.M23] + v[webgl.M10] * v[webgl.M01] * v[webgl.M32] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32] * v[webgl.M23]
|
|
- v[webgl.M20] * v[webgl.M11] * v[webgl.M02] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M02] * v[webgl.M33] + v[webgl.M20] * v[webgl.M01] * v[webgl.M12] * v[webgl.M33]
|
|
- v[webgl.M00] * v[webgl.M21] * v[webgl.M12] * v[webgl.M33] - v[webgl.M10] * v[webgl.M01] * v[webgl.M22] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
|
|
if (l_det == 0)
|
|
throw new Error("non-invertible matrix");
|
|
var inv_det = 1.0 / l_det;
|
|
t[webgl.M00] = v[webgl.M12] * v[webgl.M23] * v[webgl.M31] - v[webgl.M13] * v[webgl.M22] * v[webgl.M31] + v[webgl.M13] * v[webgl.M21] * v[webgl.M32]
|
|
- v[webgl.M11] * v[webgl.M23] * v[webgl.M32] - v[webgl.M12] * v[webgl.M21] * v[webgl.M33] + v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
|
|
t[webgl.M01] = v[webgl.M03] * v[webgl.M22] * v[webgl.M31] - v[webgl.M02] * v[webgl.M23] * v[webgl.M31] - v[webgl.M03] * v[webgl.M21] * v[webgl.M32]
|
|
+ v[webgl.M01] * v[webgl.M23] * v[webgl.M32] + v[webgl.M02] * v[webgl.M21] * v[webgl.M33] - v[webgl.M01] * v[webgl.M22] * v[webgl.M33];
|
|
t[webgl.M02] = v[webgl.M02] * v[webgl.M13] * v[webgl.M31] - v[webgl.M03] * v[webgl.M12] * v[webgl.M31] + v[webgl.M03] * v[webgl.M11] * v[webgl.M32]
|
|
- v[webgl.M01] * v[webgl.M13] * v[webgl.M32] - v[webgl.M02] * v[webgl.M11] * v[webgl.M33] + v[webgl.M01] * v[webgl.M12] * v[webgl.M33];
|
|
t[webgl.M03] = v[webgl.M03] * v[webgl.M12] * v[webgl.M21] - v[webgl.M02] * v[webgl.M13] * v[webgl.M21] - v[webgl.M03] * v[webgl.M11] * v[webgl.M22]
|
|
+ v[webgl.M01] * v[webgl.M13] * v[webgl.M22] + v[webgl.M02] * v[webgl.M11] * v[webgl.M23] - v[webgl.M01] * v[webgl.M12] * v[webgl.M23];
|
|
t[webgl.M10] = v[webgl.M13] * v[webgl.M22] * v[webgl.M30] - v[webgl.M12] * v[webgl.M23] * v[webgl.M30] - v[webgl.M13] * v[webgl.M20] * v[webgl.M32]
|
|
+ v[webgl.M10] * v[webgl.M23] * v[webgl.M32] + v[webgl.M12] * v[webgl.M20] * v[webgl.M33] - v[webgl.M10] * v[webgl.M22] * v[webgl.M33];
|
|
t[webgl.M11] = v[webgl.M02] * v[webgl.M23] * v[webgl.M30] - v[webgl.M03] * v[webgl.M22] * v[webgl.M30] + v[webgl.M03] * v[webgl.M20] * v[webgl.M32]
|
|
- v[webgl.M00] * v[webgl.M23] * v[webgl.M32] - v[webgl.M02] * v[webgl.M20] * v[webgl.M33] + v[webgl.M00] * v[webgl.M22] * v[webgl.M33];
|
|
t[webgl.M12] = v[webgl.M03] * v[webgl.M12] * v[webgl.M30] - v[webgl.M02] * v[webgl.M13] * v[webgl.M30] - v[webgl.M03] * v[webgl.M10] * v[webgl.M32]
|
|
+ v[webgl.M00] * v[webgl.M13] * v[webgl.M32] + v[webgl.M02] * v[webgl.M10] * v[webgl.M33] - v[webgl.M00] * v[webgl.M12] * v[webgl.M33];
|
|
t[webgl.M13] = v[webgl.M02] * v[webgl.M13] * v[webgl.M20] - v[webgl.M03] * v[webgl.M12] * v[webgl.M20] + v[webgl.M03] * v[webgl.M10] * v[webgl.M22]
|
|
- v[webgl.M00] * v[webgl.M13] * v[webgl.M22] - v[webgl.M02] * v[webgl.M10] * v[webgl.M23] + v[webgl.M00] * v[webgl.M12] * v[webgl.M23];
|
|
t[webgl.M20] = v[webgl.M11] * v[webgl.M23] * v[webgl.M30] - v[webgl.M13] * v[webgl.M21] * v[webgl.M30] + v[webgl.M13] * v[webgl.M20] * v[webgl.M31]
|
|
- v[webgl.M10] * v[webgl.M23] * v[webgl.M31] - v[webgl.M11] * v[webgl.M20] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M33];
|
|
t[webgl.M21] = v[webgl.M03] * v[webgl.M21] * v[webgl.M30] - v[webgl.M01] * v[webgl.M23] * v[webgl.M30] - v[webgl.M03] * v[webgl.M20] * v[webgl.M31]
|
|
+ v[webgl.M00] * v[webgl.M23] * v[webgl.M31] + v[webgl.M01] * v[webgl.M20] * v[webgl.M33] - v[webgl.M00] * v[webgl.M21] * v[webgl.M33];
|
|
t[webgl.M22] = v[webgl.M01] * v[webgl.M13] * v[webgl.M30] - v[webgl.M03] * v[webgl.M11] * v[webgl.M30] + v[webgl.M03] * v[webgl.M10] * v[webgl.M31]
|
|
- v[webgl.M00] * v[webgl.M13] * v[webgl.M31] - v[webgl.M01] * v[webgl.M10] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M33];
|
|
t[webgl.M23] = v[webgl.M03] * v[webgl.M11] * v[webgl.M20] - v[webgl.M01] * v[webgl.M13] * v[webgl.M20] - v[webgl.M03] * v[webgl.M10] * v[webgl.M21]
|
|
+ v[webgl.M00] * v[webgl.M13] * v[webgl.M21] + v[webgl.M01] * v[webgl.M10] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M23];
|
|
t[webgl.M30] = v[webgl.M12] * v[webgl.M21] * v[webgl.M30] - v[webgl.M11] * v[webgl.M22] * v[webgl.M30] - v[webgl.M12] * v[webgl.M20] * v[webgl.M31]
|
|
+ v[webgl.M10] * v[webgl.M22] * v[webgl.M31] + v[webgl.M11] * v[webgl.M20] * v[webgl.M32] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32];
|
|
t[webgl.M31] = v[webgl.M01] * v[webgl.M22] * v[webgl.M30] - v[webgl.M02] * v[webgl.M21] * v[webgl.M30] + v[webgl.M02] * v[webgl.M20] * v[webgl.M31]
|
|
- v[webgl.M00] * v[webgl.M22] * v[webgl.M31] - v[webgl.M01] * v[webgl.M20] * v[webgl.M32] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32];
|
|
t[webgl.M32] = v[webgl.M02] * v[webgl.M11] * v[webgl.M30] - v[webgl.M01] * v[webgl.M12] * v[webgl.M30] - v[webgl.M02] * v[webgl.M10] * v[webgl.M31]
|
|
+ v[webgl.M00] * v[webgl.M12] * v[webgl.M31] + v[webgl.M01] * v[webgl.M10] * v[webgl.M32] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32];
|
|
t[webgl.M33] = v[webgl.M01] * v[webgl.M12] * v[webgl.M20] - v[webgl.M02] * v[webgl.M11] * v[webgl.M20] + v[webgl.M02] * v[webgl.M10] * v[webgl.M21]
|
|
- v[webgl.M00] * v[webgl.M12] * v[webgl.M21] - v[webgl.M01] * v[webgl.M10] * v[webgl.M22] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22];
|
|
v[webgl.M00] = t[webgl.M00] * inv_det;
|
|
v[webgl.M01] = t[webgl.M01] * inv_det;
|
|
v[webgl.M02] = t[webgl.M02] * inv_det;
|
|
v[webgl.M03] = t[webgl.M03] * inv_det;
|
|
v[webgl.M10] = t[webgl.M10] * inv_det;
|
|
v[webgl.M11] = t[webgl.M11] * inv_det;
|
|
v[webgl.M12] = t[webgl.M12] * inv_det;
|
|
v[webgl.M13] = t[webgl.M13] * inv_det;
|
|
v[webgl.M20] = t[webgl.M20] * inv_det;
|
|
v[webgl.M21] = t[webgl.M21] * inv_det;
|
|
v[webgl.M22] = t[webgl.M22] * inv_det;
|
|
v[webgl.M23] = t[webgl.M23] * inv_det;
|
|
v[webgl.M30] = t[webgl.M30] * inv_det;
|
|
v[webgl.M31] = t[webgl.M31] * inv_det;
|
|
v[webgl.M32] = t[webgl.M32] * inv_det;
|
|
v[webgl.M33] = t[webgl.M33] * inv_det;
|
|
return this;
|
|
};
|
|
Matrix4.prototype.determinant = function () {
|
|
var v = this.values;
|
|
return v[webgl.M30] * v[webgl.M21] * v[webgl.M12] * v[webgl.M03] - v[webgl.M20] * v[webgl.M31] * v[webgl.M12] * v[webgl.M03] - v[webgl.M30] * v[webgl.M11] * v[webgl.M22] * v[webgl.M03]
|
|
+ v[webgl.M10] * v[webgl.M31] * v[webgl.M22] * v[webgl.M03] + v[webgl.M20] * v[webgl.M11] * v[webgl.M32] * v[webgl.M03] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32] * v[webgl.M03]
|
|
- v[webgl.M30] * v[webgl.M21] * v[webgl.M02] * v[webgl.M13] + v[webgl.M20] * v[webgl.M31] * v[webgl.M02] * v[webgl.M13] + v[webgl.M30] * v[webgl.M01] * v[webgl.M22] * v[webgl.M13]
|
|
- v[webgl.M00] * v[webgl.M31] * v[webgl.M22] * v[webgl.M13] - v[webgl.M20] * v[webgl.M01] * v[webgl.M32] * v[webgl.M13] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32] * v[webgl.M13]
|
|
+ v[webgl.M30] * v[webgl.M11] * v[webgl.M02] * v[webgl.M23] - v[webgl.M10] * v[webgl.M31] * v[webgl.M02] * v[webgl.M23] - v[webgl.M30] * v[webgl.M01] * v[webgl.M12] * v[webgl.M23]
|
|
+ v[webgl.M00] * v[webgl.M31] * v[webgl.M12] * v[webgl.M23] + v[webgl.M10] * v[webgl.M01] * v[webgl.M32] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32] * v[webgl.M23]
|
|
- v[webgl.M20] * v[webgl.M11] * v[webgl.M02] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M02] * v[webgl.M33] + v[webgl.M20] * v[webgl.M01] * v[webgl.M12] * v[webgl.M33]
|
|
- v[webgl.M00] * v[webgl.M21] * v[webgl.M12] * v[webgl.M33] - v[webgl.M10] * v[webgl.M01] * v[webgl.M22] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
|
|
};
|
|
Matrix4.prototype.translate = function (x, y, z) {
|
|
var v = this.values;
|
|
v[webgl.M03] += x;
|
|
v[webgl.M13] += y;
|
|
v[webgl.M23] += z;
|
|
return this;
|
|
};
|
|
Matrix4.prototype.copy = function () {
|
|
return new Matrix4().set(this.values);
|
|
};
|
|
Matrix4.prototype.projection = function (near, far, fovy, aspectRatio) {
|
|
this.identity();
|
|
var l_fd = (1.0 / Math.tan((fovy * (Math.PI / 180)) / 2.0));
|
|
var l_a1 = (far + near) / (near - far);
|
|
var l_a2 = (2 * far * near) / (near - far);
|
|
var v = this.values;
|
|
v[webgl.M00] = l_fd / aspectRatio;
|
|
v[webgl.M10] = 0;
|
|
v[webgl.M20] = 0;
|
|
v[webgl.M30] = 0;
|
|
v[webgl.M01] = 0;
|
|
v[webgl.M11] = l_fd;
|
|
v[webgl.M21] = 0;
|
|
v[webgl.M31] = 0;
|
|
v[webgl.M02] = 0;
|
|
v[webgl.M12] = 0;
|
|
v[webgl.M22] = l_a1;
|
|
v[webgl.M32] = -1;
|
|
v[webgl.M03] = 0;
|
|
v[webgl.M13] = 0;
|
|
v[webgl.M23] = l_a2;
|
|
v[webgl.M33] = 0;
|
|
return this;
|
|
};
|
|
Matrix4.prototype.ortho2d = function (x, y, width, height) {
|
|
return this.ortho(x, x + width, y, y + height, 0, 1);
|
|
};
|
|
Matrix4.prototype.ortho = function (left, right, bottom, top, near, far) {
|
|
this.identity();
|
|
var x_orth = 2 / (right - left);
|
|
var y_orth = 2 / (top - bottom);
|
|
var z_orth = -2 / (far - near);
|
|
var tx = -(right + left) / (right - left);
|
|
var ty = -(top + bottom) / (top - bottom);
|
|
var tz = -(far + near) / (far - near);
|
|
var v = this.values;
|
|
v[webgl.M00] = x_orth;
|
|
v[webgl.M10] = 0;
|
|
v[webgl.M20] = 0;
|
|
v[webgl.M30] = 0;
|
|
v[webgl.M01] = 0;
|
|
v[webgl.M11] = y_orth;
|
|
v[webgl.M21] = 0;
|
|
v[webgl.M31] = 0;
|
|
v[webgl.M02] = 0;
|
|
v[webgl.M12] = 0;
|
|
v[webgl.M22] = z_orth;
|
|
v[webgl.M32] = 0;
|
|
v[webgl.M03] = tx;
|
|
v[webgl.M13] = ty;
|
|
v[webgl.M23] = tz;
|
|
v[webgl.M33] = 1;
|
|
return this;
|
|
};
|
|
Matrix4.prototype.multiply = function (matrix) {
|
|
var t = this.temp;
|
|
var v = this.values;
|
|
var m = matrix.values;
|
|
t[webgl.M00] = v[webgl.M00] * m[webgl.M00] + v[webgl.M01] * m[webgl.M10] + v[webgl.M02] * m[webgl.M20] + v[webgl.M03] * m[webgl.M30];
|
|
t[webgl.M01] = v[webgl.M00] * m[webgl.M01] + v[webgl.M01] * m[webgl.M11] + v[webgl.M02] * m[webgl.M21] + v[webgl.M03] * m[webgl.M31];
|
|
t[webgl.M02] = v[webgl.M00] * m[webgl.M02] + v[webgl.M01] * m[webgl.M12] + v[webgl.M02] * m[webgl.M22] + v[webgl.M03] * m[webgl.M32];
|
|
t[webgl.M03] = v[webgl.M00] * m[webgl.M03] + v[webgl.M01] * m[webgl.M13] + v[webgl.M02] * m[webgl.M23] + v[webgl.M03] * m[webgl.M33];
|
|
t[webgl.M10] = v[webgl.M10] * m[webgl.M00] + v[webgl.M11] * m[webgl.M10] + v[webgl.M12] * m[webgl.M20] + v[webgl.M13] * m[webgl.M30];
|
|
t[webgl.M11] = v[webgl.M10] * m[webgl.M01] + v[webgl.M11] * m[webgl.M11] + v[webgl.M12] * m[webgl.M21] + v[webgl.M13] * m[webgl.M31];
|
|
t[webgl.M12] = v[webgl.M10] * m[webgl.M02] + v[webgl.M11] * m[webgl.M12] + v[webgl.M12] * m[webgl.M22] + v[webgl.M13] * m[webgl.M32];
|
|
t[webgl.M13] = v[webgl.M10] * m[webgl.M03] + v[webgl.M11] * m[webgl.M13] + v[webgl.M12] * m[webgl.M23] + v[webgl.M13] * m[webgl.M33];
|
|
t[webgl.M20] = v[webgl.M20] * m[webgl.M00] + v[webgl.M21] * m[webgl.M10] + v[webgl.M22] * m[webgl.M20] + v[webgl.M23] * m[webgl.M30];
|
|
t[webgl.M21] = v[webgl.M20] * m[webgl.M01] + v[webgl.M21] * m[webgl.M11] + v[webgl.M22] * m[webgl.M21] + v[webgl.M23] * m[webgl.M31];
|
|
t[webgl.M22] = v[webgl.M20] * m[webgl.M02] + v[webgl.M21] * m[webgl.M12] + v[webgl.M22] * m[webgl.M22] + v[webgl.M23] * m[webgl.M32];
|
|
t[webgl.M23] = v[webgl.M20] * m[webgl.M03] + v[webgl.M21] * m[webgl.M13] + v[webgl.M22] * m[webgl.M23] + v[webgl.M23] * m[webgl.M33];
|
|
t[webgl.M30] = v[webgl.M30] * m[webgl.M00] + v[webgl.M31] * m[webgl.M10] + v[webgl.M32] * m[webgl.M20] + v[webgl.M33] * m[webgl.M30];
|
|
t[webgl.M31] = v[webgl.M30] * m[webgl.M01] + v[webgl.M31] * m[webgl.M11] + v[webgl.M32] * m[webgl.M21] + v[webgl.M33] * m[webgl.M31];
|
|
t[webgl.M32] = v[webgl.M30] * m[webgl.M02] + v[webgl.M31] * m[webgl.M12] + v[webgl.M32] * m[webgl.M22] + v[webgl.M33] * m[webgl.M32];
|
|
t[webgl.M33] = v[webgl.M30] * m[webgl.M03] + v[webgl.M31] * m[webgl.M13] + v[webgl.M32] * m[webgl.M23] + v[webgl.M33] * m[webgl.M33];
|
|
return this.set(this.temp);
|
|
};
|
|
Matrix4.prototype.multiplyLeft = function (matrix) {
|
|
var t = this.temp;
|
|
var v = this.values;
|
|
var m = matrix.values;
|
|
t[webgl.M00] = m[webgl.M00] * v[webgl.M00] + m[webgl.M01] * v[webgl.M10] + m[webgl.M02] * v[webgl.M20] + m[webgl.M03] * v[webgl.M30];
|
|
t[webgl.M01] = m[webgl.M00] * v[webgl.M01] + m[webgl.M01] * v[webgl.M11] + m[webgl.M02] * v[webgl.M21] + m[webgl.M03] * v[webgl.M31];
|
|
t[webgl.M02] = m[webgl.M00] * v[webgl.M02] + m[webgl.M01] * v[webgl.M12] + m[webgl.M02] * v[webgl.M22] + m[webgl.M03] * v[webgl.M32];
|
|
t[webgl.M03] = m[webgl.M00] * v[webgl.M03] + m[webgl.M01] * v[webgl.M13] + m[webgl.M02] * v[webgl.M23] + m[webgl.M03] * v[webgl.M33];
|
|
t[webgl.M10] = m[webgl.M10] * v[webgl.M00] + m[webgl.M11] * v[webgl.M10] + m[webgl.M12] * v[webgl.M20] + m[webgl.M13] * v[webgl.M30];
|
|
t[webgl.M11] = m[webgl.M10] * v[webgl.M01] + m[webgl.M11] * v[webgl.M11] + m[webgl.M12] * v[webgl.M21] + m[webgl.M13] * v[webgl.M31];
|
|
t[webgl.M12] = m[webgl.M10] * v[webgl.M02] + m[webgl.M11] * v[webgl.M12] + m[webgl.M12] * v[webgl.M22] + m[webgl.M13] * v[webgl.M32];
|
|
t[webgl.M13] = m[webgl.M10] * v[webgl.M03] + m[webgl.M11] * v[webgl.M13] + m[webgl.M12] * v[webgl.M23] + m[webgl.M13] * v[webgl.M33];
|
|
t[webgl.M20] = m[webgl.M20] * v[webgl.M00] + m[webgl.M21] * v[webgl.M10] + m[webgl.M22] * v[webgl.M20] + m[webgl.M23] * v[webgl.M30];
|
|
t[webgl.M21] = m[webgl.M20] * v[webgl.M01] + m[webgl.M21] * v[webgl.M11] + m[webgl.M22] * v[webgl.M21] + m[webgl.M23] * v[webgl.M31];
|
|
t[webgl.M22] = m[webgl.M20] * v[webgl.M02] + m[webgl.M21] * v[webgl.M12] + m[webgl.M22] * v[webgl.M22] + m[webgl.M23] * v[webgl.M32];
|
|
t[webgl.M23] = m[webgl.M20] * v[webgl.M03] + m[webgl.M21] * v[webgl.M13] + m[webgl.M22] * v[webgl.M23] + m[webgl.M23] * v[webgl.M33];
|
|
t[webgl.M30] = m[webgl.M30] * v[webgl.M00] + m[webgl.M31] * v[webgl.M10] + m[webgl.M32] * v[webgl.M20] + m[webgl.M33] * v[webgl.M30];
|
|
t[webgl.M31] = m[webgl.M30] * v[webgl.M01] + m[webgl.M31] * v[webgl.M11] + m[webgl.M32] * v[webgl.M21] + m[webgl.M33] * v[webgl.M31];
|
|
t[webgl.M32] = m[webgl.M30] * v[webgl.M02] + m[webgl.M31] * v[webgl.M12] + m[webgl.M32] * v[webgl.M22] + m[webgl.M33] * v[webgl.M32];
|
|
t[webgl.M33] = m[webgl.M30] * v[webgl.M03] + m[webgl.M31] * v[webgl.M13] + m[webgl.M32] * v[webgl.M23] + m[webgl.M33] * v[webgl.M33];
|
|
return this.set(this.temp);
|
|
};
|
|
Matrix4.prototype.lookAt = function (position, direction, up) {
|
|
Matrix4.initTemps();
|
|
var xAxis = Matrix4.xAxis, yAxis = Matrix4.yAxis, zAxis = Matrix4.zAxis;
|
|
zAxis.setFrom(direction).normalize();
|
|
xAxis.setFrom(direction).normalize();
|
|
xAxis.cross(up).normalize();
|
|
yAxis.setFrom(xAxis).cross(zAxis).normalize();
|
|
this.identity();
|
|
var val = this.values;
|
|
val[webgl.M00] = xAxis.x;
|
|
val[webgl.M01] = xAxis.y;
|
|
val[webgl.M02] = xAxis.z;
|
|
val[webgl.M10] = yAxis.x;
|
|
val[webgl.M11] = yAxis.y;
|
|
val[webgl.M12] = yAxis.z;
|
|
val[webgl.M20] = -zAxis.x;
|
|
val[webgl.M21] = -zAxis.y;
|
|
val[webgl.M22] = -zAxis.z;
|
|
Matrix4.tmpMatrix.identity();
|
|
Matrix4.tmpMatrix.values[webgl.M03] = -position.x;
|
|
Matrix4.tmpMatrix.values[webgl.M13] = -position.y;
|
|
Matrix4.tmpMatrix.values[webgl.M23] = -position.z;
|
|
this.multiply(Matrix4.tmpMatrix);
|
|
return this;
|
|
};
|
|
Matrix4.initTemps = function () {
|
|
if (Matrix4.xAxis === null)
|
|
Matrix4.xAxis = new webgl.Vector3();
|
|
if (Matrix4.yAxis === null)
|
|
Matrix4.yAxis = new webgl.Vector3();
|
|
if (Matrix4.zAxis === null)
|
|
Matrix4.zAxis = new webgl.Vector3();
|
|
};
|
|
Matrix4.xAxis = null;
|
|
Matrix4.yAxis = null;
|
|
Matrix4.zAxis = null;
|
|
Matrix4.tmpMatrix = new Matrix4();
|
|
return Matrix4;
|
|
}());
|
|
webgl.Matrix4 = Matrix4;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var Mesh = (function () {
|
|
function Mesh(context, attributes, maxVertices, maxIndices) {
|
|
this.attributes = attributes;
|
|
this.verticesLength = 0;
|
|
this.dirtyVertices = false;
|
|
this.indicesLength = 0;
|
|
this.dirtyIndices = false;
|
|
this.elementsPerVertex = 0;
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
this.elementsPerVertex = 0;
|
|
for (var i = 0; i < attributes.length; i++) {
|
|
this.elementsPerVertex += attributes[i].numElements;
|
|
}
|
|
this.vertices = new Float32Array(maxVertices * this.elementsPerVertex);
|
|
this.indices = new Uint16Array(maxIndices);
|
|
this.context.addRestorable(this);
|
|
}
|
|
Mesh.prototype.getAttributes = function () { return this.attributes; };
|
|
Mesh.prototype.maxVertices = function () { return this.vertices.length / this.elementsPerVertex; };
|
|
Mesh.prototype.numVertices = function () { return this.verticesLength / this.elementsPerVertex; };
|
|
Mesh.prototype.setVerticesLength = function (length) {
|
|
this.dirtyVertices = true;
|
|
this.verticesLength = length;
|
|
};
|
|
Mesh.prototype.getVertices = function () { return this.vertices; };
|
|
Mesh.prototype.maxIndices = function () { return this.indices.length; };
|
|
Mesh.prototype.numIndices = function () { return this.indicesLength; };
|
|
Mesh.prototype.setIndicesLength = function (length) {
|
|
this.dirtyIndices = true;
|
|
this.indicesLength = length;
|
|
};
|
|
Mesh.prototype.getIndices = function () { return this.indices; };
|
|
;
|
|
Mesh.prototype.getVertexSizeInFloats = function () {
|
|
var size = 0;
|
|
for (var i = 0; i < this.attributes.length; i++) {
|
|
var attribute = this.attributes[i];
|
|
size += attribute.numElements;
|
|
}
|
|
return size;
|
|
};
|
|
Mesh.prototype.setVertices = function (vertices) {
|
|
this.dirtyVertices = true;
|
|
if (vertices.length > this.vertices.length)
|
|
throw Error("Mesh can't store more than " + this.maxVertices() + " vertices");
|
|
this.vertices.set(vertices, 0);
|
|
this.verticesLength = vertices.length;
|
|
};
|
|
Mesh.prototype.setIndices = function (indices) {
|
|
this.dirtyIndices = true;
|
|
if (indices.length > this.indices.length)
|
|
throw Error("Mesh can't store more than " + this.maxIndices() + " indices");
|
|
this.indices.set(indices, 0);
|
|
this.indicesLength = indices.length;
|
|
};
|
|
Mesh.prototype.draw = function (shader, primitiveType) {
|
|
this.drawWithOffset(shader, primitiveType, 0, this.indicesLength > 0 ? this.indicesLength : this.verticesLength / this.elementsPerVertex);
|
|
};
|
|
Mesh.prototype.drawWithOffset = function (shader, primitiveType, offset, count) {
|
|
var gl = this.context.gl;
|
|
if (this.dirtyVertices || this.dirtyIndices)
|
|
this.update();
|
|
this.bind(shader);
|
|
if (this.indicesLength > 0) {
|
|
gl.drawElements(primitiveType, count, gl.UNSIGNED_SHORT, offset * 2);
|
|
}
|
|
else {
|
|
gl.drawArrays(primitiveType, offset, count);
|
|
}
|
|
this.unbind(shader);
|
|
};
|
|
Mesh.prototype.bind = function (shader) {
|
|
var gl = this.context.gl;
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
|
|
var offset = 0;
|
|
for (var i = 0; i < this.attributes.length; i++) {
|
|
var attrib = this.attributes[i];
|
|
var location_1 = shader.getAttributeLocation(attrib.name);
|
|
gl.enableVertexAttribArray(location_1);
|
|
gl.vertexAttribPointer(location_1, attrib.numElements, gl.FLOAT, false, this.elementsPerVertex * 4, offset * 4);
|
|
offset += attrib.numElements;
|
|
}
|
|
if (this.indicesLength > 0)
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
|
};
|
|
Mesh.prototype.unbind = function (shader) {
|
|
var gl = this.context.gl;
|
|
for (var i = 0; i < this.attributes.length; i++) {
|
|
var attrib = this.attributes[i];
|
|
var location_2 = shader.getAttributeLocation(attrib.name);
|
|
gl.disableVertexAttribArray(location_2);
|
|
}
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
if (this.indicesLength > 0)
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
|
};
|
|
Mesh.prototype.update = function () {
|
|
var gl = this.context.gl;
|
|
if (this.dirtyVertices) {
|
|
if (!this.verticesBuffer) {
|
|
this.verticesBuffer = gl.createBuffer();
|
|
}
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
|
|
this.dirtyVertices = false;
|
|
}
|
|
if (this.dirtyIndices) {
|
|
if (!this.indicesBuffer) {
|
|
this.indicesBuffer = gl.createBuffer();
|
|
}
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
|
|
this.dirtyIndices = false;
|
|
}
|
|
};
|
|
Mesh.prototype.restore = function () {
|
|
this.verticesBuffer = null;
|
|
this.indicesBuffer = null;
|
|
this.update();
|
|
};
|
|
Mesh.prototype.dispose = function () {
|
|
this.context.removeRestorable(this);
|
|
var gl = this.context.gl;
|
|
gl.deleteBuffer(this.verticesBuffer);
|
|
gl.deleteBuffer(this.indicesBuffer);
|
|
};
|
|
return Mesh;
|
|
}());
|
|
webgl.Mesh = Mesh;
|
|
var VertexAttribute = (function () {
|
|
function VertexAttribute(name, type, numElements) {
|
|
this.name = name;
|
|
this.type = type;
|
|
this.numElements = numElements;
|
|
}
|
|
return VertexAttribute;
|
|
}());
|
|
webgl.VertexAttribute = VertexAttribute;
|
|
var Position2Attribute = (function (_super) {
|
|
__extends(Position2Attribute, _super);
|
|
function Position2Attribute() {
|
|
return _super.call(this, webgl.Shader.POSITION, VertexAttributeType.Float, 2) || this;
|
|
}
|
|
return Position2Attribute;
|
|
}(VertexAttribute));
|
|
webgl.Position2Attribute = Position2Attribute;
|
|
var Position3Attribute = (function (_super) {
|
|
__extends(Position3Attribute, _super);
|
|
function Position3Attribute() {
|
|
return _super.call(this, webgl.Shader.POSITION, VertexAttributeType.Float, 3) || this;
|
|
}
|
|
return Position3Attribute;
|
|
}(VertexAttribute));
|
|
webgl.Position3Attribute = Position3Attribute;
|
|
var TexCoordAttribute = (function (_super) {
|
|
__extends(TexCoordAttribute, _super);
|
|
function TexCoordAttribute(unit) {
|
|
if (unit === void 0) { unit = 0; }
|
|
return _super.call(this, webgl.Shader.TEXCOORDS + (unit == 0 ? "" : unit), VertexAttributeType.Float, 2) || this;
|
|
}
|
|
return TexCoordAttribute;
|
|
}(VertexAttribute));
|
|
webgl.TexCoordAttribute = TexCoordAttribute;
|
|
var ColorAttribute = (function (_super) {
|
|
__extends(ColorAttribute, _super);
|
|
function ColorAttribute() {
|
|
return _super.call(this, webgl.Shader.COLOR, VertexAttributeType.Float, 4) || this;
|
|
}
|
|
return ColorAttribute;
|
|
}(VertexAttribute));
|
|
webgl.ColorAttribute = ColorAttribute;
|
|
var Color2Attribute = (function (_super) {
|
|
__extends(Color2Attribute, _super);
|
|
function Color2Attribute() {
|
|
return _super.call(this, webgl.Shader.COLOR2, VertexAttributeType.Float, 4) || this;
|
|
}
|
|
return Color2Attribute;
|
|
}(VertexAttribute));
|
|
webgl.Color2Attribute = Color2Attribute;
|
|
var VertexAttributeType;
|
|
(function (VertexAttributeType) {
|
|
VertexAttributeType[VertexAttributeType["Float"] = 0] = "Float";
|
|
})(VertexAttributeType = webgl.VertexAttributeType || (webgl.VertexAttributeType = {}));
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var PolygonBatcher = (function () {
|
|
function PolygonBatcher(context, twoColorTint, maxVertices) {
|
|
if (twoColorTint === void 0) { twoColorTint = true; }
|
|
if (maxVertices === void 0) { maxVertices = 10920; }
|
|
this.isDrawing = false;
|
|
this.shader = null;
|
|
this.lastTexture = null;
|
|
this.verticesLength = 0;
|
|
this.indicesLength = 0;
|
|
if (maxVertices > 10920)
|
|
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
var attributes = twoColorTint ?
|
|
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute(), new webgl.Color2Attribute()] :
|
|
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()];
|
|
this.mesh = new webgl.Mesh(context, attributes, maxVertices, maxVertices * 3);
|
|
this.srcBlend = this.context.gl.SRC_ALPHA;
|
|
this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA;
|
|
}
|
|
PolygonBatcher.prototype.begin = function (shader) {
|
|
var gl = this.context.gl;
|
|
if (this.isDrawing)
|
|
throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()");
|
|
this.drawCalls = 0;
|
|
this.shader = shader;
|
|
this.lastTexture = null;
|
|
this.isDrawing = true;
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(this.srcBlend, this.dstBlend);
|
|
};
|
|
PolygonBatcher.prototype.setBlendMode = function (srcBlend, dstBlend) {
|
|
var gl = this.context.gl;
|
|
this.srcBlend = srcBlend;
|
|
this.dstBlend = dstBlend;
|
|
if (this.isDrawing) {
|
|
this.flush();
|
|
gl.blendFunc(this.srcBlend, this.dstBlend);
|
|
}
|
|
};
|
|
PolygonBatcher.prototype.draw = function (texture, vertices, indices) {
|
|
if (texture != this.lastTexture) {
|
|
this.flush();
|
|
this.lastTexture = texture;
|
|
}
|
|
else if (this.verticesLength + vertices.length > this.mesh.getVertices().length ||
|
|
this.indicesLength + indices.length > this.mesh.getIndices().length) {
|
|
this.flush();
|
|
}
|
|
var indexStart = this.mesh.numVertices();
|
|
this.mesh.getVertices().set(vertices, this.verticesLength);
|
|
this.verticesLength += vertices.length;
|
|
this.mesh.setVerticesLength(this.verticesLength);
|
|
var indicesArray = this.mesh.getIndices();
|
|
for (var i = this.indicesLength, j = 0; j < indices.length; i++, j++)
|
|
indicesArray[i] = indices[j] + indexStart;
|
|
this.indicesLength += indices.length;
|
|
this.mesh.setIndicesLength(this.indicesLength);
|
|
};
|
|
PolygonBatcher.prototype.flush = function () {
|
|
var gl = this.context.gl;
|
|
if (this.verticesLength == 0)
|
|
return;
|
|
this.lastTexture.bind();
|
|
this.mesh.draw(this.shader, gl.TRIANGLES);
|
|
this.verticesLength = 0;
|
|
this.indicesLength = 0;
|
|
this.mesh.setVerticesLength(0);
|
|
this.mesh.setIndicesLength(0);
|
|
this.drawCalls++;
|
|
};
|
|
PolygonBatcher.prototype.end = function () {
|
|
var gl = this.context.gl;
|
|
if (!this.isDrawing)
|
|
throw new Error("PolygonBatch is not drawing. Call PolygonBatch.begin() before calling PolygonBatch.end()");
|
|
if (this.verticesLength > 0 || this.indicesLength > 0)
|
|
this.flush();
|
|
this.shader = null;
|
|
this.lastTexture = null;
|
|
this.isDrawing = false;
|
|
gl.disable(gl.BLEND);
|
|
};
|
|
PolygonBatcher.prototype.getDrawCalls = function () { return this.drawCalls; };
|
|
PolygonBatcher.prototype.dispose = function () {
|
|
this.mesh.dispose();
|
|
};
|
|
return PolygonBatcher;
|
|
}());
|
|
webgl.PolygonBatcher = PolygonBatcher;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var SceneRenderer = (function () {
|
|
function SceneRenderer(canvas, context, twoColorTint) {
|
|
if (twoColorTint === void 0) { twoColorTint = true; }
|
|
this.twoColorTint = false;
|
|
this.activeRenderer = null;
|
|
this.QUAD = [
|
|
0, 0, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 0, 0,
|
|
];
|
|
this.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
|
this.WHITE = new spine.Color(1, 1, 1, 1);
|
|
this.canvas = canvas;
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
this.twoColorTint = twoColorTint;
|
|
this.camera = new webgl.OrthoCamera(canvas.width, canvas.height);
|
|
this.batcherShader = twoColorTint ? webgl.Shader.newTwoColoredTextured(this.context) : webgl.Shader.newColoredTextured(this.context);
|
|
this.batcher = new webgl.PolygonBatcher(this.context, twoColorTint);
|
|
this.shapesShader = webgl.Shader.newColored(this.context);
|
|
this.shapes = new webgl.ShapeRenderer(this.context);
|
|
this.skeletonRenderer = new webgl.SkeletonRenderer(this.context, twoColorTint);
|
|
this.skeletonDebugRenderer = new webgl.SkeletonDebugRenderer(this.context);
|
|
}
|
|
SceneRenderer.prototype.begin = function () {
|
|
this.camera.update();
|
|
this.enableRenderer(this.batcher);
|
|
};
|
|
SceneRenderer.prototype.drawSkeleton = function (skeleton, premultipliedAlpha, slotRangeStart, slotRangeEnd) {
|
|
if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
|
|
if (slotRangeStart === void 0) { slotRangeStart = -1; }
|
|
if (slotRangeEnd === void 0) { slotRangeEnd = -1; }
|
|
this.enableRenderer(this.batcher);
|
|
this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
|
|
this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd);
|
|
};
|
|
SceneRenderer.prototype.drawSkeletonDebug = function (skeleton, premultipliedAlpha, ignoredBones) {
|
|
if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
|
|
if (ignoredBones === void 0) { ignoredBones = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.skeletonDebugRenderer.premultipliedAlpha = premultipliedAlpha;
|
|
this.skeletonDebugRenderer.draw(this.shapes, skeleton, ignoredBones);
|
|
};
|
|
SceneRenderer.prototype.drawTexture = function (texture, x, y, width, height, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.batcher);
|
|
if (color === null)
|
|
color = this.WHITE;
|
|
var quad = this.QUAD;
|
|
var i = 0;
|
|
quad[i++] = x;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 0;
|
|
quad[i++] = 1;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 1;
|
|
quad[i++] = 1;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 1;
|
|
quad[i++] = 0;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
|
|
};
|
|
SceneRenderer.prototype.drawTextureUV = function (texture, x, y, width, height, u, v, u2, v2, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.batcher);
|
|
if (color === null)
|
|
color = this.WHITE;
|
|
var quad = this.QUAD;
|
|
var i = 0;
|
|
quad[i++] = x;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = u;
|
|
quad[i++] = v;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = u2;
|
|
quad[i++] = v;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = u2;
|
|
quad[i++] = v2;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = u;
|
|
quad[i++] = v2;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
|
|
};
|
|
SceneRenderer.prototype.drawTextureRotated = function (texture, x, y, width, height, pivotX, pivotY, angle, color, premultipliedAlpha) {
|
|
if (color === void 0) { color = null; }
|
|
if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
|
|
this.enableRenderer(this.batcher);
|
|
if (color === null)
|
|
color = this.WHITE;
|
|
var quad = this.QUAD;
|
|
var worldOriginX = x + pivotX;
|
|
var worldOriginY = y + pivotY;
|
|
var fx = -pivotX;
|
|
var fy = -pivotY;
|
|
var fx2 = width - pivotX;
|
|
var fy2 = height - pivotY;
|
|
var p1x = fx;
|
|
var p1y = fy;
|
|
var p2x = fx;
|
|
var p2y = fy2;
|
|
var p3x = fx2;
|
|
var p3y = fy2;
|
|
var p4x = fx2;
|
|
var p4y = fy;
|
|
var x1 = 0;
|
|
var y1 = 0;
|
|
var x2 = 0;
|
|
var y2 = 0;
|
|
var x3 = 0;
|
|
var y3 = 0;
|
|
var x4 = 0;
|
|
var y4 = 0;
|
|
if (angle != 0) {
|
|
var cos = spine.MathUtils.cosDeg(angle);
|
|
var sin = spine.MathUtils.sinDeg(angle);
|
|
x1 = cos * p1x - sin * p1y;
|
|
y1 = sin * p1x + cos * p1y;
|
|
x4 = cos * p2x - sin * p2y;
|
|
y4 = sin * p2x + cos * p2y;
|
|
x3 = cos * p3x - sin * p3y;
|
|
y3 = sin * p3x + cos * p3y;
|
|
x2 = x3 + (x1 - x4);
|
|
y2 = y3 + (y1 - y4);
|
|
}
|
|
else {
|
|
x1 = p1x;
|
|
y1 = p1y;
|
|
x4 = p2x;
|
|
y4 = p2y;
|
|
x3 = p3x;
|
|
y3 = p3y;
|
|
x2 = p4x;
|
|
y2 = p4y;
|
|
}
|
|
x1 += worldOriginX;
|
|
y1 += worldOriginY;
|
|
x2 += worldOriginX;
|
|
y2 += worldOriginY;
|
|
x3 += worldOriginX;
|
|
y3 += worldOriginY;
|
|
x4 += worldOriginX;
|
|
y4 += worldOriginY;
|
|
var i = 0;
|
|
quad[i++] = x1;
|
|
quad[i++] = y1;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 0;
|
|
quad[i++] = 1;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x2;
|
|
quad[i++] = y2;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 1;
|
|
quad[i++] = 1;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x3;
|
|
quad[i++] = y3;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 1;
|
|
quad[i++] = 0;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x4;
|
|
quad[i++] = y4;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
|
|
};
|
|
SceneRenderer.prototype.drawRegion = function (region, x, y, width, height, color, premultipliedAlpha) {
|
|
if (color === void 0) { color = null; }
|
|
if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
|
|
this.enableRenderer(this.batcher);
|
|
if (color === null)
|
|
color = this.WHITE;
|
|
var quad = this.QUAD;
|
|
var i = 0;
|
|
quad[i++] = x;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = region.u;
|
|
quad[i++] = region.v2;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = region.u2;
|
|
quad[i++] = region.v2;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x + width;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = region.u2;
|
|
quad[i++] = region.v;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
quad[i++] = x;
|
|
quad[i++] = y + height;
|
|
quad[i++] = color.r;
|
|
quad[i++] = color.g;
|
|
quad[i++] = color.b;
|
|
quad[i++] = color.a;
|
|
quad[i++] = region.u;
|
|
quad[i++] = region.v;
|
|
if (this.twoColorTint) {
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
quad[i++] = 0;
|
|
}
|
|
this.batcher.draw(region.texture, quad, this.QUAD_TRIANGLES);
|
|
};
|
|
SceneRenderer.prototype.line = function (x, y, x2, y2, color, color2) {
|
|
if (color === void 0) { color = null; }
|
|
if (color2 === void 0) { color2 = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.line(x, y, x2, y2, color);
|
|
};
|
|
SceneRenderer.prototype.triangle = function (filled, x, y, x2, y2, x3, y3, color, color2, color3) {
|
|
if (color === void 0) { color = null; }
|
|
if (color2 === void 0) { color2 = null; }
|
|
if (color3 === void 0) { color3 = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.triangle(filled, x, y, x2, y2, x3, y3, color, color2, color3);
|
|
};
|
|
SceneRenderer.prototype.quad = function (filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) {
|
|
if (color === void 0) { color = null; }
|
|
if (color2 === void 0) { color2 = null; }
|
|
if (color3 === void 0) { color3 = null; }
|
|
if (color4 === void 0) { color4 = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.quad(filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4);
|
|
};
|
|
SceneRenderer.prototype.rect = function (filled, x, y, width, height, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.rect(filled, x, y, width, height, color);
|
|
};
|
|
SceneRenderer.prototype.rectLine = function (filled, x1, y1, x2, y2, width, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.rectLine(filled, x1, y1, x2, y2, width, color);
|
|
};
|
|
SceneRenderer.prototype.polygon = function (polygonVertices, offset, count, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.polygon(polygonVertices, offset, count, color);
|
|
};
|
|
SceneRenderer.prototype.circle = function (filled, x, y, radius, color, segments) {
|
|
if (color === void 0) { color = null; }
|
|
if (segments === void 0) { segments = 0; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.circle(filled, x, y, radius, color, segments);
|
|
};
|
|
SceneRenderer.prototype.curve = function (x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.enableRenderer(this.shapes);
|
|
this.shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color);
|
|
};
|
|
SceneRenderer.prototype.end = function () {
|
|
if (this.activeRenderer === this.batcher)
|
|
this.batcher.end();
|
|
else if (this.activeRenderer === this.shapes)
|
|
this.shapes.end();
|
|
this.activeRenderer = null;
|
|
};
|
|
SceneRenderer.prototype.resize = function (resizeMode) {
|
|
var canvas = this.canvas;
|
|
var w = canvas.clientWidth;
|
|
var h = canvas.clientHeight;
|
|
if (canvas.width != w || canvas.height != h) {
|
|
canvas.width = w;
|
|
canvas.height = h;
|
|
}
|
|
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
|
|
if (resizeMode === ResizeMode.Stretch) {
|
|
}
|
|
else if (resizeMode === ResizeMode.Expand) {
|
|
this.camera.setViewport(w, h);
|
|
}
|
|
else if (resizeMode === ResizeMode.Fit) {
|
|
var sourceWidth = canvas.width, sourceHeight = canvas.height;
|
|
var targetWidth = this.camera.viewportWidth, targetHeight = this.camera.viewportHeight;
|
|
var targetRatio = targetHeight / targetWidth;
|
|
var sourceRatio = sourceHeight / sourceWidth;
|
|
var scale = targetRatio < sourceRatio ? targetWidth / sourceWidth : targetHeight / sourceHeight;
|
|
this.camera.viewportWidth = sourceWidth * scale;
|
|
this.camera.viewportHeight = sourceHeight * scale;
|
|
}
|
|
this.camera.update();
|
|
};
|
|
SceneRenderer.prototype.enableRenderer = function (renderer) {
|
|
if (this.activeRenderer === renderer)
|
|
return;
|
|
this.end();
|
|
if (renderer instanceof webgl.PolygonBatcher) {
|
|
this.batcherShader.bind();
|
|
this.batcherShader.setUniform4x4f(webgl.Shader.MVP_MATRIX, this.camera.projectionView.values);
|
|
this.batcherShader.setUniformi("u_texture", 0);
|
|
this.batcher.begin(this.batcherShader);
|
|
this.activeRenderer = this.batcher;
|
|
}
|
|
else if (renderer instanceof webgl.ShapeRenderer) {
|
|
this.shapesShader.bind();
|
|
this.shapesShader.setUniform4x4f(webgl.Shader.MVP_MATRIX, this.camera.projectionView.values);
|
|
this.shapes.begin(this.shapesShader);
|
|
this.activeRenderer = this.shapes;
|
|
}
|
|
else {
|
|
this.activeRenderer = this.skeletonDebugRenderer;
|
|
}
|
|
};
|
|
SceneRenderer.prototype.dispose = function () {
|
|
this.batcher.dispose();
|
|
this.batcherShader.dispose();
|
|
this.shapes.dispose();
|
|
this.shapesShader.dispose();
|
|
this.skeletonDebugRenderer.dispose();
|
|
};
|
|
return SceneRenderer;
|
|
}());
|
|
webgl.SceneRenderer = SceneRenderer;
|
|
var ResizeMode;
|
|
(function (ResizeMode) {
|
|
ResizeMode[ResizeMode["Stretch"] = 0] = "Stretch";
|
|
ResizeMode[ResizeMode["Expand"] = 1] = "Expand";
|
|
ResizeMode[ResizeMode["Fit"] = 2] = "Fit";
|
|
})(ResizeMode = webgl.ResizeMode || (webgl.ResizeMode = {}));
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var Shader = (function () {
|
|
function Shader(context, vertexShader, fragmentShader) {
|
|
this.vertexShader = vertexShader;
|
|
this.fragmentShader = fragmentShader;
|
|
this.vs = null;
|
|
this.fs = null;
|
|
this.program = null;
|
|
this.tmp2x2 = new Float32Array(2 * 2);
|
|
this.tmp3x3 = new Float32Array(3 * 3);
|
|
this.tmp4x4 = new Float32Array(4 * 4);
|
|
this.vsSource = vertexShader;
|
|
this.fsSource = fragmentShader;
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
this.context.addRestorable(this);
|
|
this.compile();
|
|
}
|
|
Shader.prototype.getProgram = function () { return this.program; };
|
|
Shader.prototype.getVertexShader = function () { return this.vertexShader; };
|
|
Shader.prototype.getFragmentShader = function () { return this.fragmentShader; };
|
|
Shader.prototype.getVertexShaderSource = function () { return this.vsSource; };
|
|
Shader.prototype.getFragmentSource = function () { return this.fsSource; };
|
|
Shader.prototype.compile = function () {
|
|
var gl = this.context.gl;
|
|
try {
|
|
this.vs = this.compileShader(gl.VERTEX_SHADER, this.vertexShader);
|
|
this.fs = this.compileShader(gl.FRAGMENT_SHADER, this.fragmentShader);
|
|
this.program = this.compileProgram(this.vs, this.fs);
|
|
}
|
|
catch (e) {
|
|
this.dispose();
|
|
throw e;
|
|
}
|
|
};
|
|
Shader.prototype.compileShader = function (type, source) {
|
|
var gl = this.context.gl;
|
|
var shader = gl.createShader(type);
|
|
gl.shaderSource(shader, source);
|
|
gl.compileShader(shader);
|
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
var error = "Couldn't compile shader: " + gl.getShaderInfoLog(shader);
|
|
gl.deleteShader(shader);
|
|
if (!gl.isContextLost())
|
|
throw new Error(error);
|
|
}
|
|
return shader;
|
|
};
|
|
Shader.prototype.compileProgram = function (vs, fs) {
|
|
var gl = this.context.gl;
|
|
var program = gl.createProgram();
|
|
gl.attachShader(program, vs);
|
|
gl.attachShader(program, fs);
|
|
gl.linkProgram(program);
|
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
var error = "Couldn't compile shader program: " + gl.getProgramInfoLog(program);
|
|
gl.deleteProgram(program);
|
|
if (!gl.isContextLost())
|
|
throw new Error(error);
|
|
}
|
|
return program;
|
|
};
|
|
Shader.prototype.restore = function () {
|
|
this.compile();
|
|
};
|
|
Shader.prototype.bind = function () {
|
|
this.context.gl.useProgram(this.program);
|
|
};
|
|
Shader.prototype.unbind = function () {
|
|
this.context.gl.useProgram(null);
|
|
};
|
|
Shader.prototype.setUniformi = function (uniform, value) {
|
|
this.context.gl.uniform1i(this.getUniformLocation(uniform), value);
|
|
};
|
|
Shader.prototype.setUniformf = function (uniform, value) {
|
|
this.context.gl.uniform1f(this.getUniformLocation(uniform), value);
|
|
};
|
|
Shader.prototype.setUniform2f = function (uniform, value, value2) {
|
|
this.context.gl.uniform2f(this.getUniformLocation(uniform), value, value2);
|
|
};
|
|
Shader.prototype.setUniform3f = function (uniform, value, value2, value3) {
|
|
this.context.gl.uniform3f(this.getUniformLocation(uniform), value, value2, value3);
|
|
};
|
|
Shader.prototype.setUniform4f = function (uniform, value, value2, value3, value4) {
|
|
this.context.gl.uniform4f(this.getUniformLocation(uniform), value, value2, value3, value4);
|
|
};
|
|
Shader.prototype.setUniform2x2f = function (uniform, value) {
|
|
var gl = this.context.gl;
|
|
this.tmp2x2.set(value);
|
|
gl.uniformMatrix2fv(this.getUniformLocation(uniform), false, this.tmp2x2);
|
|
};
|
|
Shader.prototype.setUniform3x3f = function (uniform, value) {
|
|
var gl = this.context.gl;
|
|
this.tmp3x3.set(value);
|
|
gl.uniformMatrix3fv(this.getUniformLocation(uniform), false, this.tmp3x3);
|
|
};
|
|
Shader.prototype.setUniform4x4f = function (uniform, value) {
|
|
var gl = this.context.gl;
|
|
this.tmp4x4.set(value);
|
|
gl.uniformMatrix4fv(this.getUniformLocation(uniform), false, this.tmp4x4);
|
|
};
|
|
Shader.prototype.getUniformLocation = function (uniform) {
|
|
var gl = this.context.gl;
|
|
var location = gl.getUniformLocation(this.program, uniform);
|
|
if (!location && !gl.isContextLost())
|
|
throw new Error("Couldn't find location for uniform " + uniform);
|
|
return location;
|
|
};
|
|
Shader.prototype.getAttributeLocation = function (attribute) {
|
|
var gl = this.context.gl;
|
|
var location = gl.getAttribLocation(this.program, attribute);
|
|
if (location == -1 && !gl.isContextLost())
|
|
throw new Error("Couldn't find location for attribute " + attribute);
|
|
return location;
|
|
};
|
|
Shader.prototype.dispose = function () {
|
|
this.context.removeRestorable(this);
|
|
var gl = this.context.gl;
|
|
if (this.vs) {
|
|
gl.deleteShader(this.vs);
|
|
this.vs = null;
|
|
}
|
|
if (this.fs) {
|
|
gl.deleteShader(this.fs);
|
|
this.fs = null;
|
|
}
|
|
if (this.program) {
|
|
gl.deleteProgram(this.program);
|
|
this.program = null;
|
|
}
|
|
};
|
|
Shader.newColoredTextured = function (context) {
|
|
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
|
|
return new Shader(context, vs, fs);
|
|
};
|
|
Shader.newTwoColoredTextured = function (context) {
|
|
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
|
|
return new Shader(context, vs, fs);
|
|
};
|
|
Shader.newColored = function (context) {
|
|
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
|
|
return new Shader(context, vs, fs);
|
|
};
|
|
Shader.MVP_MATRIX = "u_projTrans";
|
|
Shader.POSITION = "a_position";
|
|
Shader.COLOR = "a_color";
|
|
Shader.COLOR2 = "a_color2";
|
|
Shader.TEXCOORDS = "a_texCoords";
|
|
Shader.SAMPLER = "u_texture";
|
|
return Shader;
|
|
}());
|
|
webgl.Shader = Shader;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var ShapeRenderer = (function () {
|
|
function ShapeRenderer(context, maxVertices) {
|
|
if (maxVertices === void 0) { maxVertices = 10920; }
|
|
this.isDrawing = false;
|
|
this.shapeType = ShapeType.Filled;
|
|
this.color = new spine.Color(1, 1, 1, 1);
|
|
this.vertexIndex = 0;
|
|
this.tmp = new spine.Vector2();
|
|
if (maxVertices > 10920)
|
|
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
this.mesh = new webgl.Mesh(context, [new webgl.Position2Attribute(), new webgl.ColorAttribute()], maxVertices, 0);
|
|
this.srcBlend = this.context.gl.SRC_ALPHA;
|
|
this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA;
|
|
}
|
|
ShapeRenderer.prototype.begin = function (shader) {
|
|
if (this.isDrawing)
|
|
throw new Error("ShapeRenderer.begin() has already been called");
|
|
this.shader = shader;
|
|
this.vertexIndex = 0;
|
|
this.isDrawing = true;
|
|
var gl = this.context.gl;
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(this.srcBlend, this.dstBlend);
|
|
};
|
|
ShapeRenderer.prototype.setBlendMode = function (srcBlend, dstBlend) {
|
|
var gl = this.context.gl;
|
|
this.srcBlend = srcBlend;
|
|
this.dstBlend = dstBlend;
|
|
if (this.isDrawing) {
|
|
this.flush();
|
|
gl.blendFunc(this.srcBlend, this.dstBlend);
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.setColor = function (color) {
|
|
this.color.setFromColor(color);
|
|
};
|
|
ShapeRenderer.prototype.setColorWith = function (r, g, b, a) {
|
|
this.color.set(r, g, b, a);
|
|
};
|
|
ShapeRenderer.prototype.point = function (x, y, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.check(ShapeType.Point, 1);
|
|
if (color === null)
|
|
color = this.color;
|
|
this.vertex(x, y, color);
|
|
};
|
|
ShapeRenderer.prototype.line = function (x, y, x2, y2, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.check(ShapeType.Line, 2);
|
|
var vertices = this.mesh.getVertices();
|
|
var idx = this.vertexIndex;
|
|
if (color === null)
|
|
color = this.color;
|
|
this.vertex(x, y, color);
|
|
this.vertex(x2, y2, color);
|
|
};
|
|
ShapeRenderer.prototype.triangle = function (filled, x, y, x2, y2, x3, y3, color, color2, color3) {
|
|
if (color === void 0) { color = null; }
|
|
if (color2 === void 0) { color2 = null; }
|
|
if (color3 === void 0) { color3 = null; }
|
|
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
var vertices = this.mesh.getVertices();
|
|
var idx = this.vertexIndex;
|
|
if (color === null)
|
|
color = this.color;
|
|
if (color2 === null)
|
|
color2 = this.color;
|
|
if (color3 === null)
|
|
color3 = this.color;
|
|
if (filled) {
|
|
this.vertex(x, y, color);
|
|
this.vertex(x2, y2, color2);
|
|
this.vertex(x3, y3, color3);
|
|
}
|
|
else {
|
|
this.vertex(x, y, color);
|
|
this.vertex(x2, y2, color2);
|
|
this.vertex(x2, y2, color);
|
|
this.vertex(x3, y3, color2);
|
|
this.vertex(x3, y3, color);
|
|
this.vertex(x, y, color2);
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.quad = function (filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) {
|
|
if (color === void 0) { color = null; }
|
|
if (color2 === void 0) { color2 = null; }
|
|
if (color3 === void 0) { color3 = null; }
|
|
if (color4 === void 0) { color4 = null; }
|
|
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
|
|
var vertices = this.mesh.getVertices();
|
|
var idx = this.vertexIndex;
|
|
if (color === null)
|
|
color = this.color;
|
|
if (color2 === null)
|
|
color2 = this.color;
|
|
if (color3 === null)
|
|
color3 = this.color;
|
|
if (color4 === null)
|
|
color4 = this.color;
|
|
if (filled) {
|
|
this.vertex(x, y, color);
|
|
this.vertex(x2, y2, color2);
|
|
this.vertex(x3, y3, color3);
|
|
this.vertex(x3, y3, color3);
|
|
this.vertex(x4, y4, color4);
|
|
this.vertex(x, y, color);
|
|
}
|
|
else {
|
|
this.vertex(x, y, color);
|
|
this.vertex(x2, y2, color2);
|
|
this.vertex(x2, y2, color2);
|
|
this.vertex(x3, y3, color3);
|
|
this.vertex(x3, y3, color3);
|
|
this.vertex(x4, y4, color4);
|
|
this.vertex(x4, y4, color4);
|
|
this.vertex(x, y, color);
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.rect = function (filled, x, y, width, height, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
|
|
};
|
|
ShapeRenderer.prototype.rectLine = function (filled, x1, y1, x2, y2, width, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
|
|
if (color === null)
|
|
color = this.color;
|
|
var t = this.tmp.set(y2 - y1, x1 - x2);
|
|
t.normalize();
|
|
width *= 0.5;
|
|
var tx = t.x * width;
|
|
var ty = t.y * width;
|
|
if (!filled) {
|
|
this.vertex(x1 + tx, y1 + ty, color);
|
|
this.vertex(x1 - tx, y1 - ty, color);
|
|
this.vertex(x2 + tx, y2 + ty, color);
|
|
this.vertex(x2 - tx, y2 - ty, color);
|
|
this.vertex(x2 + tx, y2 + ty, color);
|
|
this.vertex(x1 + tx, y1 + ty, color);
|
|
this.vertex(x2 - tx, y2 - ty, color);
|
|
this.vertex(x1 - tx, y1 - ty, color);
|
|
}
|
|
else {
|
|
this.vertex(x1 + tx, y1 + ty, color);
|
|
this.vertex(x1 - tx, y1 - ty, color);
|
|
this.vertex(x2 + tx, y2 + ty, color);
|
|
this.vertex(x2 - tx, y2 - ty, color);
|
|
this.vertex(x2 + tx, y2 + ty, color);
|
|
this.vertex(x1 - tx, y1 - ty, color);
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.x = function (x, y, size) {
|
|
this.line(x - size, y - size, x + size, y + size);
|
|
this.line(x - size, y + size, x + size, y - size);
|
|
};
|
|
ShapeRenderer.prototype.polygon = function (polygonVertices, offset, count, color) {
|
|
if (color === void 0) { color = null; }
|
|
if (count < 3)
|
|
throw new Error("Polygon must contain at least 3 vertices");
|
|
this.check(ShapeType.Line, count * 2);
|
|
if (color === null)
|
|
color = this.color;
|
|
var vertices = this.mesh.getVertices();
|
|
var idx = this.vertexIndex;
|
|
offset <<= 1;
|
|
count <<= 1;
|
|
var firstX = polygonVertices[offset];
|
|
var firstY = polygonVertices[offset + 1];
|
|
var last = offset + count;
|
|
for (var i = offset, n = offset + count - 2; i < n; i += 2) {
|
|
var x1 = polygonVertices[i];
|
|
var y1 = polygonVertices[i + 1];
|
|
var x2 = 0;
|
|
var y2 = 0;
|
|
if (i + 2 >= last) {
|
|
x2 = firstX;
|
|
y2 = firstY;
|
|
}
|
|
else {
|
|
x2 = polygonVertices[i + 2];
|
|
y2 = polygonVertices[i + 3];
|
|
}
|
|
this.vertex(x1, y1, color);
|
|
this.vertex(x2, y2, color);
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.circle = function (filled, x, y, radius, color, segments) {
|
|
if (color === void 0) { color = null; }
|
|
if (segments === void 0) { segments = 0; }
|
|
if (segments === 0)
|
|
segments = Math.max(1, (6 * spine.MathUtils.cbrt(radius)) | 0);
|
|
if (segments <= 0)
|
|
throw new Error("segments must be > 0.");
|
|
if (color === null)
|
|
color = this.color;
|
|
var angle = 2 * spine.MathUtils.PI / segments;
|
|
var cos = Math.cos(angle);
|
|
var sin = Math.sin(angle);
|
|
var cx = radius, cy = 0;
|
|
if (!filled) {
|
|
this.check(ShapeType.Line, segments * 2 + 2);
|
|
for (var i = 0; i < segments; i++) {
|
|
this.vertex(x + cx, y + cy, color);
|
|
var temp_1 = cx;
|
|
cx = cos * cx - sin * cy;
|
|
cy = sin * temp_1 + cos * cy;
|
|
this.vertex(x + cx, y + cy, color);
|
|
}
|
|
this.vertex(x + cx, y + cy, color);
|
|
}
|
|
else {
|
|
this.check(ShapeType.Filled, segments * 3 + 3);
|
|
segments--;
|
|
for (var i = 0; i < segments; i++) {
|
|
this.vertex(x, y, color);
|
|
this.vertex(x + cx, y + cy, color);
|
|
var temp_2 = cx;
|
|
cx = cos * cx - sin * cy;
|
|
cy = sin * temp_2 + cos * cy;
|
|
this.vertex(x + cx, y + cy, color);
|
|
}
|
|
this.vertex(x, y, color);
|
|
this.vertex(x + cx, y + cy, color);
|
|
}
|
|
var temp = cx;
|
|
cx = radius;
|
|
cy = 0;
|
|
this.vertex(x + cx, y + cy, color);
|
|
};
|
|
ShapeRenderer.prototype.curve = function (x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) {
|
|
if (color === void 0) { color = null; }
|
|
this.check(ShapeType.Line, segments * 2 + 2);
|
|
if (color === null)
|
|
color = this.color;
|
|
var subdiv_step = 1 / segments;
|
|
var subdiv_step2 = subdiv_step * subdiv_step;
|
|
var subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
|
|
var pre1 = 3 * subdiv_step;
|
|
var pre2 = 3 * subdiv_step2;
|
|
var pre4 = 6 * subdiv_step2;
|
|
var pre5 = 6 * subdiv_step3;
|
|
var tmp1x = x1 - cx1 * 2 + cx2;
|
|
var tmp1y = y1 - cy1 * 2 + cy2;
|
|
var tmp2x = (cx1 - cx2) * 3 - x1 + x2;
|
|
var tmp2y = (cy1 - cy2) * 3 - y1 + y2;
|
|
var fx = x1;
|
|
var fy = y1;
|
|
var dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
|
|
var dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
|
|
var ddfx = tmp1x * pre4 + tmp2x * pre5;
|
|
var ddfy = tmp1y * pre4 + tmp2y * pre5;
|
|
var dddfx = tmp2x * pre5;
|
|
var dddfy = tmp2y * pre5;
|
|
while (segments-- > 0) {
|
|
this.vertex(fx, fy, color);
|
|
fx += dfx;
|
|
fy += dfy;
|
|
dfx += ddfx;
|
|
dfy += ddfy;
|
|
ddfx += dddfx;
|
|
ddfy += dddfy;
|
|
this.vertex(fx, fy, color);
|
|
}
|
|
this.vertex(fx, fy, color);
|
|
this.vertex(x2, y2, color);
|
|
};
|
|
ShapeRenderer.prototype.vertex = function (x, y, color) {
|
|
var idx = this.vertexIndex;
|
|
var vertices = this.mesh.getVertices();
|
|
vertices[idx++] = x;
|
|
vertices[idx++] = y;
|
|
vertices[idx++] = color.r;
|
|
vertices[idx++] = color.g;
|
|
vertices[idx++] = color.b;
|
|
vertices[idx++] = color.a;
|
|
this.vertexIndex = idx;
|
|
};
|
|
ShapeRenderer.prototype.end = function () {
|
|
if (!this.isDrawing)
|
|
throw new Error("ShapeRenderer.begin() has not been called");
|
|
this.flush();
|
|
this.context.gl.disable(this.context.gl.BLEND);
|
|
this.isDrawing = false;
|
|
};
|
|
ShapeRenderer.prototype.flush = function () {
|
|
if (this.vertexIndex == 0)
|
|
return;
|
|
this.mesh.setVerticesLength(this.vertexIndex);
|
|
this.mesh.draw(this.shader, this.shapeType);
|
|
this.vertexIndex = 0;
|
|
};
|
|
ShapeRenderer.prototype.check = function (shapeType, numVertices) {
|
|
if (!this.isDrawing)
|
|
throw new Error("ShapeRenderer.begin() has not been called");
|
|
if (this.shapeType == shapeType) {
|
|
if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices)
|
|
this.flush();
|
|
else
|
|
return;
|
|
}
|
|
else {
|
|
this.flush();
|
|
this.shapeType = shapeType;
|
|
}
|
|
};
|
|
ShapeRenderer.prototype.dispose = function () {
|
|
this.mesh.dispose();
|
|
};
|
|
return ShapeRenderer;
|
|
}());
|
|
webgl.ShapeRenderer = ShapeRenderer;
|
|
var ShapeType;
|
|
(function (ShapeType) {
|
|
ShapeType[ShapeType["Point"] = 0] = "Point";
|
|
ShapeType[ShapeType["Line"] = 1] = "Line";
|
|
ShapeType[ShapeType["Filled"] = 4] = "Filled";
|
|
})(ShapeType = webgl.ShapeType || (webgl.ShapeType = {}));
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var SkeletonDebugRenderer = (function () {
|
|
function SkeletonDebugRenderer(context) {
|
|
this.boneLineColor = new spine.Color(1, 0, 0, 1);
|
|
this.boneOriginColor = new spine.Color(0, 1, 0, 1);
|
|
this.attachmentLineColor = new spine.Color(0, 0, 1, 0.5);
|
|
this.triangleLineColor = new spine.Color(1, 0.64, 0, 0.5);
|
|
this.pathColor = new spine.Color().setFromString("FF7F00");
|
|
this.clipColor = new spine.Color(0.8, 0, 0, 2);
|
|
this.aabbColor = new spine.Color(0, 1, 0, 0.5);
|
|
this.drawBones = true;
|
|
this.drawRegionAttachments = true;
|
|
this.drawBoundingBoxes = true;
|
|
this.drawMeshHull = true;
|
|
this.drawMeshTriangles = true;
|
|
this.drawPaths = true;
|
|
this.drawSkeletonXY = false;
|
|
this.drawClipping = true;
|
|
this.premultipliedAlpha = false;
|
|
this.scale = 1;
|
|
this.boneWidth = 2;
|
|
this.bounds = new spine.SkeletonBounds();
|
|
this.temp = new Array();
|
|
this.vertices = spine.Utils.newFloatArray(2 * 1024);
|
|
this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
|
|
}
|
|
SkeletonDebugRenderer.prototype.draw = function (shapes, skeleton, ignoredBones) {
|
|
if (ignoredBones === void 0) { ignoredBones = null; }
|
|
var skeletonX = skeleton.x;
|
|
var skeletonY = skeleton.y;
|
|
var gl = this.context.gl;
|
|
var srcFunc = this.premultipliedAlpha ? gl.ONE : gl.SRC_ALPHA;
|
|
shapes.setBlendMode(srcFunc, gl.ONE_MINUS_SRC_ALPHA);
|
|
var bones = skeleton.bones;
|
|
if (this.drawBones) {
|
|
shapes.setColor(this.boneLineColor);
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (ignoredBones && ignoredBones.indexOf(bone.data.name) > -1)
|
|
continue;
|
|
if (bone.parent == null)
|
|
continue;
|
|
var x = skeletonX + bone.data.length * bone.a + bone.worldX;
|
|
var y = skeletonY + bone.data.length * bone.c + bone.worldY;
|
|
shapes.rectLine(true, skeletonX + bone.worldX, skeletonY + bone.worldY, x, y, this.boneWidth * this.scale);
|
|
}
|
|
if (this.drawSkeletonXY)
|
|
shapes.x(skeletonX, skeletonY, 4 * this.scale);
|
|
}
|
|
if (this.drawRegionAttachments) {
|
|
shapes.setColor(this.attachmentLineColor);
|
|
var slots = skeleton.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
var attachment = slot.getAttachment();
|
|
if (attachment instanceof spine.RegionAttachment) {
|
|
var regionAttachment = attachment;
|
|
var vertices = this.vertices;
|
|
regionAttachment.computeWorldVertices(slot.bone, vertices, 0, 2);
|
|
shapes.line(vertices[0], vertices[1], vertices[2], vertices[3]);
|
|
shapes.line(vertices[2], vertices[3], vertices[4], vertices[5]);
|
|
shapes.line(vertices[4], vertices[5], vertices[6], vertices[7]);
|
|
shapes.line(vertices[6], vertices[7], vertices[0], vertices[1]);
|
|
}
|
|
}
|
|
}
|
|
if (this.drawMeshHull || this.drawMeshTriangles) {
|
|
var slots = skeleton.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var attachment = slot.getAttachment();
|
|
if (!(attachment instanceof spine.MeshAttachment))
|
|
continue;
|
|
var mesh = attachment;
|
|
var vertices = this.vertices;
|
|
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, 2);
|
|
var triangles = mesh.triangles;
|
|
var hullLength = mesh.hullLength;
|
|
if (this.drawMeshTriangles) {
|
|
shapes.setColor(this.triangleLineColor);
|
|
for (var ii = 0, nn = triangles.length; ii < nn; ii += 3) {
|
|
var v1 = triangles[ii] * 2, v2 = triangles[ii + 1] * 2, v3 = triangles[ii + 2] * 2;
|
|
shapes.triangle(false, vertices[v1], vertices[v1 + 1], vertices[v2], vertices[v2 + 1], vertices[v3], vertices[v3 + 1]);
|
|
}
|
|
}
|
|
if (this.drawMeshHull && hullLength > 0) {
|
|
shapes.setColor(this.attachmentLineColor);
|
|
hullLength = (hullLength >> 1) * 2;
|
|
var lastX = vertices[hullLength - 2], lastY = vertices[hullLength - 1];
|
|
for (var ii = 0, nn = hullLength; ii < nn; ii += 2) {
|
|
var x = vertices[ii], y = vertices[ii + 1];
|
|
shapes.line(x, y, lastX, lastY);
|
|
lastX = x;
|
|
lastY = y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.drawBoundingBoxes) {
|
|
var bounds = this.bounds;
|
|
bounds.update(skeleton, true);
|
|
shapes.setColor(this.aabbColor);
|
|
shapes.rect(false, bounds.minX, bounds.minY, bounds.getWidth(), bounds.getHeight());
|
|
var polygons = bounds.polygons;
|
|
var boxes = bounds.boundingBoxes;
|
|
for (var i = 0, n = polygons.length; i < n; i++) {
|
|
var polygon = polygons[i];
|
|
shapes.setColor(boxes[i].color);
|
|
shapes.polygon(polygon, 0, polygon.length);
|
|
}
|
|
}
|
|
if (this.drawPaths) {
|
|
var slots = skeleton.slots;
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var attachment = slot.getAttachment();
|
|
if (!(attachment instanceof spine.PathAttachment))
|
|
continue;
|
|
var path = attachment;
|
|
var nn = path.worldVerticesLength;
|
|
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
|
|
path.computeWorldVertices(slot, 0, nn, world, 0, 2);
|
|
var color = this.pathColor;
|
|
var x1 = world[2], y1 = world[3], x2 = 0, y2 = 0;
|
|
if (path.closed) {
|
|
shapes.setColor(color);
|
|
var cx1 = world[0], cy1 = world[1], cx2 = world[nn - 2], cy2 = world[nn - 1];
|
|
x2 = world[nn - 4];
|
|
y2 = world[nn - 3];
|
|
shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, 32);
|
|
shapes.setColor(SkeletonDebugRenderer.LIGHT_GRAY);
|
|
shapes.line(x1, y1, cx1, cy1);
|
|
shapes.line(x2, y2, cx2, cy2);
|
|
}
|
|
nn -= 4;
|
|
for (var ii = 4; ii < nn; ii += 6) {
|
|
var cx1 = world[ii], cy1 = world[ii + 1], cx2 = world[ii + 2], cy2 = world[ii + 3];
|
|
x2 = world[ii + 4];
|
|
y2 = world[ii + 5];
|
|
shapes.setColor(color);
|
|
shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, 32);
|
|
shapes.setColor(SkeletonDebugRenderer.LIGHT_GRAY);
|
|
shapes.line(x1, y1, cx1, cy1);
|
|
shapes.line(x2, y2, cx2, cy2);
|
|
x1 = x2;
|
|
y1 = y2;
|
|
}
|
|
}
|
|
}
|
|
if (this.drawBones) {
|
|
shapes.setColor(this.boneOriginColor);
|
|
for (var i = 0, n = bones.length; i < n; i++) {
|
|
var bone = bones[i];
|
|
if (ignoredBones && ignoredBones.indexOf(bone.data.name) > -1)
|
|
continue;
|
|
shapes.circle(true, skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * this.scale, SkeletonDebugRenderer.GREEN, 8);
|
|
}
|
|
}
|
|
if (this.drawClipping) {
|
|
var slots = skeleton.slots;
|
|
shapes.setColor(this.clipColor);
|
|
for (var i = 0, n = slots.length; i < n; i++) {
|
|
var slot = slots[i];
|
|
if (!slot.bone.active)
|
|
continue;
|
|
var attachment = slot.getAttachment();
|
|
if (!(attachment instanceof spine.ClippingAttachment))
|
|
continue;
|
|
var clip = attachment;
|
|
var nn = clip.worldVerticesLength;
|
|
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
|
|
clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
|
|
for (var i_17 = 0, n_3 = world.length; i_17 < n_3; i_17 += 2) {
|
|
var x = world[i_17];
|
|
var y = world[i_17 + 1];
|
|
var x2 = world[(i_17 + 2) % world.length];
|
|
var y2 = world[(i_17 + 3) % world.length];
|
|
shapes.line(x, y, x2, y2);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
SkeletonDebugRenderer.prototype.dispose = function () {
|
|
};
|
|
SkeletonDebugRenderer.LIGHT_GRAY = new spine.Color(192 / 255, 192 / 255, 192 / 255, 1);
|
|
SkeletonDebugRenderer.GREEN = new spine.Color(0, 1, 0, 1);
|
|
return SkeletonDebugRenderer;
|
|
}());
|
|
webgl.SkeletonDebugRenderer = SkeletonDebugRenderer;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var Renderable = (function () {
|
|
function Renderable(vertices, numVertices, numFloats) {
|
|
this.vertices = vertices;
|
|
this.numVertices = numVertices;
|
|
this.numFloats = numFloats;
|
|
}
|
|
return Renderable;
|
|
}());
|
|
;
|
|
var SkeletonRenderer = (function () {
|
|
function SkeletonRenderer(context, twoColorTint) {
|
|
if (twoColorTint === void 0) { twoColorTint = true; }
|
|
this.premultipliedAlpha = false;
|
|
this.vertexEffect = null;
|
|
this.tempColor = new spine.Color();
|
|
this.tempColor2 = new spine.Color();
|
|
this.vertexSize = 2 + 2 + 4;
|
|
this.twoColorTint = false;
|
|
this.renderable = new Renderable(null, 0, 0);
|
|
this.clipper = new spine.SkeletonClipping();
|
|
this.temp = new spine.Vector2();
|
|
this.temp2 = new spine.Vector2();
|
|
this.temp3 = new spine.Color();
|
|
this.temp4 = new spine.Color();
|
|
this.twoColorTint = twoColorTint;
|
|
if (twoColorTint)
|
|
this.vertexSize += 4;
|
|
this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
|
|
}
|
|
SkeletonRenderer.prototype.draw = function (batcher, skeleton, slotRangeStart, slotRangeEnd) {
|
|
if (slotRangeStart === void 0) { slotRangeStart = -1; }
|
|
if (slotRangeEnd === void 0) { slotRangeEnd = -1; }
|
|
var clipper = this.clipper;
|
|
var premultipliedAlpha = this.premultipliedAlpha;
|
|
var twoColorTint = this.twoColorTint;
|
|
var blendMode = null;
|
|
var tempPos = this.temp;
|
|
var tempUv = this.temp2;
|
|
var tempLight = this.temp3;
|
|
var tempDark = this.temp4;
|
|
var renderable = this.renderable;
|
|
var uvs = null;
|
|
var triangles = null;
|
|
var drawOrder = skeleton.drawOrder;
|
|
var attachmentColor = null;
|
|
var skeletonColor = skeleton.color;
|
|
var vertexSize = twoColorTint ? 12 : 8;
|
|
var inRange = false;
|
|
if (slotRangeStart == -1)
|
|
inRange = true;
|
|
for (var i = 0, n = drawOrder.length; i < n; i++) {
|
|
var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
|
|
var slot = drawOrder[i];
|
|
if (!slot.bone.active) {
|
|
clipper.clipEndWithSlot(slot);
|
|
continue;
|
|
}
|
|
if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
|
|
inRange = true;
|
|
}
|
|
if (!inRange) {
|
|
clipper.clipEndWithSlot(slot);
|
|
continue;
|
|
}
|
|
if (slotRangeEnd >= 0 && slotRangeEnd == slot.data.index) {
|
|
inRange = false;
|
|
}
|
|
var attachment = slot.getAttachment();
|
|
var texture = null;
|
|
if (attachment instanceof spine.RegionAttachment) {
|
|
var region = attachment;
|
|
renderable.vertices = this.vertices;
|
|
renderable.numVertices = 4;
|
|
renderable.numFloats = clippedVertexSize << 2;
|
|
region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
|
|
triangles = SkeletonRenderer.QUAD_TRIANGLES;
|
|
uvs = region.uvs;
|
|
texture = region.region.renderObject.texture;
|
|
attachmentColor = region.color;
|
|
}
|
|
else if (attachment instanceof spine.MeshAttachment) {
|
|
var mesh = attachment;
|
|
renderable.vertices = this.vertices;
|
|
renderable.numVertices = (mesh.worldVerticesLength >> 1);
|
|
renderable.numFloats = renderable.numVertices * clippedVertexSize;
|
|
if (renderable.numFloats > renderable.vertices.length) {
|
|
renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
|
|
}
|
|
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
|
|
triangles = mesh.triangles;
|
|
texture = mesh.region.renderObject.texture;
|
|
uvs = mesh.uvs;
|
|
attachmentColor = mesh.color;
|
|
}
|
|
else if (attachment instanceof spine.ClippingAttachment) {
|
|
var clip = (attachment);
|
|
clipper.clipStart(slot, clip);
|
|
continue;
|
|
}
|
|
else {
|
|
clipper.clipEndWithSlot(slot);
|
|
continue;
|
|
}
|
|
if (texture != null) {
|
|
var slotColor = slot.color;
|
|
var finalColor = this.tempColor;
|
|
finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
|
|
finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
|
|
finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
|
|
finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
|
|
if (premultipliedAlpha) {
|
|
finalColor.r *= finalColor.a;
|
|
finalColor.g *= finalColor.a;
|
|
finalColor.b *= finalColor.a;
|
|
}
|
|
var darkColor = this.tempColor2;
|
|
if (slot.darkColor == null)
|
|
darkColor.set(0, 0, 0, 1.0);
|
|
else {
|
|
if (premultipliedAlpha) {
|
|
darkColor.r = slot.darkColor.r * finalColor.a;
|
|
darkColor.g = slot.darkColor.g * finalColor.a;
|
|
darkColor.b = slot.darkColor.b * finalColor.a;
|
|
}
|
|
else {
|
|
darkColor.setFromColor(slot.darkColor);
|
|
}
|
|
darkColor.a = premultipliedAlpha ? 1.0 : 0.0;
|
|
}
|
|
var slotBlendMode = slot.data.blendMode;
|
|
if (slotBlendMode != blendMode) {
|
|
blendMode = slotBlendMode;
|
|
batcher.setBlendMode(webgl.WebGLBlendModeConverter.getSourceGLBlendMode(blendMode, premultipliedAlpha), webgl.WebGLBlendModeConverter.getDestGLBlendMode(blendMode));
|
|
}
|
|
if (clipper.isClipping()) {
|
|
clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
|
|
var clippedVertices = new Float32Array(clipper.clippedVertices);
|
|
var clippedTriangles = clipper.clippedTriangles;
|
|
if (this.vertexEffect != null) {
|
|
var vertexEffect = this.vertexEffect;
|
|
var verts = clippedVertices;
|
|
if (!twoColorTint) {
|
|
for (var v = 0, n_4 = clippedVertices.length; v < n_4; v += vertexSize) {
|
|
tempPos.x = verts[v];
|
|
tempPos.y = verts[v + 1];
|
|
tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
|
|
tempUv.x = verts[v + 6];
|
|
tempUv.y = verts[v + 7];
|
|
tempDark.set(0, 0, 0, 0);
|
|
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
|
|
verts[v] = tempPos.x;
|
|
verts[v + 1] = tempPos.y;
|
|
verts[v + 2] = tempLight.r;
|
|
verts[v + 3] = tempLight.g;
|
|
verts[v + 4] = tempLight.b;
|
|
verts[v + 5] = tempLight.a;
|
|
verts[v + 6] = tempUv.x;
|
|
verts[v + 7] = tempUv.y;
|
|
}
|
|
}
|
|
else {
|
|
for (var v = 0, n_5 = clippedVertices.length; v < n_5; v += vertexSize) {
|
|
tempPos.x = verts[v];
|
|
tempPos.y = verts[v + 1];
|
|
tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
|
|
tempUv.x = verts[v + 6];
|
|
tempUv.y = verts[v + 7];
|
|
tempDark.set(verts[v + 8], verts[v + 9], verts[v + 10], verts[v + 11]);
|
|
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
|
|
verts[v] = tempPos.x;
|
|
verts[v + 1] = tempPos.y;
|
|
verts[v + 2] = tempLight.r;
|
|
verts[v + 3] = tempLight.g;
|
|
verts[v + 4] = tempLight.b;
|
|
verts[v + 5] = tempLight.a;
|
|
verts[v + 6] = tempUv.x;
|
|
verts[v + 7] = tempUv.y;
|
|
verts[v + 8] = tempDark.r;
|
|
verts[v + 9] = tempDark.g;
|
|
verts[v + 10] = tempDark.b;
|
|
verts[v + 11] = tempDark.a;
|
|
}
|
|
}
|
|
}
|
|
batcher.draw(texture, clippedVertices, clippedTriangles);
|
|
}
|
|
else {
|
|
var verts = renderable.vertices;
|
|
if (this.vertexEffect != null) {
|
|
var vertexEffect = this.vertexEffect;
|
|
if (!twoColorTint) {
|
|
for (var v = 0, u = 0, n_6 = renderable.numFloats; v < n_6; v += vertexSize, u += 2) {
|
|
tempPos.x = verts[v];
|
|
tempPos.y = verts[v + 1];
|
|
tempUv.x = uvs[u];
|
|
tempUv.y = uvs[u + 1];
|
|
tempLight.setFromColor(finalColor);
|
|
tempDark.set(0, 0, 0, 0);
|
|
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
|
|
verts[v] = tempPos.x;
|
|
verts[v + 1] = tempPos.y;
|
|
verts[v + 2] = tempLight.r;
|
|
verts[v + 3] = tempLight.g;
|
|
verts[v + 4] = tempLight.b;
|
|
verts[v + 5] = tempLight.a;
|
|
verts[v + 6] = tempUv.x;
|
|
verts[v + 7] = tempUv.y;
|
|
}
|
|
}
|
|
else {
|
|
for (var v = 0, u = 0, n_7 = renderable.numFloats; v < n_7; v += vertexSize, u += 2) {
|
|
tempPos.x = verts[v];
|
|
tempPos.y = verts[v + 1];
|
|
tempUv.x = uvs[u];
|
|
tempUv.y = uvs[u + 1];
|
|
tempLight.setFromColor(finalColor);
|
|
tempDark.setFromColor(darkColor);
|
|
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
|
|
verts[v] = tempPos.x;
|
|
verts[v + 1] = tempPos.y;
|
|
verts[v + 2] = tempLight.r;
|
|
verts[v + 3] = tempLight.g;
|
|
verts[v + 4] = tempLight.b;
|
|
verts[v + 5] = tempLight.a;
|
|
verts[v + 6] = tempUv.x;
|
|
verts[v + 7] = tempUv.y;
|
|
verts[v + 8] = tempDark.r;
|
|
verts[v + 9] = tempDark.g;
|
|
verts[v + 10] = tempDark.b;
|
|
verts[v + 11] = tempDark.a;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (!twoColorTint) {
|
|
for (var v = 2, u = 0, n_8 = renderable.numFloats; v < n_8; v += vertexSize, u += 2) {
|
|
verts[v] = finalColor.r;
|
|
verts[v + 1] = finalColor.g;
|
|
verts[v + 2] = finalColor.b;
|
|
verts[v + 3] = finalColor.a;
|
|
verts[v + 4] = uvs[u];
|
|
verts[v + 5] = uvs[u + 1];
|
|
}
|
|
}
|
|
else {
|
|
for (var v = 2, u = 0, n_9 = renderable.numFloats; v < n_9; v += vertexSize, u += 2) {
|
|
verts[v] = finalColor.r;
|
|
verts[v + 1] = finalColor.g;
|
|
verts[v + 2] = finalColor.b;
|
|
verts[v + 3] = finalColor.a;
|
|
verts[v + 4] = uvs[u];
|
|
verts[v + 5] = uvs[u + 1];
|
|
verts[v + 6] = darkColor.r;
|
|
verts[v + 7] = darkColor.g;
|
|
verts[v + 8] = darkColor.b;
|
|
verts[v + 9] = darkColor.a;
|
|
}
|
|
}
|
|
}
|
|
var view = renderable.vertices.subarray(0, renderable.numFloats);
|
|
batcher.draw(texture, view, triangles);
|
|
}
|
|
}
|
|
clipper.clipEndWithSlot(slot);
|
|
}
|
|
clipper.clipEnd();
|
|
};
|
|
SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
|
return SkeletonRenderer;
|
|
}());
|
|
webgl.SkeletonRenderer = SkeletonRenderer;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var Vector3 = (function () {
|
|
function Vector3(x, y, z) {
|
|
if (x === void 0) { x = 0; }
|
|
if (y === void 0) { y = 0; }
|
|
if (z === void 0) { z = 0; }
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
Vector3.prototype.setFrom = function (v) {
|
|
this.x = v.x;
|
|
this.y = v.y;
|
|
this.z = v.z;
|
|
return this;
|
|
};
|
|
Vector3.prototype.set = function (x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
return this;
|
|
};
|
|
Vector3.prototype.add = function (v) {
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z;
|
|
return this;
|
|
};
|
|
Vector3.prototype.sub = function (v) {
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
this.z -= v.z;
|
|
return this;
|
|
};
|
|
Vector3.prototype.scale = function (s) {
|
|
this.x *= s;
|
|
this.y *= s;
|
|
this.z *= s;
|
|
return this;
|
|
};
|
|
Vector3.prototype.normalize = function () {
|
|
var len = this.length();
|
|
if (len == 0)
|
|
return this;
|
|
len = 1 / len;
|
|
this.x *= len;
|
|
this.y *= len;
|
|
this.z *= len;
|
|
return this;
|
|
};
|
|
Vector3.prototype.cross = function (v) {
|
|
return this.set(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x);
|
|
};
|
|
Vector3.prototype.multiply = function (matrix) {
|
|
var l_mat = matrix.values;
|
|
return this.set(this.x * l_mat[webgl.M00] + this.y * l_mat[webgl.M01] + this.z * l_mat[webgl.M02] + l_mat[webgl.M03], this.x * l_mat[webgl.M10] + this.y * l_mat[webgl.M11] + this.z * l_mat[webgl.M12] + l_mat[webgl.M13], this.x * l_mat[webgl.M20] + this.y * l_mat[webgl.M21] + this.z * l_mat[webgl.M22] + l_mat[webgl.M23]);
|
|
};
|
|
Vector3.prototype.project = function (matrix) {
|
|
var l_mat = matrix.values;
|
|
var l_w = 1 / (this.x * l_mat[webgl.M30] + this.y * l_mat[webgl.M31] + this.z * l_mat[webgl.M32] + l_mat[webgl.M33]);
|
|
return this.set((this.x * l_mat[webgl.M00] + this.y * l_mat[webgl.M01] + this.z * l_mat[webgl.M02] + l_mat[webgl.M03]) * l_w, (this.x * l_mat[webgl.M10] + this.y * l_mat[webgl.M11] + this.z * l_mat[webgl.M12] + l_mat[webgl.M13]) * l_w, (this.x * l_mat[webgl.M20] + this.y * l_mat[webgl.M21] + this.z * l_mat[webgl.M22] + l_mat[webgl.M23]) * l_w);
|
|
};
|
|
Vector3.prototype.dot = function (v) {
|
|
return this.x * v.x + this.y * v.y + this.z * v.z;
|
|
};
|
|
Vector3.prototype.length = function () {
|
|
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
|
};
|
|
Vector3.prototype.distance = function (v) {
|
|
var a = v.x - this.x;
|
|
var b = v.y - this.y;
|
|
var c = v.z - this.z;
|
|
return Math.sqrt(a * a + b * b + c * c);
|
|
};
|
|
return Vector3;
|
|
}());
|
|
webgl.Vector3 = Vector3;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
var spine;
|
|
(function (spine) {
|
|
var webgl;
|
|
(function (webgl) {
|
|
var ManagedWebGLRenderingContext = (function () {
|
|
function ManagedWebGLRenderingContext(canvasOrContext, contextConfig) {
|
|
var _this = this;
|
|
if (contextConfig === void 0) { contextConfig = { alpha: "true" }; }
|
|
this.restorables = new Array();
|
|
if (canvasOrContext instanceof HTMLCanvasElement) {
|
|
var canvas_1 = canvasOrContext;
|
|
this.gl = (canvas_1.getContext("webgl2", contextConfig) || canvas_1.getContext("webgl", contextConfig));
|
|
this.canvas = canvas_1;
|
|
canvas_1.addEventListener("webglcontextlost", function (e) {
|
|
var event = e;
|
|
if (e) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
canvas_1.addEventListener("webglcontextrestored", function (e) {
|
|
for (var i = 0, n = _this.restorables.length; i < n; i++) {
|
|
_this.restorables[i].restore();
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
this.gl = canvasOrContext;
|
|
this.canvas = this.gl.canvas;
|
|
}
|
|
}
|
|
ManagedWebGLRenderingContext.prototype.addRestorable = function (restorable) {
|
|
this.restorables.push(restorable);
|
|
};
|
|
ManagedWebGLRenderingContext.prototype.removeRestorable = function (restorable) {
|
|
var index = this.restorables.indexOf(restorable);
|
|
if (index > -1)
|
|
this.restorables.splice(index, 1);
|
|
};
|
|
return ManagedWebGLRenderingContext;
|
|
}());
|
|
webgl.ManagedWebGLRenderingContext = ManagedWebGLRenderingContext;
|
|
var WebGLBlendModeConverter = (function () {
|
|
function WebGLBlendModeConverter() {
|
|
}
|
|
WebGLBlendModeConverter.getDestGLBlendMode = function (blendMode) {
|
|
switch (blendMode) {
|
|
case spine.BlendMode.Normal: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
|
|
case spine.BlendMode.Additive: return WebGLBlendModeConverter.ONE;
|
|
case spine.BlendMode.Multiply: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
|
|
case spine.BlendMode.Screen: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
|
|
default: throw new Error("Unknown blend mode: " + blendMode);
|
|
}
|
|
};
|
|
WebGLBlendModeConverter.getSourceGLBlendMode = function (blendMode, premultipliedAlpha) {
|
|
if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
|
|
switch (blendMode) {
|
|
case spine.BlendMode.Normal: return premultipliedAlpha ? WebGLBlendModeConverter.ONE : WebGLBlendModeConverter.SRC_ALPHA;
|
|
case spine.BlendMode.Additive: return premultipliedAlpha ? WebGLBlendModeConverter.ONE : WebGLBlendModeConverter.SRC_ALPHA;
|
|
case spine.BlendMode.Multiply: return WebGLBlendModeConverter.DST_COLOR;
|
|
case spine.BlendMode.Screen: return WebGLBlendModeConverter.ONE;
|
|
default: throw new Error("Unknown blend mode: " + blendMode);
|
|
}
|
|
};
|
|
WebGLBlendModeConverter.ZERO = 0;
|
|
WebGLBlendModeConverter.ONE = 1;
|
|
WebGLBlendModeConverter.SRC_COLOR = 0x0300;
|
|
WebGLBlendModeConverter.ONE_MINUS_SRC_COLOR = 0x0301;
|
|
WebGLBlendModeConverter.SRC_ALPHA = 0x0302;
|
|
WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA = 0x0303;
|
|
WebGLBlendModeConverter.DST_ALPHA = 0x0304;
|
|
WebGLBlendModeConverter.ONE_MINUS_DST_ALPHA = 0x0305;
|
|
WebGLBlendModeConverter.DST_COLOR = 0x0306;
|
|
return WebGLBlendModeConverter;
|
|
}());
|
|
webgl.WebGLBlendModeConverter = WebGLBlendModeConverter;
|
|
})(webgl = spine.webgl || (spine.webgl = {}));
|
|
})(spine || (spine = {}));
|
|
//# sourceMappingURL=spine-both.js.map
|
|
/*** EXPORTS FROM exports-loader ***/
|
|
module.exports = spine;
|
|
|
|
}.call(window));
|
|
|
|
|
|
/***/ }),
|
|
/* 200 */
|
|
/***/ (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__(0);
|
|
var GetFastValue = __webpack_require__(11);
|
|
var ImageFile = __webpack_require__(201);
|
|
var IsPlainObject = __webpack_require__(7);
|
|
var JSONFile = __webpack_require__(215);
|
|
var MultiFile = __webpack_require__(216);
|
|
var TextFile = __webpack_require__(217);
|
|
|
|
/**
|
|
* @typedef {object} Phaser.Loader.FileTypes.SpineFileConfig
|
|
*
|
|
* @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
|
|
* @property {string|string[]} [jsonURL] - The absolute or relative URL to load the JSON file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
|
|
* @property {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
|
|
* @property {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
|
|
* @property {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
|
|
* @property {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
|
|
*/
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Spine File suitable for loading by the Loader.
|
|
*
|
|
* These are created when you use the Phaser.Loader.LoaderPlugin#spine method and are not typically created directly.
|
|
*
|
|
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#spine.
|
|
*
|
|
* @class SpineFile
|
|
* @extends Phaser.Loader.MultiFile
|
|
* @memberof Phaser.Loader.FileTypes
|
|
* @constructor
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
|
|
* @param {(string|Phaser.Loader.FileTypes.SpineFileConfig)} key - The key to use for this file, or a file configuration object.
|
|
* @param {string|string[]} [jsonURL] - The absolute or relative URL to load the JSON file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
|
|
* @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
|
|
* @param {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
|
|
* @param {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
|
|
* @param {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
|
|
*/
|
|
var SpineFile = new Class({
|
|
|
|
Extends: MultiFile,
|
|
|
|
initialize:
|
|
|
|
function SpineFile (loader, key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings)
|
|
{
|
|
var i;
|
|
var json;
|
|
var atlas;
|
|
var files = [];
|
|
var cache = loader.cacheManager.custom.spine;
|
|
|
|
// atlas can be an array of atlas files, not just a single one
|
|
|
|
if (IsPlainObject(key))
|
|
{
|
|
var config = key;
|
|
|
|
key = GetFastValue(config, 'key');
|
|
|
|
json = new JSONFile(loader, {
|
|
key: key,
|
|
url: GetFastValue(config, 'jsonURL'),
|
|
extension: GetFastValue(config, 'jsonExtension', 'json'),
|
|
xhrSettings: GetFastValue(config, 'jsonXhrSettings')
|
|
});
|
|
|
|
atlasURL = GetFastValue(config, 'atlasURL');
|
|
preMultipliedAlpha = GetFastValue(config, 'preMultipliedAlpha');
|
|
|
|
if (!Array.isArray(atlasURL))
|
|
{
|
|
atlasURL = [ atlasURL ];
|
|
}
|
|
|
|
for (i = 0; i < atlasURL.length; i++)
|
|
{
|
|
atlas = new TextFile(loader, {
|
|
key: key + '!' + i,
|
|
url: atlasURL[i],
|
|
extension: GetFastValue(config, 'atlasExtension', 'atlas'),
|
|
xhrSettings: GetFastValue(config, 'atlasXhrSettings')
|
|
});
|
|
|
|
atlas.cache = cache;
|
|
|
|
files.push(atlas);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
json = new JSONFile(loader, key, jsonURL, jsonXhrSettings);
|
|
|
|
if (!Array.isArray(atlasURL))
|
|
{
|
|
atlasURL = [ atlasURL ];
|
|
}
|
|
|
|
for (i = 0; i < atlasURL.length; i++)
|
|
{
|
|
atlas = new TextFile(loader, key + '!' + i, atlasURL[i], atlasXhrSettings);
|
|
atlas.cache = cache;
|
|
|
|
files.push(atlas);
|
|
}
|
|
}
|
|
|
|
files.unshift(json);
|
|
|
|
MultiFile.call(this, loader, 'spine', key, files);
|
|
|
|
this.config.preMultipliedAlpha = preMultipliedAlpha;
|
|
},
|
|
|
|
/**
|
|
* Called by each File when it finishes loading.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.SpineFile#onFileComplete
|
|
* @since 3.19.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - The File that has completed processing.
|
|
*/
|
|
onFileComplete: function (file)
|
|
{
|
|
var index = this.files.indexOf(file);
|
|
|
|
if (index !== -1)
|
|
{
|
|
this.pending--;
|
|
|
|
if (file.type === 'text')
|
|
{
|
|
// Inspect the data for the files to now load
|
|
var content = file.data.split('\n');
|
|
|
|
// Extract the textures
|
|
var textures = [];
|
|
|
|
for (var t = 0; t < content.length; t++)
|
|
{
|
|
var line = content[t];
|
|
|
|
if (line.trim() === '' && t < content.length - 1)
|
|
{
|
|
line = content[t + 1];
|
|
|
|
textures.push(line);
|
|
}
|
|
}
|
|
|
|
var config = this.config;
|
|
var loader = this.loader;
|
|
|
|
var currentBaseURL = loader.baseURL;
|
|
var currentPath = loader.path;
|
|
var currentPrefix = loader.prefix;
|
|
|
|
var baseURL = GetFastValue(config, 'baseURL', this.baseURL);
|
|
var path = GetFastValue(config, 'path', file.src.match(/^.*\//))[0];
|
|
var prefix = GetFastValue(config, 'prefix', this.prefix);
|
|
var textureXhrSettings = GetFastValue(config, 'textureXhrSettings');
|
|
|
|
loader.setBaseURL(baseURL);
|
|
loader.setPath(path);
|
|
loader.setPrefix(prefix);
|
|
|
|
for (var i = 0; i < textures.length; i++)
|
|
{
|
|
var textureURL = textures[i];
|
|
|
|
var key = this.prefix + textureURL;
|
|
|
|
var image = new ImageFile(loader, key, textureURL, textureXhrSettings);
|
|
|
|
if (!loader.keyExists(image))
|
|
{
|
|
this.addToMultiFile(image);
|
|
|
|
loader.addFile(image);
|
|
}
|
|
}
|
|
|
|
// Reset the loader settings
|
|
loader.setBaseURL(currentBaseURL);
|
|
loader.setPath(currentPath);
|
|
loader.setPrefix(currentPrefix);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Adds this file to its target cache upon successful loading and processing.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.SpineFile#addToCache
|
|
* @since 3.19.0
|
|
*/
|
|
addToCache: function ()
|
|
{
|
|
if (this.isReadyToProcess())
|
|
{
|
|
var fileJSON = this.files[0];
|
|
|
|
fileJSON.addToCache();
|
|
|
|
var atlasCache;
|
|
var atlasKey = '';
|
|
var combinedAtlasData = '';
|
|
var preMultipliedAlpha = (this.config.preMultipliedAlpha) ? true : false;
|
|
var textureManager = this.loader.textureManager;
|
|
|
|
for (var i = 1; i < this.files.length; i++)
|
|
{
|
|
var file = this.files[i];
|
|
|
|
if (file.type === 'text')
|
|
{
|
|
atlasKey = file.key.replace(/![\d]$/, '');
|
|
|
|
atlasCache = file.cache;
|
|
|
|
combinedAtlasData = combinedAtlasData.concat(file.data);
|
|
}
|
|
else
|
|
{
|
|
var src = file.key.trim();
|
|
var pos = src.indexOf('!');
|
|
var key = src.substr(pos + 1);
|
|
|
|
if (!textureManager.exists(key))
|
|
{
|
|
textureManager.addImage(key, file.data);
|
|
}
|
|
}
|
|
|
|
file.pendingDestroy();
|
|
}
|
|
|
|
atlasCache.add(atlasKey, { preMultipliedAlpha: preMultipliedAlpha, data: combinedAtlasData, prefix: this.prefix });
|
|
|
|
this.complete = true;
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = SpineFile;
|
|
|
|
|
|
/***/ }),
|
|
/* 201 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var CONST = __webpack_require__(14);
|
|
var File = __webpack_require__(21);
|
|
var FileTypesManager = __webpack_require__(22);
|
|
var GetFastValue = __webpack_require__(11);
|
|
var IsPlainObject = __webpack_require__(7);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A single Image File suitable for loading by the Loader.
|
|
*
|
|
* These are created when you use the Phaser.Loader.LoaderPlugin#image method and are not typically created directly.
|
|
*
|
|
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#image.
|
|
*
|
|
* @class ImageFile
|
|
* @extends Phaser.Loader.File
|
|
* @memberof Phaser.Loader.FileTypes
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig)} key - The key to use for this file, or a file configuration object.
|
|
* @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
|
|
* @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. Only provided for, and used by, Sprite Sheets.
|
|
*/
|
|
var ImageFile = new Class({
|
|
|
|
Extends: File,
|
|
|
|
initialize:
|
|
|
|
function ImageFile (loader, key, url, xhrSettings, frameConfig)
|
|
{
|
|
var extension = 'png';
|
|
var normalMapURL;
|
|
|
|
if (IsPlainObject(key))
|
|
{
|
|
var config = key;
|
|
|
|
key = GetFastValue(config, 'key');
|
|
url = GetFastValue(config, 'url');
|
|
normalMapURL = GetFastValue(config, 'normalMap');
|
|
xhrSettings = GetFastValue(config, 'xhrSettings');
|
|
extension = GetFastValue(config, 'extension', extension);
|
|
frameConfig = GetFastValue(config, 'frameConfig');
|
|
}
|
|
|
|
if (Array.isArray(url))
|
|
{
|
|
normalMapURL = url[1];
|
|
url = url[0];
|
|
}
|
|
|
|
var fileConfig = {
|
|
type: 'image',
|
|
cache: loader.textureManager,
|
|
extension: extension,
|
|
responseType: 'blob',
|
|
key: key,
|
|
url: url,
|
|
xhrSettings: xhrSettings,
|
|
config: frameConfig
|
|
};
|
|
|
|
File.call(this, loader, fileConfig);
|
|
|
|
// Do we have a normal map to load as well?
|
|
if (normalMapURL)
|
|
{
|
|
var normalMap = new ImageFile(loader, this.key, normalMapURL, xhrSettings, frameConfig);
|
|
|
|
normalMap.type = 'normalMap';
|
|
|
|
this.setLink(normalMap);
|
|
|
|
loader.addFile(normalMap);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called automatically by Loader.nextFile.
|
|
* This method controls what extra work this File does with its loaded data.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.ImageFile#onProcess
|
|
* @since 3.7.0
|
|
*/
|
|
onProcess: function ()
|
|
{
|
|
this.state = CONST.FILE_PROCESSING;
|
|
|
|
this.data = new Image();
|
|
|
|
this.data.crossOrigin = this.crossOrigin;
|
|
|
|
var _this = this;
|
|
|
|
this.data.onload = function ()
|
|
{
|
|
File.revokeObjectURL(_this.data);
|
|
|
|
_this.onProcessComplete();
|
|
};
|
|
|
|
this.data.onerror = function ()
|
|
{
|
|
File.revokeObjectURL(_this.data);
|
|
|
|
_this.onProcessError();
|
|
};
|
|
|
|
File.createObjectURL(this.data, this.xhrLoader.response, 'image/png');
|
|
},
|
|
|
|
/**
|
|
* Adds this file to its target cache upon successful loading and processing.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.ImageFile#addToCache
|
|
* @since 3.7.0
|
|
*/
|
|
addToCache: function ()
|
|
{
|
|
var texture;
|
|
var linkFile = this.linkFile;
|
|
|
|
if (linkFile && linkFile.state === CONST.FILE_COMPLETE)
|
|
{
|
|
if (this.type === 'image')
|
|
{
|
|
texture = this.cache.addImage(this.key, this.data, linkFile.data);
|
|
}
|
|
else
|
|
{
|
|
texture = this.cache.addImage(linkFile.key, linkFile.data, this.data);
|
|
}
|
|
|
|
this.pendingDestroy(texture);
|
|
|
|
linkFile.pendingDestroy(texture);
|
|
}
|
|
else if (!linkFile)
|
|
{
|
|
texture = this.cache.addImage(this.key, this.data);
|
|
|
|
this.pendingDestroy(texture);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* Adds an Image, or array of Images, to the current load queue.
|
|
*
|
|
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
|
|
*
|
|
* ```javascript
|
|
* function preload ()
|
|
* {
|
|
* this.load.image('logo', 'images/phaserLogo.png');
|
|
* }
|
|
* ```
|
|
*
|
|
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
|
|
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
|
|
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
|
|
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
|
|
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
|
|
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
|
|
* loaded.
|
|
*
|
|
* Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle.
|
|
* If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback
|
|
* of animated gifs to Canvas elements.
|
|
*
|
|
* The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load.
|
|
* The key should be unique both in terms of files being loaded and files already present in the Texture Manager.
|
|
* Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
|
|
* then remove it from the Texture Manager first, before loading a new one.
|
|
*
|
|
* Instead of passing arguments you can pass a configuration object, such as:
|
|
*
|
|
* ```javascript
|
|
* this.load.image({
|
|
* key: 'logo',
|
|
* url: 'images/AtariLogo.png'
|
|
* });
|
|
* ```
|
|
*
|
|
* See the documentation for `Phaser.Types.Loader.FileTypes.ImageFileConfig` for more details.
|
|
*
|
|
* Once the file has finished loading you can use it as a texture for a Game Object by referencing its key:
|
|
*
|
|
* ```javascript
|
|
* this.load.image('logo', 'images/AtariLogo.png');
|
|
* // and later in your game ...
|
|
* this.add.image(x, y, 'logo');
|
|
* ```
|
|
*
|
|
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
|
|
* key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
|
|
* this is what you would use to retrieve the image from the Texture Manager.
|
|
*
|
|
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
|
|
*
|
|
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
|
|
* and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although
|
|
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
|
|
*
|
|
* Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image,
|
|
* then you can specify it by providing an array as the `url` where the second element is the normal map:
|
|
*
|
|
* ```javascript
|
|
* this.load.image('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ]);
|
|
* ```
|
|
*
|
|
* Or, if you are using a config object use the `normalMap` property:
|
|
*
|
|
* ```javascript
|
|
* this.load.image({
|
|
* key: 'logo',
|
|
* url: 'images/AtariLogo.png',
|
|
* normalMap: 'images/AtariLogo-n.png'
|
|
* });
|
|
* ```
|
|
*
|
|
* The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings.
|
|
* Normal maps are a WebGL only feature.
|
|
*
|
|
* Note: The ability to load this type of file will only be available if the Image File type has been built into Phaser.
|
|
* It is available in the default build but can be excluded from custom builds.
|
|
*
|
|
* @method Phaser.Loader.LoaderPlugin#image
|
|
* @fires Phaser.Loader.LoaderPlugin#ADD
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig|Phaser.Types.Loader.FileTypes.ImageFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
|
|
* @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
|
|
*
|
|
* @return {this} The Loader instance.
|
|
*/
|
|
FileTypesManager.register('image', function (key, url, xhrSettings)
|
|
{
|
|
if (Array.isArray(key))
|
|
{
|
|
for (var i = 0; i < key.length; i++)
|
|
{
|
|
// If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
|
|
this.addFile(new ImageFile(this, key[i]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.addFile(new ImageFile(this, key, url, xhrSettings));
|
|
}
|
|
|
|
return this;
|
|
});
|
|
|
|
module.exports = ImageFile;
|
|
|
|
|
|
/***/ }),
|
|
/* 202 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Loader.Events
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
ADD: __webpack_require__(203),
|
|
COMPLETE: __webpack_require__(204),
|
|
FILE_COMPLETE: __webpack_require__(205),
|
|
FILE_KEY_COMPLETE: __webpack_require__(206),
|
|
FILE_LOAD_ERROR: __webpack_require__(207),
|
|
FILE_LOAD: __webpack_require__(208),
|
|
FILE_PROGRESS: __webpack_require__(209),
|
|
POST_PROCESS: __webpack_require__(210),
|
|
PROGRESS: __webpack_require__(211),
|
|
START: __webpack_require__(212)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 203 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Loader Plugin Add File Event.
|
|
*
|
|
* This event is dispatched when a new file is successfully added to the Loader and placed into the load queue.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('addfile', listener)`.
|
|
*
|
|
* If you add lots of files to a Loader from a `preload` method, it will dispatch this event for each one of them.
|
|
*
|
|
* @event Phaser.Loader.Events#ADD
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key - The unique key of the file that was added to the Loader.
|
|
* @param {string} type - The [file type]{@link Phaser.Loader.File#type} string of the file that was added to the Loader, i.e. `image`.
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
|
|
* @param {Phaser.Loader.File} file - A reference to the File which was added to the Loader.
|
|
*/
|
|
module.exports = 'addfile';
|
|
|
|
|
|
/***/ }),
|
|
/* 204 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Loader Plugin Complete Event.
|
|
*
|
|
* This event is dispatched when the Loader has fully processed everything in the load queue.
|
|
* By this point every loaded file will now be in its associated cache and ready for use.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('complete', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#COMPLETE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
|
|
* @param {integer} totalComplete - The total number of files that successfully loaded.
|
|
* @param {integer} totalFailed - The total number of files that failed to load.
|
|
*/
|
|
module.exports = 'complete';
|
|
|
|
|
|
/***/ }),
|
|
/* 205 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The File Load Complete Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin when any file in the queue finishes loading.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('filecomplete', listener)`.
|
|
*
|
|
* You can also listen for the completion of a specific file. See the [FILE_KEY_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_KEY_COMPLETE} event.
|
|
*
|
|
* @event Phaser.Loader.Events#FILE_COMPLETE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key - The key of the file that just loaded and finished processing.
|
|
* @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`.
|
|
* @param {any} data - The raw data the file contained.
|
|
*/
|
|
module.exports = 'filecomplete';
|
|
|
|
|
|
/***/ }),
|
|
/* 206 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The File Load Complete Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin when any file in the queue finishes loading.
|
|
*
|
|
* It uses a special dynamic event name constructed from the key and type of the file.
|
|
*
|
|
* For example, if you have loaded an `image` with a key of `monster`, you can listen for it
|
|
* using the following:
|
|
*
|
|
* ```javascript
|
|
* this.load.on('filecomplete-image-monster', function (key, type, data) {
|
|
* // Your handler code
|
|
* });
|
|
* ```
|
|
*
|
|
* Or, if you have loaded a texture `atlas` with a key of `Level1`:
|
|
*
|
|
* ```javascript
|
|
* this.load.on('filecomplete-atlas-Level1', function (key, type, data) {
|
|
* // Your handler code
|
|
* });
|
|
* ```
|
|
*
|
|
* Or, if you have loaded a sprite sheet with a key of `Explosion` and a prefix of `GAMEOVER`:
|
|
*
|
|
* ```javascript
|
|
* this.load.on('filecomplete-spritesheet-GAMEOVERExplosion', function (key, type, data) {
|
|
* // Your handler code
|
|
* });
|
|
* ```
|
|
*
|
|
* You can also listen for the generic completion of files. See the [FILE_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_COMPLETE} event.
|
|
*
|
|
* @event Phaser.Loader.Events#FILE_KEY_COMPLETE
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key - The key of the file that just loaded and finished processing.
|
|
* @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`.
|
|
* @param {any} data - The raw data the file contained.
|
|
*/
|
|
module.exports = 'filecomplete-';
|
|
|
|
|
|
/***/ }),
|
|
/* 207 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The File Load Error Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin when a file fails to load.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('loaderror', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#FILE_LOAD_ERROR
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - A reference to the File which errored during load.
|
|
*/
|
|
module.exports = 'loaderror';
|
|
|
|
|
|
/***/ }),
|
|
/* 208 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The File Load Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin when a file finishes loading,
|
|
* but _before_ it is processed and added to the internal Phaser caches.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('load', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#FILE_LOAD
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - A reference to the File which just finished loading.
|
|
*/
|
|
module.exports = 'load';
|
|
|
|
|
|
/***/ }),
|
|
/* 209 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The File Load Progress Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin during the load of a file, if the browser receives a DOM ProgressEvent and
|
|
* the `lengthComputable` event property is true. Depending on the size of the file and browser in use, this may, or may not happen.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('fileprogress', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#FILE_PROGRESS
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - A reference to the File which errored during load.
|
|
* @param {number} percentComplete - A value between 0 and 1 indicating how 'complete' this file is.
|
|
*/
|
|
module.exports = 'fileprogress';
|
|
|
|
|
|
/***/ }),
|
|
/* 210 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Loader Plugin Post Process Event.
|
|
*
|
|
* This event is dispatched by the Loader Plugin when the Loader has finished loading everything in the load queue.
|
|
* It is dispatched before the internal lists are cleared and each File is destroyed.
|
|
*
|
|
* Use this hook to perform any last minute processing of files that can only happen once the
|
|
* Loader has completed, but prior to it emitting the `complete` event.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('postprocess', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#POST_PROCESS
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
|
|
*/
|
|
module.exports = 'postprocess';
|
|
|
|
|
|
/***/ }),
|
|
/* 211 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Loader Plugin Progress Event.
|
|
*
|
|
* This event is dispatched when the Loader updates its load progress, typically as a result of a file having completed loading.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('progress', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#PROGRESS
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} progress - The current progress of the load. A value between 0 and 1.
|
|
*/
|
|
module.exports = 'progress';
|
|
|
|
|
|
/***/ }),
|
|
/* 212 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Loader Plugin Start Event.
|
|
*
|
|
* This event is dispatched when the Loader starts running. At this point load progress is zero.
|
|
*
|
|
* This event is dispatched even if there aren't any files in the load queue.
|
|
*
|
|
* Listen to it from a Scene using: `this.load.on('start', listener)`.
|
|
*
|
|
* @event Phaser.Loader.Events#START
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
|
|
*/
|
|
module.exports = 'start';
|
|
|
|
|
|
/***/ }),
|
|
/* 213 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Given a File and a baseURL value this returns the URL the File will use to download from.
|
|
*
|
|
* @function Phaser.Loader.GetURL
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - The File object.
|
|
* @param {string} baseURL - A default base URL.
|
|
*
|
|
* @return {string} The URL the File will use.
|
|
*/
|
|
var GetURL = function (file, baseURL)
|
|
{
|
|
if (!file.url)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (file.url.match(/^(?:blob:|data:|http:\/\/|https:\/\/|\/\/)/))
|
|
{
|
|
return file.url;
|
|
}
|
|
else
|
|
{
|
|
return baseURL + file.url;
|
|
}
|
|
};
|
|
|
|
module.exports = GetURL;
|
|
|
|
|
|
/***/ }),
|
|
/* 214 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var MergeXHRSettings = __webpack_require__(44);
|
|
|
|
/**
|
|
* Creates a new XMLHttpRequest (xhr) object based on the given File and XHRSettings
|
|
* and starts the download of it. It uses the Files own XHRSettings and merges them
|
|
* with the global XHRSettings object to set the xhr values before download.
|
|
*
|
|
* @function Phaser.Loader.XHRLoader
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - The File to download.
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} globalXHRSettings - The global XHRSettings object.
|
|
*
|
|
* @return {XMLHttpRequest} The XHR object.
|
|
*/
|
|
var XHRLoader = function (file, globalXHRSettings)
|
|
{
|
|
var config = MergeXHRSettings(globalXHRSettings, file.xhrSettings);
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
xhr.open('GET', file.src, config.async, config.user, config.password);
|
|
|
|
xhr.responseType = file.xhrSettings.responseType;
|
|
xhr.timeout = config.timeout;
|
|
|
|
if (config.headers)
|
|
{
|
|
for (var key in config.headers)
|
|
{
|
|
xhr.setRequestHeader(key, config.headers[key]);
|
|
}
|
|
}
|
|
|
|
if (config.header && config.headerValue)
|
|
{
|
|
xhr.setRequestHeader(config.header, config.headerValue);
|
|
}
|
|
|
|
if (config.requestedWith)
|
|
{
|
|
xhr.setRequestHeader('X-Requested-With', config.requestedWith);
|
|
}
|
|
|
|
if (config.overrideMimeType)
|
|
{
|
|
xhr.overrideMimeType(config.overrideMimeType);
|
|
}
|
|
|
|
if (config.withCredentials)
|
|
{
|
|
xhr.withCredentials = true;
|
|
}
|
|
|
|
// After a successful request, the xhr.response property will contain the requested data as a DOMString, ArrayBuffer, Blob, or Document (depending on what was set for responseType.)
|
|
|
|
xhr.onload = file.onLoad.bind(file, xhr);
|
|
xhr.onerror = file.onError.bind(file, xhr);
|
|
xhr.onprogress = file.onProgress.bind(file);
|
|
|
|
// This is the only standard method, the ones above are browser additions (maybe not universal?)
|
|
// xhr.onreadystatechange
|
|
|
|
xhr.send();
|
|
|
|
return xhr;
|
|
};
|
|
|
|
module.exports = XHRLoader;
|
|
|
|
|
|
/***/ }),
|
|
/* 215 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var CONST = __webpack_require__(14);
|
|
var File = __webpack_require__(21);
|
|
var FileTypesManager = __webpack_require__(22);
|
|
var GetFastValue = __webpack_require__(11);
|
|
var GetValue = __webpack_require__(10);
|
|
var IsPlainObject = __webpack_require__(7);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A single JSON File suitable for loading by the Loader.
|
|
*
|
|
* These are created when you use the Phaser.Loader.LoaderPlugin#json method and are not typically created directly.
|
|
*
|
|
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#json.
|
|
*
|
|
* @class JSONFile
|
|
* @extends Phaser.Loader.File
|
|
* @memberof Phaser.Loader.FileTypes
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig)} key - The key to use for this file, or a file configuration object.
|
|
* @param {(object|string)} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, can be a fully formed JSON Object.
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
|
|
* @param {string} [dataKey] - When the JSON file loads only this property will be stored in the Cache.
|
|
*/
|
|
var JSONFile = new Class({
|
|
|
|
Extends: File,
|
|
|
|
initialize:
|
|
|
|
// url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object
|
|
// dataKey allows you to pluck a specific object out of the JSON and put just that into the cache, rather than the whole thing
|
|
|
|
function JSONFile (loader, key, url, xhrSettings, dataKey)
|
|
{
|
|
var extension = 'json';
|
|
|
|
if (IsPlainObject(key))
|
|
{
|
|
var config = key;
|
|
|
|
key = GetFastValue(config, 'key');
|
|
url = GetFastValue(config, 'url');
|
|
xhrSettings = GetFastValue(config, 'xhrSettings');
|
|
extension = GetFastValue(config, 'extension', extension);
|
|
dataKey = GetFastValue(config, 'dataKey', dataKey);
|
|
}
|
|
|
|
var fileConfig = {
|
|
type: 'json',
|
|
cache: loader.cacheManager.json,
|
|
extension: extension,
|
|
responseType: 'text',
|
|
key: key,
|
|
url: url,
|
|
xhrSettings: xhrSettings,
|
|
config: dataKey
|
|
};
|
|
|
|
File.call(this, loader, fileConfig);
|
|
|
|
if (IsPlainObject(url))
|
|
{
|
|
// Object provided instead of a URL, so no need to actually load it (populate data with value)
|
|
if (dataKey)
|
|
{
|
|
this.data = GetValue(url, dataKey);
|
|
}
|
|
else
|
|
{
|
|
this.data = url;
|
|
}
|
|
|
|
this.state = CONST.FILE_POPULATED;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called automatically by Loader.nextFile.
|
|
* This method controls what extra work this File does with its loaded data.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.JSONFile#onProcess
|
|
* @since 3.7.0
|
|
*/
|
|
onProcess: function ()
|
|
{
|
|
if (this.state !== CONST.FILE_POPULATED)
|
|
{
|
|
this.state = CONST.FILE_PROCESSING;
|
|
|
|
var json = JSON.parse(this.xhrLoader.responseText);
|
|
|
|
var key = this.config;
|
|
|
|
if (typeof key === 'string')
|
|
{
|
|
this.data = GetValue(json, key, json);
|
|
}
|
|
else
|
|
{
|
|
this.data = json;
|
|
}
|
|
}
|
|
|
|
this.onProcessComplete();
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* Adds a JSON file, or array of JSON files, to the current load queue.
|
|
*
|
|
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
|
|
*
|
|
* ```javascript
|
|
* function preload ()
|
|
* {
|
|
* this.load.json('wavedata', 'files/AlienWaveData.json');
|
|
* }
|
|
* ```
|
|
*
|
|
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
|
|
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
|
|
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
|
|
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
|
|
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
|
|
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
|
|
* loaded.
|
|
*
|
|
* The key must be a unique String. It is used to add the file to the global JSON Cache upon a successful load.
|
|
* The key should be unique both in terms of files being loaded and files already present in the JSON Cache.
|
|
* Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
|
|
* then remove it from the JSON Cache first, before loading a new one.
|
|
*
|
|
* Instead of passing arguments you can pass a configuration object, such as:
|
|
*
|
|
* ```javascript
|
|
* this.load.json({
|
|
* key: 'wavedata',
|
|
* url: 'files/AlienWaveData.json'
|
|
* });
|
|
* ```
|
|
*
|
|
* See the documentation for `Phaser.Types.Loader.FileTypes.JSONFileConfig` for more details.
|
|
*
|
|
* Once the file has finished loading you can access it from its Cache using its key:
|
|
*
|
|
* ```javascript
|
|
* this.load.json('wavedata', 'files/AlienWaveData.json');
|
|
* // and later in your game ...
|
|
* var data = this.cache.json.get('wavedata');
|
|
* ```
|
|
*
|
|
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
|
|
* key. For example, if the prefix was `LEVEL1.` and the key was `Waves` the final key will be `LEVEL1.Waves` and
|
|
* this is what you would use to retrieve the text from the JSON Cache.
|
|
*
|
|
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
|
|
*
|
|
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "data"
|
|
* and no URL is given then the Loader will set the URL to be "data.json". It will always add `.json` as the extension, although
|
|
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
|
|
*
|
|
* You can also optionally provide a `dataKey` to use. This allows you to extract only a part of the JSON and store it in the Cache,
|
|
* rather than the whole file. For example, if your JSON data had a structure like this:
|
|
*
|
|
* ```json
|
|
* {
|
|
* "level1": {
|
|
* "baddies": {
|
|
* "aliens": {},
|
|
* "boss": {}
|
|
* }
|
|
* },
|
|
* "level2": {},
|
|
* "level3": {}
|
|
* }
|
|
* ```
|
|
*
|
|
* And you only wanted to store the `boss` data in the Cache, then you could pass `level1.baddies.boss`as the `dataKey`.
|
|
*
|
|
* Note: The ability to load this type of file will only be available if the JSON File type has been built into Phaser.
|
|
* It is available in the default build but can be excluded from custom builds.
|
|
*
|
|
* @method Phaser.Loader.LoaderPlugin#json
|
|
* @fires Phaser.Loader.LoaderPlugin#ADD
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
|
|
* @param {(object|string)} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, can be a fully formed JSON Object.
|
|
* @param {string} [dataKey] - When the JSON file loads only this property will be stored in the Cache.
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
|
|
*
|
|
* @return {this} The Loader instance.
|
|
*/
|
|
FileTypesManager.register('json', function (key, url, dataKey, xhrSettings)
|
|
{
|
|
if (Array.isArray(key))
|
|
{
|
|
for (var i = 0; i < key.length; i++)
|
|
{
|
|
// If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
|
|
this.addFile(new JSONFile(this, key[i]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.addFile(new JSONFile(this, key, url, xhrSettings, dataKey));
|
|
}
|
|
|
|
return this;
|
|
});
|
|
|
|
module.exports = JSONFile;
|
|
|
|
|
|
/***/ }),
|
|
/* 216 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A MultiFile is a special kind of parent that contains two, or more, Files as children and looks after
|
|
* the loading and processing of them all. It is commonly extended and used as a base class for file types such as AtlasJSON or BitmapFont.
|
|
*
|
|
* You shouldn't create an instance of a MultiFile directly, but should extend it with your own class, setting a custom type and processing methods.
|
|
*
|
|
* @class MultiFile
|
|
* @memberof Phaser.Loader
|
|
* @constructor
|
|
* @since 3.7.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File.
|
|
* @param {string} type - The file type string for sorting within the Loader.
|
|
* @param {string} key - The key of the file within the loader.
|
|
* @param {Phaser.Loader.File[]} files - An array of Files that make-up this MultiFile.
|
|
*/
|
|
var MultiFile = new Class({
|
|
|
|
initialize:
|
|
|
|
function MultiFile (loader, type, key, files)
|
|
{
|
|
/**
|
|
* A reference to the Loader that is going to load this file.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#loader
|
|
* @type {Phaser.Loader.LoaderPlugin}
|
|
* @since 3.7.0
|
|
*/
|
|
this.loader = loader;
|
|
|
|
/**
|
|
* The file type string for sorting within the Loader.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#type
|
|
* @type {string}
|
|
* @since 3.7.0
|
|
*/
|
|
this.type = type;
|
|
|
|
/**
|
|
* Unique cache key (unique within its file type)
|
|
*
|
|
* @name Phaser.Loader.MultiFile#key
|
|
* @type {string}
|
|
* @since 3.7.0
|
|
*/
|
|
this.key = key;
|
|
|
|
/**
|
|
* The current index being used by multi-file loaders to avoid key clashes.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#multiKeyIndex
|
|
* @type {integer}
|
|
* @private
|
|
* @since 3.20.0
|
|
*/
|
|
this.multiKeyIndex = loader.multiKeyIndex++;
|
|
|
|
/**
|
|
* Array of files that make up this MultiFile.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#files
|
|
* @type {Phaser.Loader.File[]}
|
|
* @since 3.7.0
|
|
*/
|
|
this.files = files;
|
|
|
|
/**
|
|
* The completion status of this MultiFile.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#complete
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.7.0
|
|
*/
|
|
this.complete = false;
|
|
|
|
/**
|
|
* The number of files to load.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#pending
|
|
* @type {integer}
|
|
* @since 3.7.0
|
|
*/
|
|
|
|
this.pending = files.length;
|
|
|
|
/**
|
|
* The number of files that failed to load.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#failed
|
|
* @type {integer}
|
|
* @default 0
|
|
* @since 3.7.0
|
|
*/
|
|
this.failed = 0;
|
|
|
|
/**
|
|
* A storage container for transient data that the loading files need.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#config
|
|
* @type {any}
|
|
* @since 3.7.0
|
|
*/
|
|
this.config = {};
|
|
|
|
/**
|
|
* A reference to the Loaders baseURL at the time this MultiFile was created.
|
|
* Used to populate child-files.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#baseURL
|
|
* @type {string}
|
|
* @since 3.20.0
|
|
*/
|
|
this.baseURL = loader.baseURL;
|
|
|
|
/**
|
|
* A reference to the Loaders path at the time this MultiFile was created.
|
|
* Used to populate child-files.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#path
|
|
* @type {string}
|
|
* @since 3.20.0
|
|
*/
|
|
this.path = loader.path;
|
|
|
|
/**
|
|
* A reference to the Loaders prefix at the time this MultiFile was created.
|
|
* Used to populate child-files.
|
|
*
|
|
* @name Phaser.Loader.MultiFile#prefix
|
|
* @type {string}
|
|
* @since 3.20.0
|
|
*/
|
|
this.prefix = loader.prefix;
|
|
|
|
// Link the files
|
|
for (var i = 0; i < files.length; i++)
|
|
{
|
|
files[i].multiFile = this;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Checks if this MultiFile is ready to process its children or not.
|
|
*
|
|
* @method Phaser.Loader.MultiFile#isReadyToProcess
|
|
* @since 3.7.0
|
|
*
|
|
* @return {boolean} `true` if all children of this MultiFile have loaded, otherwise `false`.
|
|
*/
|
|
isReadyToProcess: function ()
|
|
{
|
|
return (this.pending === 0 && this.failed === 0 && !this.complete);
|
|
},
|
|
|
|
/**
|
|
* Adds another child to this MultiFile, increases the pending count and resets the completion status.
|
|
*
|
|
* @method Phaser.Loader.MultiFile#addToMultiFile
|
|
* @since 3.7.0
|
|
*
|
|
* @param {Phaser.Loader.File} files - The File to add to this MultiFile.
|
|
*
|
|
* @return {Phaser.Loader.MultiFile} This MultiFile instance.
|
|
*/
|
|
addToMultiFile: function (file)
|
|
{
|
|
this.files.push(file);
|
|
|
|
file.multiFile = this;
|
|
|
|
this.pending++;
|
|
|
|
this.complete = false;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Called by each File when it finishes loading.
|
|
*
|
|
* @method Phaser.Loader.MultiFile#onFileComplete
|
|
* @since 3.7.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - The File that has completed processing.
|
|
*/
|
|
onFileComplete: function (file)
|
|
{
|
|
var index = this.files.indexOf(file);
|
|
|
|
if (index !== -1)
|
|
{
|
|
this.pending--;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called by each File that fails to load.
|
|
*
|
|
* @method Phaser.Loader.MultiFile#onFileFailed
|
|
* @since 3.7.0
|
|
*
|
|
* @param {Phaser.Loader.File} file - The File that has failed to load.
|
|
*/
|
|
onFileFailed: function (file)
|
|
{
|
|
var index = this.files.indexOf(file);
|
|
|
|
if (index !== -1)
|
|
{
|
|
this.failed++;
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = MultiFile;
|
|
|
|
|
|
/***/ }),
|
|
/* 217 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var CONST = __webpack_require__(14);
|
|
var File = __webpack_require__(21);
|
|
var FileTypesManager = __webpack_require__(22);
|
|
var GetFastValue = __webpack_require__(11);
|
|
var IsPlainObject = __webpack_require__(7);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A single Text File suitable for loading by the Loader.
|
|
*
|
|
* These are created when you use the Phaser.Loader.LoaderPlugin#text method and are not typically created directly.
|
|
*
|
|
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#text.
|
|
*
|
|
* @class TextFile
|
|
* @extends Phaser.Loader.File
|
|
* @memberof Phaser.Loader.FileTypes
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig)} key - The key to use for this file, or a file configuration object.
|
|
* @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
|
|
*/
|
|
var TextFile = new Class({
|
|
|
|
Extends: File,
|
|
|
|
initialize:
|
|
|
|
function TextFile (loader, key, url, xhrSettings)
|
|
{
|
|
var extension = 'txt';
|
|
|
|
if (IsPlainObject(key))
|
|
{
|
|
var config = key;
|
|
|
|
key = GetFastValue(config, 'key');
|
|
url = GetFastValue(config, 'url');
|
|
xhrSettings = GetFastValue(config, 'xhrSettings');
|
|
extension = GetFastValue(config, 'extension', extension);
|
|
}
|
|
|
|
var fileConfig = {
|
|
type: 'text',
|
|
cache: loader.cacheManager.text,
|
|
extension: extension,
|
|
responseType: 'text',
|
|
key: key,
|
|
url: url,
|
|
xhrSettings: xhrSettings
|
|
};
|
|
|
|
File.call(this, loader, fileConfig);
|
|
},
|
|
|
|
/**
|
|
* Called automatically by Loader.nextFile.
|
|
* This method controls what extra work this File does with its loaded data.
|
|
*
|
|
* @method Phaser.Loader.FileTypes.TextFile#onProcess
|
|
* @since 3.7.0
|
|
*/
|
|
onProcess: function ()
|
|
{
|
|
this.state = CONST.FILE_PROCESSING;
|
|
|
|
this.data = this.xhrLoader.responseText;
|
|
|
|
this.onProcessComplete();
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
* Adds a Text file, or array of Text files, to the current load queue.
|
|
*
|
|
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
|
|
*
|
|
* ```javascript
|
|
* function preload ()
|
|
* {
|
|
* this.load.text('story', 'files/IntroStory.txt');
|
|
* }
|
|
* ```
|
|
*
|
|
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
|
|
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
|
|
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
|
|
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
|
|
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
|
|
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
|
|
* loaded.
|
|
*
|
|
* The key must be a unique String. It is used to add the file to the global Text Cache upon a successful load.
|
|
* The key should be unique both in terms of files being loaded and files already present in the Text Cache.
|
|
* Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
|
|
* then remove it from the Text Cache first, before loading a new one.
|
|
*
|
|
* Instead of passing arguments you can pass a configuration object, such as:
|
|
*
|
|
* ```javascript
|
|
* this.load.text({
|
|
* key: 'story',
|
|
* url: 'files/IntroStory.txt'
|
|
* });
|
|
* ```
|
|
*
|
|
* See the documentation for `Phaser.Types.Loader.FileTypes.TextFileConfig` for more details.
|
|
*
|
|
* Once the file has finished loading you can access it from its Cache using its key:
|
|
*
|
|
* ```javascript
|
|
* this.load.text('story', 'files/IntroStory.txt');
|
|
* // and later in your game ...
|
|
* var data = this.cache.text.get('story');
|
|
* ```
|
|
*
|
|
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
|
|
* key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and
|
|
* this is what you would use to retrieve the text from the Text Cache.
|
|
*
|
|
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
|
|
*
|
|
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story"
|
|
* and no URL is given then the Loader will set the URL to be "story.txt". It will always add `.txt` as the extension, although
|
|
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
|
|
*
|
|
* Note: The ability to load this type of file will only be available if the Text File type has been built into Phaser.
|
|
* It is available in the default build but can be excluded from custom builds.
|
|
*
|
|
* @method Phaser.Loader.LoaderPlugin#text
|
|
* @fires Phaser.Loader.LoaderPlugin#ADD
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig|Phaser.Types.Loader.FileTypes.TextFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
|
|
* @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
|
|
* @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
|
|
*
|
|
* @return {this} The Loader instance.
|
|
*/
|
|
FileTypesManager.register('text', function (key, url, xhrSettings)
|
|
{
|
|
if (Array.isArray(key))
|
|
{
|
|
for (var i = 0; i < key.length; i++)
|
|
{
|
|
// If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
|
|
this.addFile(new TextFile(this, key[i]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.addFile(new TextFile(this, key, url, xhrSettings));
|
|
}
|
|
|
|
return this;
|
|
});
|
|
|
|
module.exports = TextFile;
|
|
|
|
|
|
/***/ }),
|
|
/* 218 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var AngleBetween = __webpack_require__(28);
|
|
var Clamp = __webpack_require__(4);
|
|
var Class = __webpack_require__(0);
|
|
var ComponentsComputedSize = __webpack_require__(46);
|
|
var ComponentsDepth = __webpack_require__(47);
|
|
var ComponentsFlip = __webpack_require__(48);
|
|
var ComponentsScrollFactor = __webpack_require__(49);
|
|
var ComponentsTransform = __webpack_require__(50);
|
|
var ComponentsVisible = __webpack_require__(51);
|
|
var CounterClockwise = __webpack_require__(8);
|
|
var DegToRad = __webpack_require__(19);
|
|
var GameObject = __webpack_require__(52);
|
|
var RadToDeg = __webpack_require__(9);
|
|
var SpineEvents = __webpack_require__(240);
|
|
var SpineGameObjectRender = __webpack_require__(247);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Spine Game Object is a Phaser level object that can be added to your Phaser Scenes. It encapsulates
|
|
* a Spine Skeleton with Spine Animation Data and Animation State, with helper methods to allow you to
|
|
* easily change the skin, slot attachment, bone positions and more.
|
|
*
|
|
* Spine Game Objects can be created via the Game Object Factory, Game Object Creator, or directly.
|
|
* You can only create them if the Spine plugin has been loaded into Phaser.
|
|
*
|
|
* The quickest way is the Game Object Factory:
|
|
*
|
|
* ```javascript
|
|
* let jelly = this.add.spine(512, 550, 'jelly', 'jelly-think', true);
|
|
* ```
|
|
*
|
|
* Here we are creating a new Spine Game Object positioned at 512 x 550. It's using the `jelly`
|
|
* Spine data, which has previously been loaded into your Scene. The `jelly-think` argument is
|
|
* an optional animation to start playing on the skeleton. The final argument `true` sets the
|
|
* animation to loop. Look at the documentation for further details on each of these options.
|
|
*
|
|
* For more control, you can use the Game Object Creator, passing in a Spine Game Object
|
|
* Configuration object:
|
|
*
|
|
* ```javascript
|
|
* let jelly = this.make.spine({
|
|
* x: 512, y: 550, key: 'jelly',
|
|
* scale: 1.5,
|
|
* skinName: 'square_Green',
|
|
* animationName: 'jelly-think', loop: true,
|
|
* slotName: 'hat', attachmentName: 'images/La_14'
|
|
* });
|
|
* ```
|
|
*
|
|
* Here, you've got the ability to specify extra details, such as the slot name, attachments or
|
|
* overall scale.
|
|
*
|
|
* If you wish to instantiate a Spine Game Object directly you can do so, but in order for it to
|
|
* update and render, it must be added to the display and update lists of your Scene:
|
|
*
|
|
* ```javascript
|
|
* let jelly = new SpineGameObject(this, this.spine, 512, 550, 'jelly', 'jelly-think', true);
|
|
* this.sys.displayList.add(jelly);
|
|
* this.sys.updateList.add(jelly);
|
|
* ```
|
|
*
|
|
* It's possible to enable Spine Game Objects for input, but you should be aware that it will use
|
|
* the bounds of the skeletons current pose to create the hit area from. Sometimes this is ok, but
|
|
* often not. Make use of the `InputPlugin.enableDebug` method to view the input shape being created.
|
|
* If it's not suitable, provide your own shape to the `setInteractive` method.
|
|
*
|
|
* Due to the way Spine handles scaling, it's not recommended to enable a Spine Game Object for
|
|
* physics directly. Instead, you should look at creating a proxy body and syncing the Spine Game
|
|
* Object position with it. See the examples for further details.
|
|
*
|
|
* If your Spine Game Object has black outlines around the different parts of the texture when it
|
|
* renders then you have exported the files from Spine with pre-multiplied alpha enabled, but have
|
|
* forgotten to set that flag when loading the Spine data. Please see the loader docs for more details.
|
|
*
|
|
* @class SpineGameObject
|
|
* @constructor
|
|
* @since 3.19.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that this Game Object belongs to.
|
|
* @param {SpinePlugin} pluginManager - A reference to the Phaser Spine Plugin.
|
|
* @param {number} x - The horizontal position of this Game Object in the world.
|
|
* @param {number} y - The vertical position of this Game Object in the world.
|
|
* @param {string} [key] - The key of the Spine Skeleton this Game Object will use, as stored in the Spine Plugin.
|
|
* @param {string} [animationName] - The name of the animation to set on this Skeleton.
|
|
* @param {boolean} [loop=false] - Should the animation playback be looped or not?
|
|
*/
|
|
var SpineGameObject = new Class({
|
|
|
|
Extends: GameObject,
|
|
|
|
Mixins: [
|
|
ComponentsComputedSize,
|
|
ComponentsDepth,
|
|
ComponentsFlip,
|
|
ComponentsScrollFactor,
|
|
ComponentsTransform,
|
|
ComponentsVisible,
|
|
SpineGameObjectRender
|
|
],
|
|
|
|
initialize:
|
|
|
|
function SpineGameObject (scene, plugin, x, y, key, animationName, loop)
|
|
{
|
|
GameObject.call(this, scene, 'Spine');
|
|
|
|
/**
|
|
* A reference to the Spine Plugin.
|
|
*
|
|
* @name SpineGameObject#plugin
|
|
* @type {SpinePlugin}
|
|
* @since 3.19.0
|
|
*/
|
|
this.plugin = plugin;
|
|
|
|
/**
|
|
* The Spine Skeleton this Game Object is using.
|
|
*
|
|
* @name SpineGameObject#skeleton
|
|
* @type {spine.Skeleton}
|
|
* @since 3.19.0
|
|
*/
|
|
this.skeleton = null;
|
|
|
|
/**
|
|
* The Spine Skeleton Data associated with the Skeleton this Game Object is using.
|
|
*
|
|
* @name SpineGameObject#skeletonData
|
|
* @type {spine.SkeletonData}
|
|
* @since 3.19.0
|
|
*/
|
|
this.skeletonData = null;
|
|
|
|
/**
|
|
* The Spine Animation State this Game Object is using.
|
|
*
|
|
* @name SpineGameObject#state
|
|
* @type {spine.AnimationState}
|
|
* @since 3.19.0
|
|
*/
|
|
this.state = null;
|
|
|
|
/**
|
|
* The Spine Animation State Data associated with the Animation State this Game Object is using.
|
|
*
|
|
* @name SpineGameObject#stateData
|
|
* @type {spine.AnimationStateData}
|
|
* @since 3.19.0
|
|
*/
|
|
this.stateData = null;
|
|
|
|
/**
|
|
* A reference to the root bone of the Skeleton.
|
|
*
|
|
* @name SpineGameObject#root
|
|
* @type {spine.Bone}
|
|
* @since 3.19.0
|
|
*/
|
|
this.root = null;
|
|
|
|
/**
|
|
* This object holds the calculated bounds of the current
|
|
* pose, as set when a new Skeleton is applied.
|
|
*
|
|
* @name SpineGameObject#bounds
|
|
* @type {any}
|
|
* @since 3.19.0
|
|
*/
|
|
this.bounds = null;
|
|
|
|
/**
|
|
* A Game Object level flag that allows you to enable debug drawing
|
|
* to the Skeleton Debug Renderer by toggling it.
|
|
*
|
|
* @name SpineGameObject#drawDebug
|
|
* @type {boolean}
|
|
* @since 3.19.0
|
|
*/
|
|
this.drawDebug = false;
|
|
|
|
/**
|
|
* The factor to scale the Animation update time by.
|
|
*
|
|
* @name SpineGameObject#timeScale
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
this.timeScale = 1;
|
|
|
|
/**
|
|
* The calculated Display Origin of this Game Object.
|
|
*
|
|
* @name SpineGameObject#displayOriginX
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
this.displayOriginX = 0;
|
|
|
|
/**
|
|
* The calculated Display Origin of this Game Object.
|
|
*
|
|
* @name SpineGameObject#displayOriginY
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
this.displayOriginY = 0;
|
|
|
|
/**
|
|
* A flag that stores if the texture associated with the current
|
|
* Skin being used by this Game Object, has its alpha pre-multiplied
|
|
* into it, or not.
|
|
*
|
|
* @name SpineGameObject#preMultipliedAlpha
|
|
* @type {boolean}
|
|
* @since 3.19.0
|
|
*/
|
|
this.preMultipliedAlpha = false;
|
|
|
|
/**
|
|
* A default Blend Mode. You cannot change the blend mode of a
|
|
* Spine Game Object.
|
|
*
|
|
* @name SpineGameObject#blendMode
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
this.blendMode = -1;
|
|
|
|
this.setPosition(x, y);
|
|
|
|
if (key)
|
|
{
|
|
this.setSkeleton(key, animationName, loop);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Overrides the default Game Object method and always returns true.
|
|
* Rendering is decided in the renderer functions.
|
|
*
|
|
* @method SpineGameObject#willRender
|
|
* @since 3.19.0
|
|
*
|
|
* @return {boolean} Always returns `true`.
|
|
*/
|
|
willRender: function ()
|
|
{
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Set the Alpha level for the whole Skeleton of this Game Object.
|
|
*
|
|
* The alpha controls the opacity of the Game Object as it renders.
|
|
*
|
|
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
|
|
*
|
|
* @method SpineGameObject#setAlpha
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} [value=1] - The alpha value used for the whole Skeleton.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setAlpha: function (value, slotName)
|
|
{
|
|
if (value === undefined) { value = 1; }
|
|
|
|
if (slotName)
|
|
{
|
|
var slot = this.findSlot(slotName);
|
|
|
|
if (slot)
|
|
{
|
|
slot.color.a = Clamp(value, 0, 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.alpha = value;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The alpha value of the Skeleton.
|
|
*
|
|
* A value between 0 and 1.
|
|
*
|
|
* This is a global value, impacting the entire Skeleton, not just a region of it.
|
|
*
|
|
* @name SpineGameObject#alpha
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
alpha: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.skeleton.color.a;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
if (this.skeleton)
|
|
{
|
|
this.skeleton.color.a = v;
|
|
}
|
|
|
|
if (v === 0)
|
|
{
|
|
this.renderFlags &= ~2;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= 2;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The amount of red used when rendering the Skeleton.
|
|
*
|
|
* A value between 0 and 1.
|
|
*
|
|
* This is a global value, impacting the entire Skeleton, not just a region of it.
|
|
*
|
|
* @name SpineGameObject#red
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
red: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.skeleton.color.r;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
if (this.skeleton)
|
|
{
|
|
this.skeleton.color.r = v;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The amount of green used when rendering the Skeleton.
|
|
*
|
|
* A value between 0 and 1.
|
|
*
|
|
* This is a global value, impacting the entire Skeleton, not just a region of it.
|
|
*
|
|
* @name SpineGameObject#green
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
green: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.skeleton.color.g;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
if (this.skeleton)
|
|
{
|
|
this.skeleton.color.g = v;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The amount of blue used when rendering the Skeleton.
|
|
*
|
|
* A value between 0 and 1.
|
|
*
|
|
* This is a global value, impacting the entire Skeleton, not just a region of it.
|
|
*
|
|
* @name SpineGameObject#blue
|
|
* @type {number}
|
|
* @since 3.19.0
|
|
*/
|
|
blue: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.skeleton.color.b;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
if (this.skeleton)
|
|
{
|
|
this.skeleton.color.b = v;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the color on the given attachment slot. Or, if no slot is given, on the whole skeleton.
|
|
*
|
|
* @method SpineGameObject#setColor
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} [color=0xffffff] - The color being applied to the Skeleton or named Slot. Set to white to disable any previously set color.
|
|
* @param {string} [slotName] - The name of the slot to set the color on. If not give, will be set on the whole skeleton.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setColor: function (color, slotName)
|
|
{
|
|
if (color === undefined) { color = 0xffffff; }
|
|
|
|
var red = (color >> 16 & 0xFF) / 255;
|
|
var green = (color >> 8 & 0xFF) / 255;
|
|
var blue = (color & 0xFF) / 255;
|
|
var alpha = (color > 16777215) ? (color >>> 24) / 255 : null;
|
|
|
|
var target = this.skeleton;
|
|
|
|
if (slotName)
|
|
{
|
|
var slot = this.findSlot(slotName);
|
|
|
|
if (slot)
|
|
{
|
|
target = slot;
|
|
}
|
|
}
|
|
|
|
target.color.r = red;
|
|
target.color.g = green;
|
|
target.color.b = blue;
|
|
|
|
if (alpha !== null)
|
|
{
|
|
target.color.a = alpha;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets this Game Object to use the given Skeleton based on the Atlas Data Key and a provided JSON object
|
|
* that contains the Skeleton data.
|
|
*
|
|
* @method SpineGameObject#setSkeletonFromJSON
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} atlasDataKey - The key of the Spine data to use for this Skeleton.
|
|
* @param {object} skeletonJSON - The JSON data for the Skeleton.
|
|
* @param {string} [animationName] - Optional name of the animation to set on the Skeleton.
|
|
* @param {boolean} [loop=false] - Should the animation, if set, loop or not?
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSkeletonFromJSON: function (atlasDataKey, skeletonJSON, animationName, loop)
|
|
{
|
|
return this.setSkeleton(atlasDataKey, skeletonJSON, animationName, loop);
|
|
},
|
|
|
|
/**
|
|
* Sets this Game Object to use the given Skeleton based on its cache key.
|
|
*
|
|
* Typically, once set, the Skeleton doesn't change. Instead, you change the skin,
|
|
* or slot attachment, or any other property to adjust it.
|
|
*
|
|
* @method SpineGameObject#setSkeleton
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} atlasDataKey - The key of the Spine data to use for this Skeleton.
|
|
* @param {object} skeletonJSON - The JSON data for the Skeleton.
|
|
* @param {string} [animationName] - Optional name of the animation to set on the Skeleton.
|
|
* @param {boolean} [loop=false] - Should the animation, if set, loop or not?
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSkeleton: function (atlasDataKey, animationName, loop, skeletonJSON)
|
|
{
|
|
if (this.state)
|
|
{
|
|
this.state.clearListeners();
|
|
this.state.clearListenerNotifications();
|
|
}
|
|
|
|
var data = this.plugin.createSkeleton(atlasDataKey, skeletonJSON);
|
|
|
|
this.skeletonData = data.skeletonData;
|
|
|
|
this.preMultipliedAlpha = data.preMultipliedAlpha;
|
|
|
|
var skeleton = data.skeleton;
|
|
|
|
skeleton.setSkin();
|
|
skeleton.setToSetupPose();
|
|
|
|
this.skeleton = skeleton;
|
|
|
|
// AnimationState
|
|
data = this.plugin.createAnimationState(skeleton);
|
|
|
|
if (this.state)
|
|
{
|
|
this.state.clearListeners();
|
|
this.state.clearListenerNotifications();
|
|
}
|
|
|
|
this.state = data.state;
|
|
this.stateData = data.stateData;
|
|
|
|
this.state.addListener({
|
|
event: this.onEvent.bind(this),
|
|
complete: this.onComplete.bind(this),
|
|
start: this.onStart.bind(this),
|
|
end: this.onEnd.bind(this),
|
|
dispose: this.onDispose.bind(this),
|
|
interrupted: this.onInterrupted.bind(this)
|
|
});
|
|
|
|
if (animationName)
|
|
{
|
|
this.setAnimation(0, animationName, loop);
|
|
}
|
|
|
|
this.root = this.getRootBone();
|
|
|
|
if (this.root)
|
|
{
|
|
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
|
this.root.rotation = RadToDeg(CounterClockwise(this.rotation)) + 90;
|
|
}
|
|
|
|
this.state.apply(skeleton);
|
|
|
|
skeleton.updateCache();
|
|
|
|
return this.updateSize();
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine onComplete event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onComplete
|
|
* @fires SpinePluginEvents#COMPLETE
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
*/
|
|
onComplete: function (entry)
|
|
{
|
|
this.emit(SpineEvents.COMPLETE, entry);
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine onDispose event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onDispose
|
|
* @fires SpinePluginEvents#DISPOSE
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
*/
|
|
onDispose: function (entry)
|
|
{
|
|
this.emit(SpineEvents.DISPOSE, entry);
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine onEnd event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onEnd
|
|
* @fires SpinePluginEvents#END
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
*/
|
|
onEnd: function (entry)
|
|
{
|
|
this.emit(SpineEvents.END, entry);
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine Event event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onEvent
|
|
* @fires SpinePluginEvents#EVENT
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
* @param {spine.Event} event - The Spine event.
|
|
*/
|
|
onEvent: function (entry, event)
|
|
{
|
|
this.emit(SpineEvents.EVENT, entry, event);
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine onInterrupted event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onInterrupted
|
|
* @fires SpinePluginEvents#INTERRUPTED
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
*/
|
|
onInterrupted: function (entry)
|
|
{
|
|
this.emit(SpineEvents.INTERRUPTED, entry);
|
|
},
|
|
|
|
/**
|
|
* Internal event handler that emits the Spine onStart event via this Game Object.
|
|
*
|
|
* @method SpineGameObject#onStart
|
|
* @fires SpinePluginEvents#START
|
|
* @private
|
|
* @since 3.19.0
|
|
*
|
|
* @param {any} entry - The event data from Spine.
|
|
*/
|
|
onStart: function (entry)
|
|
{
|
|
this.emit(SpineEvents.START, entry);
|
|
},
|
|
|
|
/**
|
|
* Refreshes the data about the current Skeleton.
|
|
*
|
|
* This will reset the rotation, position and size of the Skeleton to match this Game Object.
|
|
*
|
|
* Call this method if you need to access the Skeleton data directly, and it may have changed
|
|
* recently.
|
|
*
|
|
* @method SpineGameObject#refresh
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
refresh: function ()
|
|
{
|
|
if (this.root)
|
|
{
|
|
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
|
this.root.rotation = RadToDeg(CounterClockwise(this.rotation)) + 90;
|
|
}
|
|
|
|
this.updateSize();
|
|
|
|
this.skeleton.updateCache();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the size of this Game Object.
|
|
*
|
|
* If no arguments are given it uses the current skeleton data dimensions.
|
|
*
|
|
* You can use this method to set a fixed size of this Game Object, such as for input detection,
|
|
* when the skeleton data doesn't match what is required in-game.
|
|
*
|
|
* @method SpineGameObject#setSize
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} [width] - The width of the Skeleton. If not given it defaults to the Skeleton Data width.
|
|
* @param {number} [height] - The height of the Skeleton. If not given it defaults to the Skeleton Data height.
|
|
* @param {number} [offsetX=0] - The horizontal offset of the Skeleton from its x and y coordinate.
|
|
* @param {number} [offsetY=0] - The vertical offset of the Skeleton from its x and y coordinate.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSize: function (width, height, offsetX, offsetY)
|
|
{
|
|
var skeleton = this.skeleton;
|
|
|
|
if (width === undefined) { width = skeleton.data.width; }
|
|
if (height === undefined) { height = skeleton.data.height; }
|
|
if (offsetX === undefined) { offsetX = 0; }
|
|
if (offsetY === undefined) { offsetY = 0; }
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
this.displayOriginX = skeleton.x - offsetX;
|
|
this.displayOriginY = skeleton.y - offsetY;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the offset of this Game Object from the Skeleton position.
|
|
*
|
|
* You can use this method to adjust how the position of this Game Object relates to the Skeleton it is using.
|
|
*
|
|
* @method SpineGameObject#setOffset
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} [offsetX=0] - The horizontal offset of the Skeleton from its x and y coordinate.
|
|
* @param {number} [offsetY=0] - The vertical offset of the Skeleton from its x and y coordinate.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setOffset: function (offsetX, offsetY)
|
|
{
|
|
var skeleton = this.skeleton;
|
|
|
|
if (offsetX === undefined) { offsetX = 0; }
|
|
if (offsetY === undefined) { offsetY = 0; }
|
|
|
|
this.displayOriginX = skeleton.x - offsetX;
|
|
this.displayOriginY = skeleton.y - offsetY;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Internal method that syncs all of the Game Object position and scale data to the Skeleton.
|
|
* It then syncs the skeleton bounds back to this Game Object.
|
|
*
|
|
* This method is called automatically as needed internally, however, it's also exposed should
|
|
* you require overriding the size settings.
|
|
*
|
|
* @method SpineGameObject#updateSize
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
updateSize: function ()
|
|
{
|
|
var skeleton = this.skeleton;
|
|
var renderer = this.plugin.renderer;
|
|
|
|
var height = renderer.height;
|
|
|
|
var oldScaleX = this.scaleX;
|
|
var oldScaleY = this.scaleY;
|
|
|
|
skeleton.x = this.x;
|
|
skeleton.y = height - this.y;
|
|
skeleton.scaleX = 1;
|
|
skeleton.scaleY = 1;
|
|
|
|
skeleton.updateWorldTransform();
|
|
|
|
var bounds = this.getBounds();
|
|
|
|
this.width = bounds.size.x;
|
|
this.height = bounds.size.y;
|
|
|
|
this.displayOriginX = this.x - bounds.offset.x;
|
|
this.displayOriginY = this.y - (height - (this.height + bounds.offset.y));
|
|
|
|
skeleton.scaleX = oldScaleX;
|
|
skeleton.scaleY = oldScaleY;
|
|
|
|
skeleton.updateWorldTransform();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The horizontal scale of this Game Object, as applied to the Skeleton it is using.
|
|
*
|
|
* @name SpineGameObject#scaleX
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.19.0
|
|
*/
|
|
scaleX: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._scaleX;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._scaleX = value;
|
|
|
|
this.refresh();
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The vertical scale of this Game Object, as applied to the Skeleton it is using.
|
|
*
|
|
* @name SpineGameObject#scaleY
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.19.0
|
|
*/
|
|
scaleY: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._scaleY;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._scaleY = value;
|
|
|
|
this.refresh();
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Returns an array containing the names of all the bones in the Skeleton Data.
|
|
*
|
|
* @method SpineGameObject#getBoneList
|
|
* @since 3.19.0
|
|
*
|
|
* @return {string[]} An array containing the names of all the bones in the Skeleton Data.
|
|
*/
|
|
getBoneList: function ()
|
|
{
|
|
var output = [];
|
|
|
|
var skeletonData = this.skeletonData;
|
|
|
|
if (skeletonData)
|
|
{
|
|
for (var i = 0; i < skeletonData.bones.length; i++)
|
|
{
|
|
output.push(skeletonData.bones[i].name);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns an array containing the names of all the skins in the Skeleton Data.
|
|
*
|
|
* @method SpineGameObject#getSkinList
|
|
* @since 3.19.0
|
|
*
|
|
* @return {string[]} An array containing the names of all the skins in the Skeleton Data.
|
|
*/
|
|
getSkinList: function ()
|
|
{
|
|
var output = [];
|
|
|
|
var skeletonData = this.skeletonData;
|
|
|
|
if (skeletonData)
|
|
{
|
|
for (var i = 0; i < skeletonData.skins.length; i++)
|
|
{
|
|
output.push(skeletonData.skins[i].name);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns an array containing the names of all the slots in the Skeleton.
|
|
*
|
|
* @method SpineGameObject#getSlotList
|
|
* @since 3.19.0
|
|
*
|
|
* @return {string[]} An array containing the names of all the slots in the Skeleton.
|
|
*/
|
|
getSlotList: function ()
|
|
{
|
|
var output = [];
|
|
|
|
var skeleton = this.skeleton;
|
|
|
|
for (var i = 0; i < skeleton.slots.length; i++)
|
|
{
|
|
output.push(skeleton.slots[i].data.name);
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns an array containing the names of all the animations in the Skeleton Data.
|
|
*
|
|
* @method SpineGameObject#getAnimationList
|
|
* @since 3.19.0
|
|
*
|
|
* @return {string[]} An array containing the names of all the animations in the Skeleton Data.
|
|
*/
|
|
getAnimationList: function ()
|
|
{
|
|
var output = [];
|
|
|
|
var skeletonData = this.skeletonData;
|
|
|
|
if (skeletonData)
|
|
{
|
|
for (var i = 0; i < skeletonData.animations.length; i++)
|
|
{
|
|
output.push(skeletonData.animations[i].name);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns the current animation being played on the given track, if any.
|
|
*
|
|
* @method SpineGameObject#getCurrentAnimation
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} [trackIndex=0] - The track to return the current animation on.
|
|
*
|
|
* @return {?spine.Animation} The current Animation on the given track, or `undefined` if there is no current animation.
|
|
*/
|
|
getCurrentAnimation: function (trackIndex)
|
|
{
|
|
if (trackIndex === undefined) { trackIndex = 0; }
|
|
|
|
var current = this.state.getCurrent(trackIndex);
|
|
|
|
if (current)
|
|
{
|
|
return current.animation;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sets the current animation for a track, discarding any queued animations.
|
|
* If the formerly current track entry was never applied to a skeleton, it is replaced (not mixed from).
|
|
*
|
|
* Animations are referenced by a unique string-based key, as defined in the Spine software.
|
|
*
|
|
* @method SpineGameObject#play
|
|
* @fires SpinePluginEvents#START
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} animationName - The string-based key of the animation to play.
|
|
* @param {boolean} [loop=false] - Should the animation be looped when played?
|
|
* @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call.
|
|
*
|
|
* @return {this} This Game Object. If you need the TrackEntry, see `setAnimation` instead.
|
|
*/
|
|
play: function (animationName, loop, ignoreIfPlaying)
|
|
{
|
|
this.setAnimation(0, animationName, loop, ignoreIfPlaying);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the current animation for a track, discarding any queued animations.
|
|
* If the formerly current track entry was never applied to a skeleton, it is replaced (not mixed from).
|
|
*
|
|
* Animations are referenced by a unique string-based key, as defined in the Spine software.
|
|
*
|
|
* @method SpineGameObject#setAnimation
|
|
* @fires SpinePluginEvents#START
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} trackIndex - The track index to play the animation on.
|
|
* @param {string} animationName - The string-based key of the animation to play.
|
|
* @param {boolean} [loop=false] - Should the animation be looped when played?
|
|
* @param {boolean} [ignoreIfPlaying=false] - If the animation specified by the track index is already playing then ignore this call.
|
|
*
|
|
* @return {spine.TrackEntry} A track entry to allow further customization of animation playback.
|
|
*/
|
|
setAnimation: function (trackIndex, animationName, loop, ignoreIfPlaying)
|
|
{
|
|
if (loop === undefined) { loop = false; }
|
|
if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; }
|
|
|
|
if (ignoreIfPlaying && this.state)
|
|
{
|
|
var currentTrack = this.state.getCurrent(trackIndex);
|
|
|
|
if (currentTrack && currentTrack.animation.name === animationName && !currentTrack.isComplete())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (this.findAnimation(animationName))
|
|
{
|
|
return this.state.setAnimation(trackIndex, animationName, loop);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Adds an animation to be played after the current or last queued animation for a track.
|
|
* If the track is empty, it is equivalent to calling setAnimation.
|
|
*
|
|
* Animations are referenced by a unique string-based key, as defined in the Spine software.
|
|
*
|
|
* The delay is a float. If > 0, sets delay. If <= 0, the delay set is the duration of the previous
|
|
* track entry minus any mix duration (from the AnimationStateData) plus the specified delay
|
|
* (ie the mix ends at (delay = 0) or before (delay < 0) the previous track entry duration).
|
|
* If the previous entry is looping, its next loop completion is used instead of its duration.
|
|
*
|
|
* @method SpineGameObject#addAnimation
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} trackIndex - The track index to add the animation to.
|
|
* @param {string} animationName - The string-based key of the animation to add.
|
|
* @param {boolean} [loop=false] - Should the animation be looped when played?
|
|
* @param {integer} [delay=0] - A delay, in ms, before which this animation will start when played.
|
|
*
|
|
* @return {spine.TrackEntry} A track entry to allow further customization of animation playback.
|
|
*/
|
|
addAnimation: function (trackIndex, animationName, loop, delay)
|
|
{
|
|
if (loop === undefined) { loop = false; }
|
|
if (delay === undefined) { delay = 0; }
|
|
|
|
return this.state.addAnimation(trackIndex, animationName, loop, delay);
|
|
},
|
|
|
|
/**
|
|
* Sets an empty animation for a track, discarding any queued animations, and sets the track
|
|
* entry's mixDuration. An empty animation has no timelines and serves as a placeholder for mixing in or out.
|
|
*
|
|
* Mixing out is done by setting an empty animation with a mix duration using either setEmptyAnimation,
|
|
* setEmptyAnimations, or addEmptyAnimation. Mixing to an empty animation causes the previous animation to be
|
|
* applied less and less over the mix duration. Properties keyed in the previous animation transition to
|
|
* the value from lower tracks or to the setup pose value if no lower tracks key the property.
|
|
* A mix duration of 0 still mixes out over one frame.
|
|
*
|
|
* Mixing in is done by first setting an empty animation, then adding an animation using addAnimation
|
|
* and on the returned track entry, set the mixDuration. Mixing from an empty animation causes the new
|
|
* animation to be applied more and more over the mix duration. Properties keyed in the new animation
|
|
* transition from the value from lower tracks or from the setup pose value if no lower tracks key the
|
|
* property to the value keyed in the new animation.
|
|
*
|
|
* @method SpineGameObject#setEmptyAnimation
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} trackIndex - The track index to add the animation to.
|
|
* @param {integer} [mixDuration] - Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData getMix based on the animation before this animation (if any).
|
|
*
|
|
* @return {spine.TrackEntry} The returned Track Entry.
|
|
*/
|
|
setEmptyAnimation: function (trackIndex, mixDuration)
|
|
{
|
|
return this.state.setEmptyAnimation(trackIndex, mixDuration);
|
|
},
|
|
|
|
/**
|
|
* Removes all animations from the track, leaving skeletons in their current pose.
|
|
*
|
|
* It may be desired to use setEmptyAnimation to mix the skeletons back to the setup pose,
|
|
* rather than leaving them in their current pose.
|
|
*
|
|
* @method SpineGameObject#clearTrack
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} trackIndex - The track index to add the animation to.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
clearTrack: function (trackIndex)
|
|
{
|
|
this.state.clearTrack(trackIndex);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes all animations from all tracks, leaving skeletons in their current pose.
|
|
*
|
|
* It may be desired to use setEmptyAnimation to mix the skeletons back to the setup pose,
|
|
* rather than leaving them in their current pose.
|
|
*
|
|
* @method SpineGameObject#clearTracks
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
clearTracks: function ()
|
|
{
|
|
this.state.clearTracks();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the skin used to look up attachments before looking in the defaultSkin.
|
|
*
|
|
* Attachments from the new skin are attached if the corresponding attachment from the
|
|
* old skin was attached. If there was no old skin, each slot's setup mode attachment is
|
|
* attached from the new skin.
|
|
*
|
|
* After changing the skin, the visible attachments can be reset to those attached in the
|
|
* setup pose by calling setSlotsToSetupPose. Also, often apply is called before the next time
|
|
* the skeleton is rendered to allow any attachment keys in the current animation(s) to hide
|
|
* or show attachments from the new skin.
|
|
*
|
|
* @method SpineGameObject#setSkinByName
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} skinName - The name of the skin to set.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSkinByName: function (skinName)
|
|
{
|
|
var skeleton = this.skeleton;
|
|
|
|
skeleton.setSkinByName(skinName);
|
|
|
|
skeleton.setSlotsToSetupPose();
|
|
|
|
this.state.apply(skeleton);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the skin used to look up attachments before looking in the defaultSkin.
|
|
*
|
|
* Attachments from the new skin are attached if the corresponding attachment from the
|
|
* old skin was attached. If there was no old skin, each slot's setup mode attachment is
|
|
* attached from the new skin.
|
|
*
|
|
* After changing the skin, the visible attachments can be reset to those attached in the
|
|
* setup pose by calling setSlotsToSetupPose. Also, often apply is called before the next time
|
|
* the skeleton is rendered to allow any attachment keys in the current animation(s) to hide
|
|
* or show attachments from the new skin.
|
|
*
|
|
* @method SpineGameObject#setSkin
|
|
* @since 3.19.0
|
|
*
|
|
* @param {?spine.Skin} newSkin - The Skin to set. May be `null`.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSkin: function (newSkin)
|
|
{
|
|
var skeleton = this.skeleton;
|
|
|
|
skeleton.setSkin(newSkin);
|
|
|
|
skeleton.setSlotsToSetupPose();
|
|
|
|
this.state.apply(skeleton);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the mix duration when changing from the specified animation to the other.
|
|
*
|
|
* @method SpineGameObject#setMix
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} fromName - The animation to mix from.
|
|
* @param {string} toName - The animation to mix to.
|
|
* @param {number} [duration] - Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData getMix based on the animation before this animation (if any).
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setMix: function (fromName, toName, duration)
|
|
{
|
|
this.stateData.setMix(fromName, toName, duration);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Finds an attachment by looking in the skin and defaultSkin using the slot
|
|
* index and attachment name. First the skin is checked and if the attachment was not found,
|
|
* the default skin is checked.
|
|
*
|
|
* @method SpineGameObject#getAttachment
|
|
* @since 3.19.0
|
|
*
|
|
* @param {integer} slotIndex - The slot index to search.
|
|
* @param {string} attachmentName - The attachment name to look for.
|
|
*
|
|
* @return {?spine.Attachment} The Attachment, if found. May be null.
|
|
*/
|
|
getAttachment: function (slotIndex, attachmentName)
|
|
{
|
|
return this.skeleton.getAttachment(slotIndex, attachmentName);
|
|
},
|
|
|
|
/**
|
|
* Finds an attachment by looking in the skin and defaultSkin using the slot name and attachment name.
|
|
*
|
|
* @method SpineGameObject#getAttachmentByName
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} slotName - The slot name to search.
|
|
* @param {string} attachmentName - The attachment name to look for.
|
|
*
|
|
* @return {?spine.Attachment} The Attachment, if found. May be null.
|
|
*/
|
|
getAttachmentByName: function (slotName, attachmentName)
|
|
{
|
|
return this.skeleton.getAttachmentByName(slotName, attachmentName);
|
|
},
|
|
|
|
/**
|
|
* A convenience method to set an attachment by finding the slot with findSlot,
|
|
* finding the attachment with getAttachment, then setting the slot's attachment.
|
|
*
|
|
* @method SpineGameObject#setAttachment
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} slotName - The slot name to add the attachment to.
|
|
* @param {string} attachmentName - The attachment name to add.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setAttachment: function (slotName, attachmentName)
|
|
{
|
|
if (Array.isArray(slotName) && Array.isArray(attachmentName) && slotName.length === attachmentName.length)
|
|
{
|
|
for (var i = 0; i < slotName.length; i++)
|
|
{
|
|
this.skeleton.setAttachment(slotName[i], attachmentName[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.skeleton.setAttachment(slotName, attachmentName);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the bones, constraints, slots, and draw order to their setup pose values.
|
|
*
|
|
* @method SpineGameObject#setToSetupPose
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setToSetupPose: function ()
|
|
{
|
|
this.skeleton.setToSetupPose();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the slots and draw order to their setup pose values.
|
|
*
|
|
* @method SpineGameObject#setSlotsToSetupPose
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setSlotsToSetupPose: function ()
|
|
{
|
|
this.skeleton.setSlotsToSetupPose();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the bones and constraints to their setup pose values.
|
|
*
|
|
* @method SpineGameObject#setBonesToSetupPose
|
|
* @since 3.19.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setBonesToSetupPose: function ()
|
|
{
|
|
this.skeleton.setBonesToSetupPose();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Gets the root bone, or null.
|
|
*
|
|
* @method SpineGameObject#getRootBone
|
|
* @since 3.19.0
|
|
*
|
|
* @return {spine.Bone} The root bone, or null.
|
|
*/
|
|
getRootBone: function ()
|
|
{
|
|
return this.skeleton.getRootBone();
|
|
},
|
|
|
|
/**
|
|
* Takes a Bone object and a position in world space and rotates the Bone so it is angled
|
|
* towards the given position. You can set an optional angle offset, should the bone be
|
|
* designed at a specific angle already. You can also set a minimum and maximum range for the angle.
|
|
*
|
|
* @method SpineGameObject#angleBoneToXY
|
|
* @since 3.19.0
|
|
*
|
|
* @param {spine.Bone} bone - The bone to rotate towards the world position.
|
|
* @param {number} worldX - The world x coordinate to rotate the bone towards.
|
|
* @param {number} worldY - The world y coordinate to rotate the bone towards.
|
|
* @param {number} [offset=0] - An offset to add to the rotation angle.
|
|
* @param {number} [minAngle=0] - The minimum range of the rotation angle.
|
|
* @param {number} [maxAngle=360] - The maximum range of the rotation angle.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
angleBoneToXY: function (bone, worldX, worldY, offset, minAngle, maxAngle)
|
|
{
|
|
if (offset === undefined) { offset = 0; }
|
|
if (minAngle === undefined) { minAngle = 0; }
|
|
if (maxAngle === undefined) { maxAngle = 360; }
|
|
|
|
var renderer = this.plugin.renderer;
|
|
var height = renderer.height;
|
|
|
|
var angle = CounterClockwise(AngleBetween(bone.worldX, height - bone.worldY, worldX, worldY) + DegToRad(offset));
|
|
|
|
bone.rotation = Clamp(RadToDeg(angle), minAngle, maxAngle);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Finds a bone by comparing each bone's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findBone
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} boneName - The name of the bone to find.
|
|
*
|
|
* @return {spine.Bone} The bone, or null.
|
|
*/
|
|
findBone: function (boneName)
|
|
{
|
|
return this.skeleton.findBone(boneName);
|
|
},
|
|
|
|
/**
|
|
* Finds the index of a bone by comparing each bone's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findBoneIndex
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} boneName - The name of the bone to find.
|
|
*
|
|
* @return {integer} The bone index. Or -1 if the bone was not found.
|
|
*/
|
|
findBoneIndex: function (boneName)
|
|
{
|
|
return this.skeleton.findBoneIndex(boneName);
|
|
},
|
|
|
|
/**
|
|
* Finds a slot by comparing each slot's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findSlot
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} slotName - The name of the slot to find.
|
|
*
|
|
* @return {spine.Slot} The Slot. May be null.
|
|
*/
|
|
findSlot: function (slotName)
|
|
{
|
|
return this.skeleton.findSlot(slotName);
|
|
},
|
|
|
|
/**
|
|
* Finds the index of a slot by comparing each slot's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findSlotIndex
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} slotName - The name of the slot to find.
|
|
*
|
|
* @return {integer} The slot index. Or -1 if the Slot was not found.
|
|
*/
|
|
findSlotIndex: function (slotName)
|
|
{
|
|
return this.skeleton.findSlotIndex(slotName);
|
|
},
|
|
|
|
/**
|
|
* Finds a skin by comparing each skin's name. It is more efficient to cache the results of
|
|
* this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findSkin
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} skinName - The name of the skin to find.
|
|
*
|
|
* @return {spine.Skin} The Skin. May be null.
|
|
*/
|
|
findSkin: function (skinName)
|
|
{
|
|
return this.skeletonData.findSkin(skinName);
|
|
},
|
|
|
|
/**
|
|
* Finds an event by comparing each events's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findEvent
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} eventDataName - The name of the event to find.
|
|
*
|
|
* @return {spine.EventData} The Event Data. May be null.
|
|
*/
|
|
findEvent: function (eventDataName)
|
|
{
|
|
return this.skeletonData.findEvent(eventDataName);
|
|
},
|
|
|
|
/**
|
|
* Finds an animation by comparing each animation's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findAnimation
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} animationName - The name of the animation to find.
|
|
*
|
|
* @return {spine.Animation} The Animation. May be null.
|
|
*/
|
|
findAnimation: function (animationName)
|
|
{
|
|
return this.skeletonData.findAnimation(animationName);
|
|
},
|
|
|
|
/**
|
|
* Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results
|
|
* of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findIkConstraint
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} constraintName - The name of the constraint to find.
|
|
*
|
|
* @return {spine.IkConstraintData} The IK constraint. May be null.
|
|
*/
|
|
findIkConstraint: function (constraintName)
|
|
{
|
|
return this.skeletonData.findIkConstraint(constraintName);
|
|
},
|
|
|
|
/**
|
|
* Finds an transform constraint by comparing each transform constraint's name.
|
|
* It is more efficient to cache the results of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findTransformConstraint
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} constraintName - The name of the constraint to find.
|
|
*
|
|
* @return {spine.TransformConstraintData} The transform constraint. May be null.
|
|
*/
|
|
findTransformConstraint: function (constraintName)
|
|
{
|
|
return this.skeletonData.findTransformConstraint(constraintName);
|
|
},
|
|
|
|
/**
|
|
* Finds a path constraint by comparing each path constraint's name.
|
|
* It is more efficient to cache the results of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findPathConstraint
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} constraintName - The name of the constraint to find.
|
|
*
|
|
* @return {spine.PathConstraintData} The path constraint. May be null.
|
|
*/
|
|
findPathConstraint: function (constraintName)
|
|
{
|
|
return this.skeletonData.findPathConstraint(constraintName);
|
|
},
|
|
|
|
/**
|
|
* Finds the index of a path constraint by comparing each path constraint's name.
|
|
* It is more efficient to cache the results of this method than to call it multiple times.
|
|
*
|
|
* @method SpineGameObject#findPathConstraintIndex
|
|
* @since 3.19.0
|
|
*
|
|
* @param {string} constraintName - The name of the constraint to find.
|
|
*
|
|
* @return {integer} The constraint index. Or -1 if the constraint was not found.
|
|
*/
|
|
findPathConstraintIndex: function (constraintName)
|
|
{
|
|
return this.skeletonData.findPathConstraintIndex(constraintName);
|
|
},
|
|
|
|
/**
|
|
* Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
|
|
*
|
|
* The returned object contains two properties: `offset` and `size`:
|
|
*
|
|
* `offset` - The distance from the skeleton origin to the bottom left corner of the AABB.
|
|
* `size` - The width and height of the AABB.
|
|
*
|
|
* @method SpineGameObject#getBounds
|
|
* @since 3.19.0
|
|
*
|
|
* @return {any} The bounds object.
|
|
*/
|
|
getBounds: function ()
|
|
{
|
|
return this.plugin.getBounds(this.skeleton);
|
|
},
|
|
|
|
/**
|
|
* Internal update handler.
|
|
*
|
|
* @method SpineGameObject#preUpdate
|
|
* @protected
|
|
* @since 3.19.0
|
|
*
|
|
* @param {number} time - The current timestamp.
|
|
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
|
|
*/
|
|
preUpdate: function (time, delta)
|
|
{
|
|
var skeleton = this.skeleton;
|
|
|
|
this.state.update((delta / 1000) * this.timeScale);
|
|
|
|
this.state.apply(skeleton);
|
|
},
|
|
|
|
/**
|
|
* Internal destroy handler, called as part of the destroy process.
|
|
*
|
|
* @method SpineGameObject#preDestroy
|
|
* @protected
|
|
* @since 3.19.0
|
|
*/
|
|
preDestroy: function ()
|
|
{
|
|
if (this.state)
|
|
{
|
|
this.state.clearListeners();
|
|
this.state.clearListenerNotifications();
|
|
}
|
|
|
|
this.plugin = null;
|
|
|
|
this.skeleton = null;
|
|
this.skeletonData = null;
|
|
|
|
this.state = null;
|
|
this.stateData = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = SpineGameObject;
|
|
|
|
|
|
/***/ }),
|
|
/* 219 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var Events = __webpack_require__(220);
|
|
|
|
/**
|
|
* @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 Manager 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(Events.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
|
|
* @fires Phaser.Data.Events#SET_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @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 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;
|
|
},
|
|
|
|
/**
|
|
* Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0.
|
|
*
|
|
* When the value is first set, a `setdata` event is emitted.
|
|
*
|
|
* @method Phaser.Data.DataManager#inc
|
|
* @fires Phaser.Data.Events#SET_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @since 3.23.0
|
|
*
|
|
* @param {(string|object)} key - The key to increase the value for.
|
|
* @param {*} [data] - The value to increase for the given key.
|
|
*
|
|
* @return {Phaser.Data.DataManager} This DataManager object.
|
|
*/
|
|
inc: function (key, data)
|
|
{
|
|
if (this._frozen)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
if (data === undefined)
|
|
{
|
|
data = 1;
|
|
}
|
|
|
|
var value = this.get(key);
|
|
if (value === undefined)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
this.set(key, (value + data));
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false.
|
|
*
|
|
* When the value is first set, a `setdata` event is emitted.
|
|
*
|
|
* @method Phaser.Data.DataManager#toggle
|
|
* @fires Phaser.Data.Events#SET_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @since 3.23.0
|
|
*
|
|
* @param {(string|object)} key - The key to toggle the value for.
|
|
*
|
|
* @return {Phaser.Data.DataManager} This DataManager object.
|
|
*/
|
|
toggle: function (key)
|
|
{
|
|
if (this._frozen)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
this.set(key, !this.get(key));
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Internal value setter, called automatically by the `set` method.
|
|
*
|
|
* @method Phaser.Data.DataManager#setValue
|
|
* @fires Phaser.Data.Events#SET_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @private
|
|
* @since 3.10.0
|
|
*
|
|
* @param {string} key - The key to set the value for.
|
|
* @param {*} data - The value to set.
|
|
*
|
|
* @return {this} 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(Events.CHANGE_DATA, parent, key, value, previousValue);
|
|
events.emit(Events.CHANGE_DATA_KEY + key, parent, value, previousValue);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
list[key] = data;
|
|
|
|
events.emit(Events.SET_DATA, 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 {this} 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
|
|
* @fires Phaser.Data.Events#SET_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA
|
|
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @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 {this} 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
|
|
* @fires Phaser.Data.Events#REMOVE_DATA
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|string[])} key - The key to remove, or an array of keys to remove.
|
|
*
|
|
* @return {this} 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
|
|
* @fires Phaser.Data.Events#REMOVE_DATA
|
|
* @since 3.10.0
|
|
*
|
|
* @param {string} key - The key to set the value for.
|
|
*
|
|
* @return {this} 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(Events.REMOVE_DATA, 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
|
|
* @fires Phaser.Data.Events#REMOVE_DATA
|
|
* @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(Events.REMOVE_DATA, this.parent, 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 {this} 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 {this} 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(Events.CHANGE_DATA);
|
|
this.events.off(Events.SET_DATA);
|
|
this.events.off(Events.REMOVE_DATA);
|
|
|
|
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;
|
|
|
|
|
|
/***/ }),
|
|
/* 220 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Data.Events
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
CHANGE_DATA: __webpack_require__(221),
|
|
CHANGE_DATA_KEY: __webpack_require__(222),
|
|
DESTROY: __webpack_require__(223),
|
|
REMOVE_DATA: __webpack_require__(224),
|
|
SET_DATA: __webpack_require__(225)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 221 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Change Data Event.
|
|
*
|
|
* This event is dispatched by a Data Manager when an item in the data store is changed.
|
|
*
|
|
* Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
|
|
* a change data event from a Game Object you would use: `sprite.data.on('changedata', listener)`.
|
|
*
|
|
* This event is dispatched for all items that change in the Data Manager.
|
|
* To listen for the change of a specific item, use the `CHANGE_DATA_KEY_EVENT` event.
|
|
*
|
|
* @event Phaser.Data.Events#CHANGE_DATA
|
|
* @since 3.0.0
|
|
*
|
|
* @param {any} parent - A reference to the object that the Data Manager responsible for this event belongs to.
|
|
* @param {string} key - The unique key of the data item within the Data Manager.
|
|
* @param {any} value - The new value of the item in the Data Manager.
|
|
* @param {any} previousValue - The previous value of the item in the Data Manager.
|
|
*/
|
|
module.exports = 'changedata';
|
|
|
|
|
|
/***/ }),
|
|
/* 222 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Change Data Key Event.
|
|
*
|
|
* This event is dispatched by a Data Manager when an item in the data store is changed.
|
|
*
|
|
* Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
|
|
* the change of a specific data item from a Game Object you would use: `sprite.data.on('changedata-key', listener)`,
|
|
* where `key` is the unique string key of the data item. For example, if you have a data item stored called `gold`
|
|
* then you can listen for `sprite.data.on('changedata-gold')`.
|
|
*
|
|
* @event Phaser.Data.Events#CHANGE_DATA_KEY
|
|
* @since 3.16.1
|
|
*
|
|
* @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
|
|
* @param {any} value - The item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
|
|
* @param {any} previousValue - The previous item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
|
|
*/
|
|
module.exports = 'changedata-';
|
|
|
|
|
|
/***/ }),
|
|
/* 223 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Data Manager Destroy Event.
|
|
*
|
|
* The Data Manager will listen for the destroy event from its parent, and then close itself down.
|
|
*
|
|
* @event Phaser.Data.Events#DESTROY
|
|
* @since 3.50.0
|
|
*/
|
|
module.exports = 'destroy';
|
|
|
|
|
|
/***/ }),
|
|
/* 224 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Remove Data Event.
|
|
*
|
|
* This event is dispatched by a Data Manager when an item is removed from it.
|
|
*
|
|
* Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
|
|
* the removal of a data item on a Game Object you would use: `sprite.data.on('removedata', listener)`.
|
|
*
|
|
* @event Phaser.Data.Events#REMOVE_DATA
|
|
* @since 3.0.0
|
|
*
|
|
* @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
|
|
* @param {string} key - The unique key of the data item within the Data Manager.
|
|
* @param {any} data - The item that was removed from the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
|
|
*/
|
|
module.exports = 'removedata';
|
|
|
|
|
|
/***/ }),
|
|
/* 225 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Set Data Event.
|
|
*
|
|
* This event is dispatched by a Data Manager when a new item is added to the data store.
|
|
*
|
|
* Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
|
|
* the addition of a new data item on a Game Object you would use: `sprite.data.on('setdata', listener)`.
|
|
*
|
|
* @event Phaser.Data.Events#SET_DATA
|
|
* @since 3.0.0
|
|
*
|
|
* @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
|
|
* @param {string} key - The unique key of the data item within the Data Manager.
|
|
* @param {any} data - The item that was added to the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
|
|
*/
|
|
module.exports = 'setdata';
|
|
|
|
|
|
/***/ }),
|
|
/* 226 */
|
|
/***/ (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;
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
/* 227 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Object Added to Scene Event.
|
|
*
|
|
* This event is dispatched when a Game Object is added to a Scene.
|
|
*
|
|
* Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#ADDED_TO_SCENE
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene.
|
|
* @param {Phaser.Scene} scene - The Scene to which the Game Object was added.
|
|
*/
|
|
module.exports = 'addedtoscene';
|
|
|
|
|
|
/***/ }),
|
|
/* 228 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Object Destroy Event.
|
|
*
|
|
* This event is dispatched when a Game Object instance is being destroyed.
|
|
*
|
|
* Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#DESTROY
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object which is being destroyed.
|
|
*/
|
|
module.exports = 'destroy';
|
|
|
|
|
|
/***/ }),
|
|
/* 229 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Object Removed from Scene Event.
|
|
*
|
|
* This event is dispatched when a Game Object is removed from a Scene.
|
|
*
|
|
* Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#REMOVED_FROM_SCENE
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene.
|
|
* @param {Phaser.Scene} scene - The Scene from which the Game Object was removed.
|
|
*/
|
|
module.exports = 'removedfromscene';
|
|
|
|
|
|
/***/ }),
|
|
/* 230 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Complete Event.
|
|
*
|
|
* This event is dispatched when a Video finishes playback by reaching the end of its duration. It
|
|
* is also dispatched if a video marker sequence is being played and reaches the end.
|
|
*
|
|
* Note that not all videos can fire this event. Live streams, for example, have no fixed duration,
|
|
* so never technically 'complete'.
|
|
*
|
|
* If a video is stopped from playback, via the `Video.stop` method, it will emit the
|
|
* `VIDEO_STOP` event instead of this one.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('complete', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_COMPLETE
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which completed playback.
|
|
*/
|
|
module.exports = 'complete';
|
|
|
|
|
|
/***/ }),
|
|
/* 231 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Created Event.
|
|
*
|
|
* This event is dispatched when the texture for a Video has been created. This happens
|
|
* when enough of the video source has been loaded that the browser is able to render a
|
|
* frame from it.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('created', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_CREATED
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event.
|
|
* @param {integer} width - The width of the video.
|
|
* @param {integer} height - The height of the video.
|
|
*/
|
|
module.exports = 'created';
|
|
|
|
|
|
/***/ }),
|
|
/* 232 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Error Event.
|
|
*
|
|
* This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('error', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_ERROR
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error.
|
|
* @param {Event} event - The native DOM event the browser raised during playback.
|
|
*/
|
|
module.exports = 'error';
|
|
|
|
|
|
/***/ }),
|
|
/* 233 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Loop Event.
|
|
*
|
|
* This event is dispatched when a Video that is currently playing has looped. This only
|
|
* happens if the `loop` parameter was specified, or the `setLoop` method was called,
|
|
* and if the video has a fixed duration. Video streams, for example, cannot loop, as
|
|
* they have no duration.
|
|
*
|
|
* Looping is based on the result of the Video `timeupdate` event. This event is not
|
|
* frame-accurate, due to the way browsers work, so please do not rely on this loop
|
|
* event to be time or frame precise.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('loop', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_LOOP
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which has looped.
|
|
*/
|
|
module.exports = 'loop';
|
|
|
|
|
|
/***/ }),
|
|
/* 234 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Play Event.
|
|
*
|
|
* This event is dispatched when a Video begins playback. For videos that do not require
|
|
* interaction unlocking, this is usually as soon as the `Video.play` method is called.
|
|
* However, for videos that require unlocking, it is fired once playback begins after
|
|
* they've been unlocked.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('play', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_PLAY
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback.
|
|
*/
|
|
module.exports = 'play';
|
|
|
|
|
|
/***/ }),
|
|
/* 235 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Seeked Event.
|
|
*
|
|
* This event is dispatched when a Video completes seeking to a new point in its timeline.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_SEEKED
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which completed seeking.
|
|
*/
|
|
module.exports = 'seeked';
|
|
|
|
|
|
/***/ }),
|
|
/* 236 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Seeking Event.
|
|
*
|
|
* This event is dispatched when a Video _begins_ seeking to a new point in its timeline.
|
|
* When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_SEEKING
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which started seeking.
|
|
*/
|
|
module.exports = 'seeking';
|
|
|
|
|
|
/***/ }),
|
|
/* 237 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Stopped Event.
|
|
*
|
|
* This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method,
|
|
* either directly via game code, or indirectly as the result of changing a video source or destroying it.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('stop', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_STOP
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which stopped playback.
|
|
*/
|
|
module.exports = 'stop';
|
|
|
|
|
|
/***/ }),
|
|
/* 238 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Timeout Event.
|
|
*
|
|
* This event is dispatched when a Video has exhausted its allocated time while trying to connect to a video
|
|
* source to start playback.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('timeout', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_TIMEOUT
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which timed out.
|
|
*/
|
|
module.exports = 'timeout';
|
|
|
|
|
|
/***/ }),
|
|
/* 239 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Video Game Object Unlocked Event.
|
|
*
|
|
* This event is dispatched when a Video that was prevented from playback due to the browsers
|
|
* Media Engagement Interaction policy, is unlocked by a user gesture.
|
|
*
|
|
* Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`.
|
|
*
|
|
* @event Phaser.GameObjects.Events#VIDEO_UNLOCKED
|
|
* @since 3.20.0
|
|
*
|
|
* @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event.
|
|
*/
|
|
module.exports = 'unlocked';
|
|
|
|
|
|
/***/ }),
|
|
/* 240 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace SpinePluginEvents
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
COMPLETE: __webpack_require__(241),
|
|
DISPOSE: __webpack_require__(242),
|
|
END: __webpack_require__(243),
|
|
EVENT: __webpack_require__(244),
|
|
INTERRUPTED: __webpack_require__(245),
|
|
START: __webpack_require__(246)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 241 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Complete Event.
|
|
*
|
|
* @event SpinePluginEvents#COMPLETE
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'complete';
|
|
|
|
|
|
/***/ }),
|
|
/* 242 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Dispose Event.
|
|
*
|
|
* @event SpinePluginEvents#DISPOSE
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'dispose';
|
|
|
|
|
|
/***/ }),
|
|
/* 243 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The End Event.
|
|
*
|
|
* @event SpinePluginEvents#END
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'end';
|
|
|
|
|
|
/***/ }),
|
|
/* 244 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Custom Event Event.
|
|
*
|
|
* @event SpinePluginEvents#EVENT
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'event';
|
|
|
|
|
|
/***/ }),
|
|
/* 245 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Interrupted Event.
|
|
*
|
|
* @event SpinePluginEvents#INTERRUPTED
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'interrupted';
|
|
|
|
|
|
/***/ }),
|
|
/* 246 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Start Event.
|
|
*
|
|
* @event SpinePluginEvents#START
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'start';
|
|
|
|
|
|
/***/ }),
|
|
/* 247 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var renderWebGL = __webpack_require__(1);
|
|
var renderCanvas = __webpack_require__(1);
|
|
|
|
if (true)
|
|
{
|
|
renderWebGL = __webpack_require__(248);
|
|
}
|
|
|
|
if (true)
|
|
{
|
|
renderCanvas = __webpack_require__(250);
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
renderWebGL: renderWebGL,
|
|
renderCanvas: renderCanvas
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 248 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var CounterClockwise = __webpack_require__(8);
|
|
var GetCalcMatrix = __webpack_require__(249);
|
|
var RadToDeg = __webpack_require__(9);
|
|
var Wrap = __webpack_require__(6);
|
|
|
|
/**
|
|
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method SpineGameObject#renderWebGL
|
|
* @since 3.19.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
|
|
* @param {SpineGameObject} src - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var SpineGameObjectWebGLRenderer = function (renderer, src, camera, parentMatrix)
|
|
{
|
|
var plugin = src.plugin;
|
|
var skeleton = src.skeleton;
|
|
var childAlpha = skeleton.color.a;
|
|
var sceneRenderer = plugin.sceneRenderer;
|
|
|
|
var GameObjectRenderMask = 15;
|
|
|
|
var willRender = !(GameObjectRenderMask !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || childAlpha === 0);
|
|
|
|
if (!skeleton || !willRender)
|
|
{
|
|
// If there is already a batch running, and the next type isn't a Spine object, or this is the end, we need to close it
|
|
|
|
if (sceneRenderer.batcher.isDrawing && (!renderer.nextTypeMatch || renderer.finalType))
|
|
{
|
|
// The next object in the display list is not a Spine object, so we end the batch
|
|
sceneRenderer.end();
|
|
|
|
renderer.pipelines.rebind();
|
|
}
|
|
|
|
if (!renderer.finalType)
|
|
{
|
|
// Reset the current type
|
|
renderer.currentType = '';
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (renderer.newType)
|
|
{
|
|
// flush + clear previous pipeline if this is a new type
|
|
renderer.pipelines.clear();
|
|
}
|
|
|
|
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
|
|
|
|
var viewportHeight = renderer.height;
|
|
|
|
skeleton.x = calcMatrix.tx;
|
|
skeleton.y = viewportHeight - calcMatrix.ty;
|
|
|
|
skeleton.scaleX = calcMatrix.scaleX;
|
|
skeleton.scaleY = calcMatrix.scaleY;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
skeleton.scaleX *= -1;
|
|
|
|
src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
|
|
}
|
|
else
|
|
{
|
|
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
|
src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
|
|
}
|
|
|
|
if (src.scaleY < 0)
|
|
{
|
|
skeleton.scaleY *= -1;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
else
|
|
{
|
|
src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
}
|
|
|
|
if (camera.renderToTexture || renderer.currentFramebuffer !== null)
|
|
{
|
|
skeleton.y = calcMatrix.ty;
|
|
skeleton.scaleY *= -1;
|
|
}
|
|
|
|
// Add autoUpdate option
|
|
skeleton.updateWorldTransform();
|
|
|
|
if (renderer.newType)
|
|
{
|
|
sceneRenderer.begin();
|
|
}
|
|
|
|
// Draw the current skeleton
|
|
sceneRenderer.drawSkeleton(skeleton, src.preMultipliedAlpha);
|
|
|
|
if (plugin.drawDebug || src.drawDebug)
|
|
{
|
|
// Because if we don't, the bones render positions are completely wrong (*sigh*)
|
|
var oldX = skeleton.x;
|
|
var oldY = skeleton.y;
|
|
|
|
skeleton.x = 0;
|
|
skeleton.y = 0;
|
|
|
|
sceneRenderer.drawSkeletonDebug(skeleton, src.preMultipliedAlpha);
|
|
|
|
skeleton.x = oldX;
|
|
skeleton.y = oldY;
|
|
}
|
|
|
|
if (!renderer.nextTypeMatch)
|
|
{
|
|
// The next object in the display list is not a Spine Game Object or Spine Container, so we end the batch
|
|
sceneRenderer.end();
|
|
|
|
// And rebind the previous pipeline
|
|
renderer.pipelines.rebind();
|
|
}
|
|
};
|
|
|
|
module.exports = SpineGameObjectWebGLRenderer;
|
|
|
|
|
|
/***/ }),
|
|
/* 249 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var TransformMatrix = __webpack_require__(23);
|
|
|
|
var tempMatrix1 = new TransformMatrix();
|
|
var tempMatrix2 = new TransformMatrix();
|
|
var tempMatrix3 = new TransformMatrix();
|
|
|
|
var result = { camera: tempMatrix1, sprite: tempMatrix2, calc: tempMatrix3 };
|
|
|
|
/**
|
|
* Calculates the Transform Matrix of the given Game Object and Camera, factoring in
|
|
* the parent matrix if provided.
|
|
*
|
|
* Note that the object this results contains _references_ to the Transform Matrices,
|
|
* not new instances of them. Therefore, you should use their values immediately, or
|
|
* copy them to your own matrix, as they will be replaced as soon as another Game
|
|
* Object is rendered.
|
|
*
|
|
* @function Phaser.GameObjects.GetCalcMatrix
|
|
* @memberof Phaser.GameObjects
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} src - The Game Object to calculate the transform matrix for.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera being used to render the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - The transform matrix of the parent container, if any.
|
|
*
|
|
* @return {Phaser.Types.GameObjects.GetCalcMatrixResults} The results object containing the updated transform matrices.
|
|
*/
|
|
var GetCalcMatrix = function (src, camera, parentMatrix)
|
|
{
|
|
var camMatrix = tempMatrix1;
|
|
var spriteMatrix = tempMatrix2;
|
|
var calcMatrix = tempMatrix3;
|
|
|
|
spriteMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);
|
|
|
|
camMatrix.copyFrom(camera.matrix);
|
|
|
|
if (parentMatrix)
|
|
{
|
|
// Multiply the camera by the parent matrix
|
|
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
|
|
|
|
// Undo the camera scroll
|
|
spriteMatrix.e = src.x;
|
|
spriteMatrix.f = src.y;
|
|
}
|
|
else
|
|
{
|
|
spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
|
|
spriteMatrix.f -= camera.scrollY * src.scrollFactorY;
|
|
}
|
|
|
|
// Multiply by the Sprite matrix, store result in calcMatrix
|
|
camMatrix.multiply(spriteMatrix, calcMatrix);
|
|
|
|
return result;
|
|
};
|
|
|
|
module.exports = GetCalcMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 250 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var CounterClockwise = __webpack_require__(8);
|
|
var RadToDeg = __webpack_require__(9);
|
|
var Wrap = __webpack_require__(6);
|
|
|
|
/**
|
|
* Renders this Game Object with the Canvas Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method SpineGameObject#renderCanvas
|
|
* @since 3.19.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
|
|
* @param {SpineGameObject} src - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var SpineGameObjectCanvasRenderer = function (renderer, src, camera, parentMatrix)
|
|
{
|
|
var context = renderer.currentContext;
|
|
|
|
var plugin = src.plugin;
|
|
var skeleton = src.skeleton;
|
|
var skeletonRenderer = plugin.skeletonRenderer;
|
|
|
|
var GameObjectRenderMask = 15;
|
|
|
|
var willRender = !(GameObjectRenderMask !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)));
|
|
|
|
if (!skeleton || !willRender)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var camMatrix = renderer._tempMatrix1;
|
|
var spriteMatrix = renderer._tempMatrix2;
|
|
var calcMatrix = renderer._tempMatrix3;
|
|
|
|
spriteMatrix.applyITRS(src.x, src.y, src.rotation, Math.abs(src.scaleX), Math.abs(src.scaleY));
|
|
|
|
camMatrix.copyFrom(camera.matrix);
|
|
|
|
if (parentMatrix)
|
|
{
|
|
// Multiply the camera by the parent matrix
|
|
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
|
|
|
|
// Undo the camera scroll
|
|
spriteMatrix.e = src.x;
|
|
spriteMatrix.f = src.y;
|
|
|
|
// Multiply by the Sprite matrix, store result in calcMatrix
|
|
camMatrix.multiply(spriteMatrix, calcMatrix);
|
|
}
|
|
else
|
|
{
|
|
spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
|
|
spriteMatrix.f -= camera.scrollY * src.scrollFactorY;
|
|
|
|
// Multiply by the Sprite matrix, store result in calcMatrix
|
|
camMatrix.multiply(spriteMatrix, calcMatrix);
|
|
}
|
|
|
|
skeleton.x = calcMatrix.tx;
|
|
skeleton.y = calcMatrix.ty;
|
|
|
|
skeleton.scaleX = calcMatrix.scaleX;
|
|
|
|
// Inverse or we get upside-down skeletons
|
|
skeleton.scaleY = calcMatrix.scaleY * -1;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
skeleton.scaleX *= -1;
|
|
|
|
src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
|
|
}
|
|
else
|
|
{
|
|
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
|
src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
|
|
}
|
|
|
|
if (src.scaleY < 0)
|
|
{
|
|
skeleton.scaleY *= -1;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
else
|
|
{
|
|
src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
}
|
|
|
|
if (camera.renderToTexture)
|
|
{
|
|
skeleton.y = calcMatrix.ty;
|
|
skeleton.scaleY *= -1;
|
|
}
|
|
|
|
// Add autoUpdate option
|
|
skeleton.updateWorldTransform();
|
|
|
|
skeletonRenderer.ctx = context;
|
|
skeletonRenderer.debugRendering = (plugin.drawDebug || src.drawDebug);
|
|
|
|
context.save();
|
|
|
|
skeletonRenderer.draw(skeleton);
|
|
|
|
context.restore();
|
|
};
|
|
|
|
module.exports = SpineGameObjectCanvasRenderer;
|
|
|
|
|
|
/***/ }),
|
|
/* 251 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var Container = __webpack_require__(252);
|
|
var SpineContainerRender = __webpack_require__(338);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Spine Container is a special kind of Container created specifically for Spine Game Objects.
|
|
*
|
|
* You have all of the same features of a standard Container, but the rendering functions are optimized specifically
|
|
* for Spine Game Objects. You must only add ever Spine Game Objects to this type of Container. Although Phaser will
|
|
* not prevent you from adding other types, they will not render and are likely to throw runtime errors.
|
|
*
|
|
* To create one in a Scene, use the factory methods:
|
|
*
|
|
* ```javascript
|
|
* this.add.spinecontainer();
|
|
* ```
|
|
*
|
|
* or
|
|
*
|
|
* ```javascript
|
|
* this.make.spinecontainer();
|
|
* ```
|
|
*
|
|
* See the Container documentation for further details about what Containers can do.
|
|
*
|
|
* @class SpineContainer
|
|
* @extends Phaser.GameObjects.Container
|
|
* @constructor
|
|
* @since 3.50.0
|
|
*
|
|
* @param {Phaser.Scene} scene - A reference to the Scene that this Game Object belongs to.
|
|
* @param {SpinePlugin} pluginManager - A reference to the Phaser Spine Plugin.
|
|
* @param {number} x - The horizontal position of this Game Object in the world.
|
|
* @param {number} y - The vertical position of this Game Object in the world.
|
|
* @param {SpineGameObject[]} [children] - An optional array of Spine Game Objects to add to this Container.
|
|
*/
|
|
var SpineContainer = new Class({
|
|
|
|
Extends: Container,
|
|
|
|
Mixins: [
|
|
SpineContainerRender
|
|
],
|
|
|
|
initialize:
|
|
|
|
function SpineContainer (scene, plugin, x, y, children)
|
|
{
|
|
Container.call(this, scene, x, y, children);
|
|
|
|
// Same as SpineGameObject, to prevent the renderer from mis-typing it when batching
|
|
this.type = 'Spine';
|
|
|
|
/**
|
|
* A reference to the Spine Plugin.
|
|
*
|
|
* @name SpineContainer#plugin
|
|
* @type {SpinePlugin}
|
|
* @since 3.50.0
|
|
*/
|
|
this.plugin = plugin;
|
|
},
|
|
|
|
/**
|
|
* Internal destroy handler, called as part of the destroy process.
|
|
*
|
|
* @method SpineContainer#preDestroy
|
|
* @protected
|
|
* @since 3.50.0
|
|
*/
|
|
preDestroy: function ()
|
|
{
|
|
this.removeAll(!!this.exclusive);
|
|
|
|
this.localTransform.destroy();
|
|
this.tempTransformMatrix.destroy();
|
|
|
|
this.list = [];
|
|
this._displayList = null;
|
|
this.plugin = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = SpineContainer;
|
|
|
|
|
|
/***/ }),
|
|
/* 252 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author Felipe Alfonso <@bitnenfer>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var ArrayUtils = __webpack_require__(253);
|
|
var BlendModes = __webpack_require__(17);
|
|
var Class = __webpack_require__(0);
|
|
var Components = __webpack_require__(290);
|
|
var Events = __webpack_require__(54);
|
|
var GameObject = __webpack_require__(52);
|
|
var Rectangle = __webpack_require__(25);
|
|
var Render = __webpack_require__(334);
|
|
var Union = __webpack_require__(337);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Container Game Object.
|
|
*
|
|
* A Container, as the name implies, can 'contain' other types of Game Object.
|
|
* When a Game Object is added to a Container, the Container becomes responsible for the rendering of it.
|
|
* By default it will be removed from the Display List and instead added to the Containers own internal list.
|
|
*
|
|
* The position of the Game Object automatically becomes relative to the position of the Container.
|
|
*
|
|
* The origin of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the
|
|
* Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of
|
|
* the Container, and position children positively and negative around it as required.
|
|
*
|
|
* When the Container is rendered, all of its children are rendered as well, in the order in which they exist
|
|
* within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`.
|
|
*
|
|
* If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will
|
|
* automatically influence all children as well.
|
|
*
|
|
* Containers can include other Containers for deeply nested transforms.
|
|
*
|
|
* Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked.
|
|
* The masks do not 'stack up'. Only a Container on the root of the display list will use its mask.
|
|
*
|
|
* Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them
|
|
* to use as their hit area. Container children can also be enabled for input, independent of the Container.
|
|
*
|
|
* If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child,
|
|
* or the input area will become misaligned.
|
|
*
|
|
* Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However,
|
|
* if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies,
|
|
* if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children
|
|
* with physics do not factor in the Container due to the excessive extra calculations needed. Please structure
|
|
* your game to work around this.
|
|
*
|
|
* It's important to understand the impact of using Containers. They add additional processing overhead into
|
|
* every one of their children. The deeper you nest them, the more the cost escalates. This is especially true
|
|
* for input events. You also loose the ability to set the display depth of Container children in the same
|
|
* flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost
|
|
* every time you create one, try to structure your game around avoiding that where possible.
|
|
*
|
|
* @class Container
|
|
* @extends Phaser.GameObjects.GameObject
|
|
* @memberof Phaser.GameObjects
|
|
* @constructor
|
|
* @since 3.4.0
|
|
*
|
|
* @extends Phaser.GameObjects.Components.AlphaSingle
|
|
* @extends Phaser.GameObjects.Components.BlendMode
|
|
* @extends Phaser.GameObjects.Components.ComputedSize
|
|
* @extends Phaser.GameObjects.Components.Depth
|
|
* @extends Phaser.GameObjects.Components.Mask
|
|
* @extends Phaser.GameObjects.Components.Transform
|
|
* @extends Phaser.GameObjects.Components.Visible
|
|
*
|
|
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
|
|
* @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.
|
|
*/
|
|
var Container = new Class({
|
|
|
|
Extends: GameObject,
|
|
|
|
Mixins: [
|
|
Components.AlphaSingle,
|
|
Components.BlendMode,
|
|
Components.ComputedSize,
|
|
Components.Depth,
|
|
Components.Mask,
|
|
Components.Transform,
|
|
Components.Visible,
|
|
Render
|
|
],
|
|
|
|
initialize:
|
|
|
|
function Container (scene, x, y, children)
|
|
{
|
|
GameObject.call(this, scene, 'Container');
|
|
|
|
/**
|
|
* An array holding the children of this Container.
|
|
*
|
|
* @name Phaser.GameObjects.Container#list
|
|
* @type {Phaser.GameObjects.GameObject[]}
|
|
* @since 3.4.0
|
|
*/
|
|
this.list = [];
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Containers can have an optional maximum size. If set to anything above 0 it
|
|
* will constrict the addition of new Game Objects into the Container, capping off
|
|
* the maximum limit the Container can grow in size to.
|
|
*
|
|
* @name Phaser.GameObjects.Container#maxSize
|
|
* @type {integer}
|
|
* @default -1
|
|
* @since 3.4.0
|
|
*/
|
|
this.maxSize = -1;
|
|
|
|
/**
|
|
* The cursor position.
|
|
*
|
|
* @name Phaser.GameObjects.Container#position
|
|
* @type {integer}
|
|
* @since 3.4.0
|
|
*/
|
|
this.position = 0;
|
|
|
|
/**
|
|
* Internal Transform Matrix used for local space conversion.
|
|
*
|
|
* @name Phaser.GameObjects.Container#localTransform
|
|
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
|
* @since 3.4.0
|
|
*/
|
|
this.localTransform = new Components.TransformMatrix();
|
|
|
|
/**
|
|
* Internal temporary Transform Matrix used to avoid object creation.
|
|
*
|
|
* @name Phaser.GameObjects.Container#tempTransformMatrix
|
|
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
|
* @private
|
|
* @since 3.4.0
|
|
*/
|
|
this.tempTransformMatrix = new Components.TransformMatrix();
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* The property key to sort by.
|
|
*
|
|
* @name Phaser.GameObjects.Container#_sortKey
|
|
* @type {string}
|
|
* @private
|
|
* @since 3.4.0
|
|
*/
|
|
this._sortKey = '';
|
|
|
|
/**
|
|
* A reference to the Scene Systems Event Emitter.
|
|
*
|
|
* @name Phaser.GameObjects.Container#_sysEvents
|
|
* @type {Phaser.Events.EventEmitter}
|
|
* @private
|
|
* @since 3.9.0
|
|
*/
|
|
this._sysEvents = scene.sys.events;
|
|
|
|
/**
|
|
* The horizontal scroll factor of this Container.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Container.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Container is rendered on-screen.
|
|
* It does not change the Containers actual position values.
|
|
*
|
|
* For a Container, setting this value will only update the Container itself, not its children.
|
|
* If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Container.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @name Phaser.GameObjects.Container#scrollFactorX
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
this.scrollFactorX = 1;
|
|
|
|
/**
|
|
* The vertical scroll factor of this Container.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Container.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Container is rendered on-screen.
|
|
* It does not change the Containers actual position values.
|
|
*
|
|
* For a Container, setting this value will only update the Container itself, not its children.
|
|
* If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Container.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @name Phaser.GameObjects.Container#scrollFactorY
|
|
* @type {number}
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
this.scrollFactorY = 1;
|
|
|
|
this.setPosition(x, y);
|
|
|
|
this.clearAlpha();
|
|
|
|
this.setBlendMode(BlendModes.SKIP_CHECK);
|
|
|
|
if (children)
|
|
{
|
|
this.add(children);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Internal value to allow Containers to be used for input and physics.
|
|
* Do not change this value. It has no effect other than to break things.
|
|
*
|
|
* @name Phaser.GameObjects.Container#originX
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
originX: {
|
|
|
|
get: function ()
|
|
{
|
|
return 0.5;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Internal value to allow Containers to be used for input and physics.
|
|
* Do not change this value. It has no effect other than to break things.
|
|
*
|
|
* @name Phaser.GameObjects.Container#originY
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
originY: {
|
|
|
|
get: function ()
|
|
{
|
|
return 0.5;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Internal value to allow Containers to be used for input and physics.
|
|
* Do not change this value. It has no effect other than to break things.
|
|
*
|
|
* @name Phaser.GameObjects.Container#displayOriginX
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
displayOriginX: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.width * 0.5;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Internal value to allow Containers to be used for input and physics.
|
|
* Do not change this value. It has no effect other than to break things.
|
|
*
|
|
* @name Phaser.GameObjects.Container#displayOriginY
|
|
* @type {number}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
displayOriginY: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.height * 0.5;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* 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 {this} This Container.
|
|
*/
|
|
setExclusive: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.exclusive = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Gets the bounds of this Container. It works by iterating all children of the Container,
|
|
* getting their respective bounds, and then working out a min-max rectangle from that.
|
|
* It does not factor in if the children render or not, all are included.
|
|
*
|
|
* Some children are unable to return their bounds, such as Graphics objects, in which case
|
|
* they are skipped.
|
|
*
|
|
* Depending on the quantity of children in this Container it could be a really expensive call,
|
|
* so cache it and only poll it as needed.
|
|
*
|
|
* The values are stored and returned in a Rectangle object.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getBounds
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} [output] - A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created.
|
|
*
|
|
* @return {Phaser.Geom.Rectangle} The values stored in the output object.
|
|
*/
|
|
getBounds: function (output)
|
|
{
|
|
if (output === undefined) { output = new Rectangle(); }
|
|
|
|
output.setTo(this.x, this.y, 0, 0);
|
|
|
|
if (this.parentContainer)
|
|
{
|
|
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
|
|
var transformedPosition = parentMatrix.transformPoint(this.x, this.y);
|
|
|
|
output.setTo(transformedPosition.x, transformedPosition.y, 0, 0);
|
|
}
|
|
|
|
if (this.list.length > 0)
|
|
{
|
|
var children = this.list;
|
|
var tempRect = new Rectangle();
|
|
var hasSetFirst = false;
|
|
|
|
output.setEmpty();
|
|
|
|
for (var i = 0; i < children.length; i++)
|
|
{
|
|
var entry = children[i];
|
|
|
|
if (entry.getBounds)
|
|
{
|
|
entry.getBounds(tempRect);
|
|
|
|
if (!hasSetFirst)
|
|
{
|
|
output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height);
|
|
hasSetFirst = true;
|
|
}
|
|
else
|
|
{
|
|
Union(tempRect, output, output);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Internal add handler.
|
|
*
|
|
* @method Phaser.GameObjects.Container#addHandler
|
|
* @private
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container.
|
|
*/
|
|
addHandler: function (gameObject)
|
|
{
|
|
gameObject.once(Events.DESTROY, this.remove, this);
|
|
|
|
if (this.exclusive)
|
|
{
|
|
this._displayList.remove(gameObject);
|
|
|
|
if (gameObject.parentContainer)
|
|
{
|
|
gameObject.parentContainer.remove(gameObject);
|
|
}
|
|
|
|
gameObject.parentContainer = this;
|
|
}
|
|
|
|
// Is only on the Display List via this Container
|
|
if (!this.scene.sys.displayList.exists(gameObject))
|
|
{
|
|
gameObject.emit(Events.ADDED_TO_SCENE, gameObject, this.scene);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Internal remove handler.
|
|
*
|
|
* @method Phaser.GameObjects.Container#removeHandler
|
|
* @private
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container.
|
|
*/
|
|
removeHandler: function (gameObject)
|
|
{
|
|
gameObject.off(Events.DESTROY, this.remove);
|
|
|
|
if (this.exclusive)
|
|
{
|
|
gameObject.parentContainer = null;
|
|
}
|
|
|
|
// Is only on the Display List via this Container
|
|
if (!this.scene.sys.displayList.exists(gameObject))
|
|
{
|
|
gameObject.emit(Events.REMOVED_FROM_SCENE, gameObject, this.scene);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
if (output === undefined) { output = new Vector2(); }
|
|
|
|
if (this.parentContainer)
|
|
{
|
|
this.parentContainer.pointToContainer(source, output);
|
|
}
|
|
else
|
|
{
|
|
output = new Vector2(source.x, source.y);
|
|
}
|
|
|
|
var tempMatrix = this.tempTransformMatrix;
|
|
|
|
// No need to loadIdentity because applyITRS overwrites every value anyway
|
|
tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY);
|
|
|
|
tempMatrix.invert();
|
|
|
|
tempMatrix.transformPoint(source.x, source.y, output);
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Returns the world transform matrix as used for Bounds checks.
|
|
*
|
|
* The returned matrix is temporal and shouldn't be stored.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getBoundsTransformMatrix
|
|
* @since 3.4.0
|
|
*
|
|
* @return {Phaser.GameObjects.Components.TransformMatrix} The world transform matrix.
|
|
*/
|
|
getBoundsTransformMatrix: function ()
|
|
{
|
|
return this.getWorldTransformMatrix(this.tempTransformMatrix, this.localTransform);
|
|
},
|
|
|
|
/**
|
|
* Adds the given Game Object, or array of Game Objects, to this Container.
|
|
*
|
|
* Each Game Object must be unique within the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#add
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
add: function (child)
|
|
{
|
|
ArrayUtils.Add(this.list, child, this.maxSize, this.addHandler, this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Adds the given Game Object, or array of Game Objects, to this Container at the specified position.
|
|
*
|
|
* Existing Game Objects in the Container are shifted up.
|
|
*
|
|
* Each Game Object must be unique within the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#addAt
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
|
|
* @param {integer} [index=0] - The position to insert the Game Object/s at.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
addAt: function (child, index)
|
|
{
|
|
ArrayUtils.AddAt(this.list, child, index, this.maxSize, this.addHandler, this);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Returns the Game Object at the given position in this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getAt
|
|
* @since 3.4.0
|
|
*
|
|
* @param {integer} index - The position to get the Game Object from.
|
|
*
|
|
* @return {?Phaser.GameObjects.GameObject} The Game Object at the specified index, or `null` if none found.
|
|
*/
|
|
getAt: function (index)
|
|
{
|
|
return this.list[index];
|
|
},
|
|
|
|
/**
|
|
* Returns the index of the given Game Object in this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getIndex
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to search for in this Container.
|
|
*
|
|
* @return {integer} The index of the Game Object in this Container, or -1 if not found.
|
|
*/
|
|
getIndex: function (child)
|
|
{
|
|
return this.list.indexOf(child);
|
|
},
|
|
|
|
/**
|
|
* Sort the contents of this Container so the items are in order based on the given property.
|
|
* For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property.
|
|
*
|
|
* @method Phaser.GameObjects.Container#sort
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} property - The property to lexically sort by.
|
|
* @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
sort: function (property, handler)
|
|
{
|
|
if (!property)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
if (handler === undefined)
|
|
{
|
|
handler = function (childA, childB)
|
|
{
|
|
return childA[property] - childB[property];
|
|
};
|
|
}
|
|
|
|
ArrayUtils.StableSort(this.list, handler);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Searches for the first instance of a child with its `name` property matching the given argument.
|
|
* Should more than one child have the same name only the first is returned.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getByName
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} name - The name to search for.
|
|
*
|
|
* @return {?Phaser.GameObjects.GameObject} The first child with a matching name, or `null` if none were found.
|
|
*/
|
|
getByName: function (name)
|
|
{
|
|
return ArrayUtils.GetFirst(this.list, 'name', name);
|
|
},
|
|
|
|
/**
|
|
* Returns a random Game Object from this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getRandom
|
|
* @since 3.4.0
|
|
*
|
|
* @param {integer} [startIndex=0] - An optional start index.
|
|
* @param {integer} [length] - An optional length, the total number of elements (from the startIndex) to choose from.
|
|
*
|
|
* @return {?Phaser.GameObjects.GameObject} A random child from the Container, or `null` if the Container is empty.
|
|
*/
|
|
getRandom: function (startIndex, length)
|
|
{
|
|
return ArrayUtils.GetRandom(this.list, startIndex, length);
|
|
},
|
|
|
|
/**
|
|
* Gets the first Game Object in this Container.
|
|
*
|
|
* You can also specify a property and value to search for, in which case it will return the first
|
|
* Game Object in this Container with a matching property and / or value.
|
|
*
|
|
* For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set.
|
|
*
|
|
* You can limit the search to the `startIndex` - `endIndex` range.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getFirst
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} property - The property to test on each Game Object in the Container.
|
|
* @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check.
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=Container.length] - An optional end index to search up to (but not included)
|
|
*
|
|
* @return {?Phaser.GameObjects.GameObject} The first matching Game Object, or `null` if none was found.
|
|
*/
|
|
getFirst: function (property, value, startIndex, endIndex)
|
|
{
|
|
return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex);
|
|
},
|
|
|
|
/**
|
|
* Returns all Game Objects in this Container.
|
|
*
|
|
* You can optionally specify a matching criteria using the `property` and `value` arguments.
|
|
*
|
|
* For example: `getAll('body')` would return only Game Objects that have a body property.
|
|
*
|
|
* You can also specify a value to compare the property to:
|
|
*
|
|
* `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`.
|
|
*
|
|
* Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
|
|
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
|
|
* the first 50 Game Objects.
|
|
*
|
|
* @method Phaser.GameObjects.Container#getAll
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} [property] - The property to test on each Game Object in the Container.
|
|
* @param {any} [value] - If property is set then the `property` must strictly equal this value to be included in the results.
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=Container.length] - An optional end index to search up to (but not included)
|
|
*
|
|
* @return {Phaser.GameObjects.GameObject[]} An array of matching Game Objects from this Container.
|
|
*/
|
|
getAll: function (property, value, startIndex, endIndex)
|
|
{
|
|
return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex);
|
|
},
|
|
|
|
/**
|
|
* Returns the total number of Game Objects in this Container that have a property
|
|
* matching the given value.
|
|
*
|
|
* For example: `count('visible', true)` would count all the elements that have their visible property set.
|
|
*
|
|
* You can optionally limit the operation to the `startIndex` - `endIndex` range.
|
|
*
|
|
* @method Phaser.GameObjects.Container#count
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} property - The property to check.
|
|
* @param {any} value - The value to check.
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=Container.length] - An optional end index to search up to (but not included)
|
|
*
|
|
* @return {integer} The total number of Game Objects in this Container with a property matching the given value.
|
|
*/
|
|
count: function (property, value, startIndex, endIndex)
|
|
{
|
|
return ArrayUtils.CountAllMatching(this.list, property, value, startIndex, endIndex);
|
|
},
|
|
|
|
/**
|
|
* Swaps the position of two Game Objects in this Container.
|
|
* Both Game Objects must belong to this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#swap
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child1 - The first Game Object to swap.
|
|
* @param {Phaser.GameObjects.GameObject} child2 - The second Game Object to swap.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
swap: function (child1, child2)
|
|
{
|
|
ArrayUtils.Swap(this.list, child1, child2);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Moves a Game Object to a new position within this Container.
|
|
*
|
|
* The Game Object must already be a child of this Container.
|
|
*
|
|
* The Game Object is removed from its old position and inserted into the new one.
|
|
* Therefore the Container size does not change. Other children will change position accordingly.
|
|
*
|
|
* @method Phaser.GameObjects.Container#moveTo
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to move.
|
|
* @param {integer} index - The new position of the Game Object in this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
moveTo: function (child, index)
|
|
{
|
|
ArrayUtils.MoveTo(this.list, child, index);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes the given Game Object, or array of Game Objects, from this Container.
|
|
*
|
|
* The Game Objects must already be children of this Container.
|
|
*
|
|
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#remove
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to be removed from the Container.
|
|
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
remove: function (child, destroyChild)
|
|
{
|
|
var removed = ArrayUtils.Remove(this.list, child, this.removeHandler, this);
|
|
|
|
if (destroyChild && removed)
|
|
{
|
|
if (!Array.isArray(removed))
|
|
{
|
|
removed = [ removed ];
|
|
}
|
|
|
|
for (var i = 0; i < removed.length; i++)
|
|
{
|
|
removed[i].destroy();
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes the Game Object at the given position in this Container.
|
|
*
|
|
* You can also optionally call `destroy` on the Game Object, if one is found.
|
|
*
|
|
* @method Phaser.GameObjects.Container#removeAt
|
|
* @since 3.4.0
|
|
*
|
|
* @param {integer} index - The index of the Game Object to be removed.
|
|
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
removeAt: function (index, destroyChild)
|
|
{
|
|
var removed = ArrayUtils.RemoveAt(this.list, index, this.removeHandler, this);
|
|
|
|
if (destroyChild && removed)
|
|
{
|
|
removed.destroy();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes the Game Objects between the given positions in this Container.
|
|
*
|
|
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#removeBetween
|
|
* @since 3.4.0
|
|
*
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=Container.length] - An optional end index to search up to (but not included)
|
|
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
removeBetween: function (startIndex, endIndex, destroyChild)
|
|
{
|
|
var removed = ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeHandler, this);
|
|
|
|
if (destroyChild)
|
|
{
|
|
for (var i = 0; i < removed.length; i++)
|
|
{
|
|
removed[i].destroy();
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes all Game Objects from this Container.
|
|
*
|
|
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#removeAll
|
|
* @since 3.4.0
|
|
*
|
|
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
removeAll: function (destroyChild)
|
|
{
|
|
var removed = ArrayUtils.RemoveBetween(this.list, 0, this.list.length, this.removeHandler, this);
|
|
|
|
if (destroyChild)
|
|
{
|
|
for (var i = 0; i < removed.length; i++)
|
|
{
|
|
removed[i].destroy();
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Brings the given Game Object to the top of this Container.
|
|
* This will cause it to render on-top of any other objects in the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#bringToTop
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to bring to the top of the Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
bringToTop: function (child)
|
|
{
|
|
ArrayUtils.BringToTop(this.list, child);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sends the given Game Object to the bottom of this Container.
|
|
* This will cause it to render below any other objects in the Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#sendToBack
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to send to the bottom of the Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
sendToBack: function (child)
|
|
{
|
|
ArrayUtils.SendToBack(this.list, child);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Moves the given Game Object up one place in this Container, unless it's already at the top.
|
|
*
|
|
* @method Phaser.GameObjects.Container#moveUp
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
moveUp: function (child)
|
|
{
|
|
ArrayUtils.MoveUp(this.list, child);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Moves the given Game Object down one place in this Container, unless it's already at the bottom.
|
|
*
|
|
* @method Phaser.GameObjects.Container#moveDown
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
moveDown: function (child)
|
|
{
|
|
ArrayUtils.MoveDown(this.list, child);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Reverses the order of all Game Objects in this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#reverse
|
|
* @since 3.4.0
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
reverse: function ()
|
|
{
|
|
this.list.reverse();
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Shuffles the all Game Objects in this Container using the Fisher-Yates implementation.
|
|
*
|
|
* @method Phaser.GameObjects.Container#shuffle
|
|
* @since 3.4.0
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
shuffle: function ()
|
|
{
|
|
ArrayUtils.Shuffle(this.list);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Replaces a Game Object in this Container with the new Game Object.
|
|
* The new Game Object cannot already be a child of this Container.
|
|
*
|
|
* @method Phaser.GameObjects.Container#replace
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} oldChild - The Game Object in this Container that will be replaced.
|
|
* @param {Phaser.GameObjects.GameObject} newChild - The Game Object to be added to this Container.
|
|
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
replace: function (oldChild, newChild, destroyChild)
|
|
{
|
|
var moved = ArrayUtils.Replace(this.list, oldChild, newChild);
|
|
|
|
if (moved)
|
|
{
|
|
this.addHandler(newChild);
|
|
this.removeHandler(oldChild);
|
|
|
|
if (destroyChild)
|
|
{
|
|
oldChild.destroy();
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Returns `true` if the given Game Object is a direct child of this Container.
|
|
*
|
|
* This check does not scan nested Containers.
|
|
*
|
|
* @method Phaser.GameObjects.Container#exists
|
|
* @since 3.4.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object to check for within this Container.
|
|
*
|
|
* @return {boolean} True if the Game Object is an immediate child of this Container, otherwise false.
|
|
*/
|
|
exists: function (child)
|
|
{
|
|
return (this.list.indexOf(child) > -1);
|
|
},
|
|
|
|
/**
|
|
* Sets the property to the given value on all Game Objects in this Container.
|
|
*
|
|
* Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
|
|
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
|
|
* the first 50 Game Objects.
|
|
*
|
|
* @method Phaser.GameObjects.Container#setAll
|
|
* @since 3.4.0
|
|
*
|
|
* @param {string} property - The property that must exist on the Game Object.
|
|
* @param {any} value - The value to get the property to.
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=Container.length] - An optional end index to search up to (but not included)
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
setAll: function (property, value, startIndex, endIndex)
|
|
{
|
|
ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* @callback EachContainerCallback
|
|
* @generic I - [item]
|
|
*
|
|
* @param {*} item - The child Game Object of the Container.
|
|
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
|
|
*/
|
|
|
|
/**
|
|
* Passes all Game Objects in this Container to the given callback.
|
|
*
|
|
* A copy of the Container is made before passing each entry to your callback.
|
|
* This protects against the callback itself modifying the Container.
|
|
*
|
|
* If you know for sure that the callback will not change the size of this Container
|
|
* then you can use the more performant `Container.iterate` method instead.
|
|
*
|
|
* @method Phaser.GameObjects.Container#each
|
|
* @since 3.4.0
|
|
*
|
|
* @param {function} callback - The function to call.
|
|
* @param {object} [context] - Value to use as `this` when executing callback.
|
|
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
each: function (callback, context)
|
|
{
|
|
var args = [ null ];
|
|
var i;
|
|
var temp = this.list.slice();
|
|
var len = temp.length;
|
|
|
|
for (i = 2; i < arguments.length; i++)
|
|
{
|
|
args.push(arguments[i]);
|
|
}
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
args[0] = temp[i];
|
|
|
|
callback.apply(context, args);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Passes all Game Objects in this Container to the given callback.
|
|
*
|
|
* Only use this method when you absolutely know that the Container will not be modified during
|
|
* the iteration, i.e. by removing or adding to its contents.
|
|
*
|
|
* @method Phaser.GameObjects.Container#iterate
|
|
* @since 3.4.0
|
|
*
|
|
* @param {function} callback - The function to call.
|
|
* @param {object} [context] - Value to use as `this` when executing callback.
|
|
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
|
|
*
|
|
* @return {this} This Container instance.
|
|
*/
|
|
iterate: function (callback, context)
|
|
{
|
|
var args = [ null ];
|
|
var i;
|
|
|
|
for (i = 2; i < arguments.length; i++)
|
|
{
|
|
args.push(arguments[i]);
|
|
}
|
|
|
|
for (i = 0; i < this.list.length; i++)
|
|
{
|
|
args[0] = this.list[i];
|
|
|
|
callback.apply(context, args);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the scroll factor of this Container and optionally all of its children.
|
|
*
|
|
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
|
|
*
|
|
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
|
|
* It does not change the Game Objects actual position values.
|
|
*
|
|
* A value of 1 means it will move exactly in sync with a camera.
|
|
* A value of 0 means it will not move at all, even if the camera moves.
|
|
* Other values control the degree to which the camera movement is mapped to this Game Object.
|
|
*
|
|
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
|
|
* calculating physics collisions. Bodies always collide based on their world position, but changing
|
|
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
|
|
* them from physics bodies if not accounted for in your code.
|
|
*
|
|
* @method Phaser.GameObjects.Container#setScrollFactor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} x - The horizontal scroll factor of this Game Object.
|
|
* @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
|
|
* @param {boolean} [updateChildren=false] - Apply this scrollFactor to all Container children as well?
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setScrollFactor: function (x, y, updateChildren)
|
|
{
|
|
if (y === undefined) { y = x; }
|
|
if (updateChildren === undefined) { updateChildren = false; }
|
|
|
|
this.scrollFactorX = x;
|
|
this.scrollFactorY = y;
|
|
|
|
if (updateChildren)
|
|
{
|
|
ArrayUtils.SetAll(this.list, 'scrollFactorX', x);
|
|
ArrayUtils.SetAll(this.list, 'scrollFactorY', y);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The number of Game Objects inside this Container.
|
|
*
|
|
* @name Phaser.GameObjects.Container#length
|
|
* @type {integer}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
length: {
|
|
|
|
get: function ()
|
|
{
|
|
return this.list.length;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Returns the first Game Object within the Container, or `null` if it is empty.
|
|
*
|
|
* You can move the cursor by calling `Container.next` and `Container.previous`.
|
|
*
|
|
* @name Phaser.GameObjects.Container#first
|
|
* @type {?Phaser.GameObjects.GameObject}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
first: {
|
|
|
|
get: function ()
|
|
{
|
|
this.position = 0;
|
|
|
|
if (this.list.length > 0)
|
|
{
|
|
return this.list[0];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Returns the last Game Object within the Container, or `null` if it is empty.
|
|
*
|
|
* You can move the cursor by calling `Container.next` and `Container.previous`.
|
|
*
|
|
* @name Phaser.GameObjects.Container#last
|
|
* @type {?Phaser.GameObjects.GameObject}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
last: {
|
|
|
|
get: function ()
|
|
{
|
|
if (this.list.length > 0)
|
|
{
|
|
this.position = this.list.length - 1;
|
|
|
|
return this.list[this.position];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Returns the next Game Object within the Container, or `null` if it is empty.
|
|
*
|
|
* You can move the cursor by calling `Container.next` and `Container.previous`.
|
|
*
|
|
* @name Phaser.GameObjects.Container#next
|
|
* @type {?Phaser.GameObjects.GameObject}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
next: {
|
|
|
|
get: function ()
|
|
{
|
|
if (this.position < this.list.length)
|
|
{
|
|
this.position++;
|
|
|
|
return this.list[this.position];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Returns the previous Game Object within the Container, or `null` if it is empty.
|
|
*
|
|
* You can move the cursor by calling `Container.next` and `Container.previous`.
|
|
*
|
|
* @name Phaser.GameObjects.Container#previous
|
|
* @type {?Phaser.GameObjects.GameObject}
|
|
* @readonly
|
|
* @since 3.4.0
|
|
*/
|
|
previous: {
|
|
|
|
get: function ()
|
|
{
|
|
if (this.position > 0)
|
|
{
|
|
this.position--;
|
|
|
|
return this.list[this.position];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Internal destroy handler, called as part of the destroy process.
|
|
*
|
|
* @method Phaser.GameObjects.Container#preDestroy
|
|
* @protected
|
|
* @since 3.9.0
|
|
*/
|
|
preDestroy: function ()
|
|
{
|
|
this.removeAll(!!this.exclusive);
|
|
|
|
this.localTransform.destroy();
|
|
this.tempTransformMatrix.destroy();
|
|
|
|
this.list = [];
|
|
this._displayList = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Container;
|
|
|
|
|
|
/***/ }),
|
|
/* 253 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Utils.Array
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Matrix: __webpack_require__(254),
|
|
|
|
Add: __webpack_require__(263),
|
|
AddAt: __webpack_require__(264),
|
|
BringToTop: __webpack_require__(265),
|
|
CountAllMatching: __webpack_require__(266),
|
|
Each: __webpack_require__(267),
|
|
EachInRange: __webpack_require__(268),
|
|
FindClosestInSorted: __webpack_require__(269),
|
|
GetAll: __webpack_require__(270),
|
|
GetFirst: __webpack_require__(271),
|
|
GetRandom: __webpack_require__(272),
|
|
MoveDown: __webpack_require__(273),
|
|
MoveTo: __webpack_require__(274),
|
|
MoveUp: __webpack_require__(275),
|
|
NumberArray: __webpack_require__(276),
|
|
NumberArrayStep: __webpack_require__(277),
|
|
QuickSelect: __webpack_require__(278),
|
|
Range: __webpack_require__(279),
|
|
Remove: __webpack_require__(280),
|
|
RemoveAt: __webpack_require__(281),
|
|
RemoveBetween: __webpack_require__(282),
|
|
RemoveRandomElement: __webpack_require__(283),
|
|
Replace: __webpack_require__(284),
|
|
RotateLeft: __webpack_require__(56),
|
|
RotateRight: __webpack_require__(57),
|
|
SafeRange: __webpack_require__(5),
|
|
SendToBack: __webpack_require__(285),
|
|
SetAll: __webpack_require__(286),
|
|
Shuffle: __webpack_require__(58),
|
|
SortByDigits: __webpack_require__(287),
|
|
SpliceOne: __webpack_require__(16),
|
|
StableSort: __webpack_require__(288),
|
|
Swap: __webpack_require__(289)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 254 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Utils.Array.Matrix
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
CheckMatrix: __webpack_require__(24),
|
|
MatrixToString: __webpack_require__(255),
|
|
ReverseColumns: __webpack_require__(257),
|
|
ReverseRows: __webpack_require__(258),
|
|
Rotate180: __webpack_require__(259),
|
|
RotateLeft: __webpack_require__(260),
|
|
RotateMatrix: __webpack_require__(15),
|
|
RotateRight: __webpack_require__(261),
|
|
Translate: __webpack_require__(262),
|
|
TransposeMatrix: __webpack_require__(55)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 255 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Pad = __webpack_require__(256);
|
|
var CheckMatrix = __webpack_require__(24);
|
|
|
|
/**
|
|
* Generates a string (which you can pass to console.log) from the given Array Matrix.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.MatrixToString
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix]
|
|
*
|
|
* @param {T[][]} [matrix] - A 2-dimensional array.
|
|
*
|
|
* @return {string} A string representing the matrix.
|
|
*/
|
|
var MatrixToString = function (matrix)
|
|
{
|
|
var str = '';
|
|
|
|
if (!CheckMatrix(matrix))
|
|
{
|
|
return str;
|
|
}
|
|
|
|
for (var r = 0; r < matrix.length; r++)
|
|
{
|
|
for (var c = 0; c < matrix[r].length; c++)
|
|
{
|
|
var cell = matrix[r][c].toString();
|
|
|
|
if (cell !== 'undefined')
|
|
{
|
|
str += Pad(cell, 2);
|
|
}
|
|
else
|
|
{
|
|
str += '?';
|
|
}
|
|
|
|
if (c < matrix[r].length - 1)
|
|
{
|
|
str += ' |';
|
|
}
|
|
}
|
|
|
|
if (r < matrix.length - 1)
|
|
{
|
|
str += '\n';
|
|
|
|
for (var i = 0; i < matrix[r].length; i++)
|
|
{
|
|
str += '---';
|
|
|
|
if (i < matrix[r].length - 1)
|
|
{
|
|
str += '+';
|
|
}
|
|
}
|
|
|
|
str += '\n';
|
|
}
|
|
|
|
}
|
|
|
|
return str;
|
|
};
|
|
|
|
module.exports = MatrixToString;
|
|
|
|
|
|
/***/ }),
|
|
/* 256 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Takes the given string and pads it out, to the length required, using the character
|
|
* specified. For example if you need a string to be 6 characters long, you can call:
|
|
*
|
|
* `pad('bob', 6, '-', 2)`
|
|
*
|
|
* This would return: `bob---` as it has padded it out to 6 characters, using the `-` on the right.
|
|
*
|
|
* You can also use it to pad numbers (they are always returned as strings):
|
|
*
|
|
* `pad(512, 6, '0', 1)`
|
|
*
|
|
* Would return: `000512` with the string padded to the left.
|
|
*
|
|
* If you don't specify a direction it'll pad to both sides:
|
|
*
|
|
* `pad('c64', 7, '*')`
|
|
*
|
|
* Would return: `**c64**`
|
|
*
|
|
* @function Phaser.Utils.String.Pad
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string|number|object} str - The target string. `toString()` will be called on the string, which means you can also pass in common data types like numbers.
|
|
* @param {integer} [len=0] - The number of characters to be added.
|
|
* @param {string} [pad=" "] - The string to pad it out with (defaults to a space).
|
|
* @param {integer} [dir=3] - The direction dir = 1 (left), 2 (right), 3 (both).
|
|
*
|
|
* @return {string} The padded string.
|
|
*/
|
|
var Pad = function (str, len, pad, dir)
|
|
{
|
|
if (len === undefined) { len = 0; }
|
|
if (pad === undefined) { pad = ' '; }
|
|
if (dir === undefined) { dir = 3; }
|
|
|
|
str = str.toString();
|
|
|
|
var padlen = 0;
|
|
|
|
if (len + 1 >= str.length)
|
|
{
|
|
switch (dir)
|
|
{
|
|
case 1:
|
|
str = new Array(len + 1 - str.length).join(pad) + str;
|
|
break;
|
|
|
|
case 3:
|
|
var right = Math.ceil((padlen = len - str.length) / 2);
|
|
var left = padlen - right;
|
|
str = new Array(left + 1).join(pad) + str + new Array(right + 1).join(pad);
|
|
break;
|
|
|
|
default:
|
|
str = str + new Array(len + 1 - str.length).join(pad);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return str;
|
|
};
|
|
|
|
module.exports = Pad;
|
|
|
|
|
|
/***/ }),
|
|
/* 257 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Reverses the columns in the given Array Matrix.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.ReverseColumns
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array matrix to reverse the columns for.
|
|
*
|
|
* @return {T[][]} The column reversed matrix.
|
|
*/
|
|
var ReverseColumns = function (matrix)
|
|
{
|
|
return matrix.reverse();
|
|
};
|
|
|
|
module.exports = ReverseColumns;
|
|
|
|
|
|
/***/ }),
|
|
/* 258 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Reverses the rows in the given Array Matrix.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.ReverseRows
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array matrix to reverse the rows for.
|
|
*
|
|
* @return {T[][]} The column reversed matrix.
|
|
*/
|
|
var ReverseRows = function (matrix)
|
|
{
|
|
for (var i = 0; i < matrix.length; i++)
|
|
{
|
|
matrix[i].reverse();
|
|
}
|
|
|
|
return matrix;
|
|
};
|
|
|
|
module.exports = ReverseRows;
|
|
|
|
|
|
/***/ }),
|
|
/* 259 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var RotateMatrix = __webpack_require__(15);
|
|
|
|
/**
|
|
* Rotates the array matrix 180 degrees.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.Rotate180
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array to rotate.
|
|
*
|
|
* @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
|
|
*/
|
|
var Rotate180 = function (matrix)
|
|
{
|
|
return RotateMatrix(matrix, 180);
|
|
};
|
|
|
|
module.exports = Rotate180;
|
|
|
|
|
|
/***/ }),
|
|
/* 260 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var RotateMatrix = __webpack_require__(15);
|
|
|
|
/**
|
|
* Rotates the array matrix to the left (or 90 degrees)
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.RotateLeft
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array to rotate.
|
|
*
|
|
* @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
|
|
*/
|
|
var RotateLeft = function (matrix)
|
|
{
|
|
return RotateMatrix(matrix, 90);
|
|
};
|
|
|
|
module.exports = RotateLeft;
|
|
|
|
|
|
/***/ }),
|
|
/* 261 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var RotateMatrix = __webpack_require__(15);
|
|
|
|
/**
|
|
* Rotates the array matrix to the left (or -90 degrees)
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.RotateRight
|
|
* @since 3.0.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array to rotate.
|
|
*
|
|
* @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
|
|
*/
|
|
var RotateRight = function (matrix)
|
|
{
|
|
return RotateMatrix(matrix, -90);
|
|
};
|
|
|
|
module.exports = RotateRight;
|
|
|
|
|
|
/***/ }),
|
|
/* 262 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var RotateLeft = __webpack_require__(56);
|
|
var RotateRight = __webpack_require__(57);
|
|
|
|
/**
|
|
* Translates the given Array Matrix by shifting each column and row the
|
|
* amount specified.
|
|
*
|
|
* A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
|
|
* have the same length. There must be at least two rows. This is an example matrix:
|
|
*
|
|
* ```
|
|
* [
|
|
* [ 1, 1, 1, 1, 1, 1 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 2, 0, 1, 2, 0, 4 ],
|
|
* [ 2, 0, 3, 4, 0, 4 ],
|
|
* [ 2, 0, 0, 0, 0, 4 ],
|
|
* [ 3, 3, 3, 3, 3, 3 ]
|
|
* ]
|
|
* ```
|
|
*
|
|
* @function Phaser.Utils.Array.Matrix.Translate
|
|
* @since 3.50.0
|
|
*
|
|
* @generic T
|
|
* @genericUse {T[][]} - [matrix,$return]
|
|
*
|
|
* @param {T[][]} [matrix] - The array matrix to translate.
|
|
* @param {number} [x=0] - The amount to horizontally translate the matrix by.
|
|
* @param {number} [y=0] - The amount to vertically translate the matrix by.
|
|
*
|
|
* @return {T[][]} The translated matrix.
|
|
*/
|
|
var TranslateMatrix = function (matrix, x, y)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = 0; }
|
|
|
|
// Vertical translation
|
|
|
|
if (y !== 0)
|
|
{
|
|
if (y < 0)
|
|
{
|
|
// Shift Up
|
|
RotateLeft(matrix, Math.abs(y));
|
|
}
|
|
else
|
|
{
|
|
// Shift Down
|
|
RotateRight(matrix, y);
|
|
}
|
|
}
|
|
|
|
// Horizontal translation
|
|
|
|
if (x !== 0)
|
|
{
|
|
for (var i = 0; i < matrix.length; i++)
|
|
{
|
|
var row = matrix[i];
|
|
|
|
if (x < 0)
|
|
{
|
|
RotateLeft(row, Math.abs(x));
|
|
}
|
|
else
|
|
{
|
|
RotateRight(row, x);
|
|
}
|
|
}
|
|
}
|
|
|
|
return matrix;
|
|
};
|
|
|
|
module.exports = TranslateMatrix;
|
|
|
|
|
|
/***/ }),
|
|
/* 263 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Adds the given item, or array of items, to the array.
|
|
*
|
|
* Each item must be unique within the array.
|
|
*
|
|
* The array is modified in-place and returned.
|
|
*
|
|
* You can optionally specify a limit to the maximum size of the array. If the quantity of items being
|
|
* added will take the array length over this limit, it will stop adding once the limit is reached.
|
|
*
|
|
* You can optionally specify a callback to be invoked for each item successfully added to the array.
|
|
*
|
|
* @function Phaser.Utils.Array.Add
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to be added to.
|
|
* @param {any|any[]} item - The item, or array of items, to add to the array. Each item must be unique within the array.
|
|
* @param {integer} [limit] - Optional limit which caps the size of the array.
|
|
* @param {function} [callback] - A callback to be invoked for each item successfully added to the array.
|
|
* @param {object} [context] - The context in which the callback is invoked.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var Add = function (array, item, limit, callback, context)
|
|
{
|
|
if (context === undefined) { context = array; }
|
|
|
|
if (limit > 0)
|
|
{
|
|
var remaining = limit - array.length;
|
|
|
|
// There's nothing more we can do here, the array is full
|
|
if (remaining <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Fast path to avoid array mutation and iteration
|
|
if (!Array.isArray(item))
|
|
{
|
|
if (array.indexOf(item) === -1)
|
|
{
|
|
array.push(item);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, item);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// If we got this far, we have an array of items to insert
|
|
|
|
// Ensure all the items are unique
|
|
var itemLength = item.length - 1;
|
|
|
|
while (itemLength >= 0)
|
|
{
|
|
if (array.indexOf(item[itemLength]) !== -1)
|
|
{
|
|
// Already exists in array, so remove it
|
|
item.splice(itemLength, 1);
|
|
}
|
|
|
|
itemLength--;
|
|
}
|
|
|
|
// Anything left?
|
|
itemLength = item.length;
|
|
|
|
if (itemLength === 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (limit > 0 && itemLength > remaining)
|
|
{
|
|
item.splice(remaining);
|
|
|
|
itemLength = remaining;
|
|
}
|
|
|
|
for (var i = 0; i < itemLength; i++)
|
|
{
|
|
var entry = item[i];
|
|
|
|
array.push(entry);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, entry);
|
|
}
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = Add;
|
|
|
|
|
|
/***/ }),
|
|
/* 264 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Adds the given item, or array of items, to the array starting at the index specified.
|
|
*
|
|
* Each item must be unique within the array.
|
|
*
|
|
* Existing elements in the array are shifted up.
|
|
*
|
|
* The array is modified in-place and returned.
|
|
*
|
|
* You can optionally specify a limit to the maximum size of the array. If the quantity of items being
|
|
* added will take the array length over this limit, it will stop adding once the limit is reached.
|
|
*
|
|
* You can optionally specify a callback to be invoked for each item successfully added to the array.
|
|
*
|
|
* @function Phaser.Utils.Array.AddAt
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to be added to.
|
|
* @param {any|any[]} item - The item, or array of items, to add to the array.
|
|
* @param {integer} [index=0] - The index in the array where the item will be inserted.
|
|
* @param {integer} [limit] - Optional limit which caps the size of the array.
|
|
* @param {function} [callback] - A callback to be invoked for each item successfully added to the array.
|
|
* @param {object} [context] - The context in which the callback is invoked.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var AddAt = function (array, item, index, limit, callback, context)
|
|
{
|
|
if (index === undefined) { index = 0; }
|
|
if (context === undefined) { context = array; }
|
|
|
|
if (limit > 0)
|
|
{
|
|
var remaining = limit - array.length;
|
|
|
|
// There's nothing more we can do here, the array is full
|
|
if (remaining <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Fast path to avoid array mutation and iteration
|
|
if (!Array.isArray(item))
|
|
{
|
|
if (array.indexOf(item) === -1)
|
|
{
|
|
array.splice(index, 0, item);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, item);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// If we got this far, we have an array of items to insert
|
|
|
|
// Ensure all the items are unique
|
|
var itemLength = item.length - 1;
|
|
|
|
while (itemLength >= 0)
|
|
{
|
|
if (array.indexOf(item[itemLength]) !== -1)
|
|
{
|
|
// Already exists in array, so remove it
|
|
item.pop();
|
|
}
|
|
|
|
itemLength--;
|
|
}
|
|
|
|
// Anything left?
|
|
itemLength = item.length;
|
|
|
|
if (itemLength === 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// Truncate to the limit
|
|
if (limit > 0 && itemLength > remaining)
|
|
{
|
|
item.splice(remaining);
|
|
|
|
itemLength = remaining;
|
|
}
|
|
|
|
for (var i = itemLength - 1; i >= 0; i--)
|
|
{
|
|
var entry = item[i];
|
|
|
|
array.splice(index, 0, entry);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, entry);
|
|
}
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = AddAt;
|
|
|
|
|
|
/***/ }),
|
|
/* 265 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the given element to the top of the array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.BringToTop
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array.
|
|
* @param {*} item - The element to move.
|
|
*
|
|
* @return {*} The element that was moved.
|
|
*/
|
|
var BringToTop = function (array, item)
|
|
{
|
|
var currentIndex = array.indexOf(item);
|
|
|
|
if (currentIndex !== -1 && currentIndex < array.length)
|
|
{
|
|
array.splice(currentIndex, 1);
|
|
array.push(item);
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = BringToTop;
|
|
|
|
|
|
/***/ }),
|
|
/* 266 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Returns the total number of elements in the array which have a property matching the given value.
|
|
*
|
|
* @function Phaser.Utils.Array.CountAllMatching
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {string} property - The property to test on each array element.
|
|
* @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check.
|
|
* @param {integer} [startIndex] - An optional start index to search from.
|
|
* @param {integer} [endIndex] - An optional end index to search to.
|
|
*
|
|
* @return {integer} The total number of elements with properties matching the given value.
|
|
*/
|
|
var CountAllMatching = function (array, property, value, startIndex, endIndex)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
|
|
var total = 0;
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
for (var i = startIndex; i < endIndex; i++)
|
|
{
|
|
var child = array[i];
|
|
|
|
if (child[property] === value)
|
|
{
|
|
total++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return total;
|
|
};
|
|
|
|
module.exports = CountAllMatching;
|
|
|
|
|
|
/***/ }),
|
|
/* 267 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Passes each element in the array to the given callback.
|
|
*
|
|
* @function Phaser.Utils.Array.Each
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {function} callback - A callback to be invoked for each item in the array.
|
|
* @param {object} context - The context in which the callback is invoked.
|
|
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the current array item.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var Each = function (array, callback, context)
|
|
{
|
|
var i;
|
|
var args = [ null ];
|
|
|
|
for (i = 3; i < arguments.length; i++)
|
|
{
|
|
args.push(arguments[i]);
|
|
}
|
|
|
|
for (i = 0; i < array.length; i++)
|
|
{
|
|
args[0] = array[i];
|
|
|
|
callback.apply(context, args);
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = Each;
|
|
|
|
|
|
/***/ }),
|
|
/* 268 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Passes each element in the array, between the start and end indexes, to the given callback.
|
|
*
|
|
* @function Phaser.Utils.Array.EachInRange
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {function} callback - A callback to be invoked for each item in the array.
|
|
* @param {object} context - The context in which the callback is invoked.
|
|
* @param {integer} startIndex - The start index to search from.
|
|
* @param {integer} endIndex - The end index to search to.
|
|
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var EachInRange = function (array, callback, context, startIndex, endIndex)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
var i;
|
|
var args = [ null ];
|
|
|
|
for (i = 5; i < arguments.length; i++)
|
|
{
|
|
args.push(arguments[i]);
|
|
}
|
|
|
|
for (i = startIndex; i < endIndex; i++)
|
|
{
|
|
args[0] = array[i];
|
|
|
|
callback.apply(context, args);
|
|
}
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = EachInRange;
|
|
|
|
|
|
/***/ }),
|
|
/* 269 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Searches a pre-sorted array for the closet value to the given number.
|
|
*
|
|
* If the `key` argument is given it will assume the array contains objects that all have the required `key` property name,
|
|
* and will check for the closest value of those to the given number.
|
|
*
|
|
* @function Phaser.Utils.Array.FindClosestInSorted
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} value - The value to search for in the array.
|
|
* @param {array} array - The array to search, which must be sorted.
|
|
* @param {string} [key] - An optional property key. If specified the array elements property will be checked against value.
|
|
*
|
|
* @return {(number|any)} The nearest value found in the array, or if a `key` was given, the nearest object with the matching property value.
|
|
*/
|
|
var FindClosestInSorted = function (value, array, key)
|
|
{
|
|
if (!array.length)
|
|
{
|
|
return NaN;
|
|
}
|
|
else if (array.length === 1)
|
|
{
|
|
return array[0];
|
|
}
|
|
|
|
var i = 1;
|
|
var low;
|
|
var high;
|
|
|
|
if (key)
|
|
{
|
|
if (value < array[0][key])
|
|
{
|
|
return array[0];
|
|
}
|
|
|
|
while (array[i][key] < value)
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (array[i] < value)
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
|
|
if (i > array.length)
|
|
{
|
|
i = array.length;
|
|
}
|
|
|
|
if (key)
|
|
{
|
|
low = array[i - 1][key];
|
|
high = array[i][key];
|
|
|
|
return ((high - value) <= (value - low)) ? array[i] : array[i - 1];
|
|
}
|
|
else
|
|
{
|
|
low = array[i - 1];
|
|
high = array[i];
|
|
|
|
return ((high - value) <= (value - low)) ? high : low;
|
|
}
|
|
};
|
|
|
|
module.exports = FindClosestInSorted;
|
|
|
|
|
|
/***/ }),
|
|
/* 270 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Returns all elements in the array.
|
|
*
|
|
* You can optionally specify a matching criteria using the `property` and `value` arguments.
|
|
*
|
|
* For example: `getAll('visible', true)` would return only elements that have their visible property set.
|
|
*
|
|
* Optionally you can specify a start and end index. For example if the array had 100 elements,
|
|
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
|
|
* the first 50 elements.
|
|
*
|
|
* @function Phaser.Utils.Array.GetAll
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {string} [property] - The property to test on each array element.
|
|
* @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check.
|
|
* @param {integer} [startIndex] - An optional start index to search from.
|
|
* @param {integer} [endIndex] - An optional end index to search to.
|
|
*
|
|
* @return {array} All matching elements from the array.
|
|
*/
|
|
var GetAll = function (array, property, value, startIndex, endIndex)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
|
|
var output = [];
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
for (var i = startIndex; i < endIndex; i++)
|
|
{
|
|
var child = array[i];
|
|
|
|
if (!property ||
|
|
(property && value === undefined && child.hasOwnProperty(property)) ||
|
|
(property && value !== undefined && child[property] === value))
|
|
{
|
|
output.push(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
|
|
module.exports = GetAll;
|
|
|
|
|
|
/***/ }),
|
|
/* 271 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Returns the first element in the array.
|
|
*
|
|
* You can optionally specify a matching criteria using the `property` and `value` arguments.
|
|
*
|
|
* For example: `getAll('visible', true)` would return the first element that had its `visible` property set.
|
|
*
|
|
* Optionally you can specify a start and end index. For example if the array had 100 elements,
|
|
* and you set `startIndex` to 0 and `endIndex` to 50, it would search only the first 50 elements.
|
|
*
|
|
* @function Phaser.Utils.Array.GetFirst
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {string} [property] - The property to test on each array element.
|
|
* @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check.
|
|
* @param {integer} [startIndex=0] - An optional start index to search from.
|
|
* @param {integer} [endIndex=array.length] - An optional end index to search up to (but not included)
|
|
*
|
|
* @return {object} The first matching element from the array, or `null` if no element could be found in the range given.
|
|
*/
|
|
var GetFirst = function (array, property, value, startIndex, endIndex)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
for (var i = startIndex; i < endIndex; i++)
|
|
{
|
|
var child = array[i];
|
|
|
|
if (!property ||
|
|
(property && value === undefined && child.hasOwnProperty(property)) ||
|
|
(property && value !== undefined && child[property] === value))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
module.exports = GetFirst;
|
|
|
|
|
|
/***/ }),
|
|
/* 272 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Returns a Random element from the array.
|
|
*
|
|
* @function Phaser.Utils.Array.GetRandom
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The array to select the random entry from.
|
|
* @param {integer} [startIndex=0] - An optional start index.
|
|
* @param {integer} [length=array.length] - An optional length, the total number of elements (from the startIndex) to choose from.
|
|
*
|
|
* @return {*} A random element from the array, or `null` if no element could be found in the range given.
|
|
*/
|
|
var GetRandom = function (array, startIndex, length)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (length === undefined) { length = array.length; }
|
|
|
|
var randomIndex = startIndex + Math.floor(Math.random() * length);
|
|
|
|
return (array[randomIndex] === undefined) ? null : array[randomIndex];
|
|
};
|
|
|
|
module.exports = GetRandom;
|
|
|
|
|
|
/***/ }),
|
|
/* 273 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the given array element down one place in the array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.MoveDown
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The input array.
|
|
* @param {*} item - The element to move down the array.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var MoveDown = function (array, item)
|
|
{
|
|
var currentIndex = array.indexOf(item);
|
|
|
|
if (currentIndex > 0)
|
|
{
|
|
var item2 = array[currentIndex - 1];
|
|
|
|
var index2 = array.indexOf(item2);
|
|
|
|
array[currentIndex] = item2;
|
|
array[index2] = item;
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = MoveDown;
|
|
|
|
|
|
/***/ }),
|
|
/* 274 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves an element in an array to a new position within the same array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.MoveTo
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array.
|
|
* @param {*} item - The element to move.
|
|
* @param {integer} index - The new index that the element will be moved to.
|
|
*
|
|
* @return {*} The element that was moved.
|
|
*/
|
|
var MoveTo = function (array, item, index)
|
|
{
|
|
var currentIndex = array.indexOf(item);
|
|
|
|
if (currentIndex === -1 || index < 0 || index >= array.length)
|
|
{
|
|
throw new Error('Supplied index out of bounds');
|
|
}
|
|
|
|
if (currentIndex !== index)
|
|
{
|
|
// Remove
|
|
array.splice(currentIndex, 1);
|
|
|
|
// Add in new location
|
|
array.splice(index, 0, item);
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = MoveTo;
|
|
|
|
|
|
/***/ }),
|
|
/* 275 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the given array element up one place in the array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.MoveUp
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The input array.
|
|
* @param {*} item - The element to move up the array.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var MoveUp = function (array, item)
|
|
{
|
|
var currentIndex = array.indexOf(item);
|
|
|
|
if (currentIndex !== -1 && currentIndex < array.length - 1)
|
|
{
|
|
// The element one above `item` in the array
|
|
var item2 = array[currentIndex + 1];
|
|
var index2 = array.indexOf(item2);
|
|
|
|
array[currentIndex] = item2;
|
|
array[index2] = item;
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = MoveUp;
|
|
|
|
|
|
/***/ }),
|
|
/* 276 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Create an array representing the range of numbers (usually integers), between, and inclusive of,
|
|
* the given `start` and `end` arguments. For example:
|
|
*
|
|
* `var array = Phaser.Utils.Array.NumberArray(2, 4); // array = [2, 3, 4]`
|
|
* `var array = Phaser.Utils.Array.NumberArray(0, 9); // array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`
|
|
* `var array = Phaser.Utils.Array.NumberArray(8, 2); // array = [8, 7, 6, 5, 4, 3, 2]`
|
|
*
|
|
* This is equivalent to `Phaser.Utils.Array.NumberArrayStep(start, end, 1)`.
|
|
*
|
|
* You can optionally provide a prefix and / or suffix string. If given the array will contain
|
|
* strings, not integers. For example:
|
|
*
|
|
* `var array = Phaser.Utils.Array.NumberArray(1, 4, 'Level '); // array = ["Level 1", "Level 2", "Level 3", "Level 4"]`
|
|
* `var array = Phaser.Utils.Array.NumberArray(5, 7, 'HD-', '.png'); // array = ["HD-5.png", "HD-6.png", "HD-7.png"]`
|
|
*
|
|
* @function Phaser.Utils.Array.NumberArray
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} start - The minimum value the array starts with.
|
|
* @param {number} end - The maximum value the array contains.
|
|
* @param {string} [prefix] - Optional prefix to place before the number. If provided the array will contain strings, not integers.
|
|
* @param {string} [suffix] - Optional suffix to place after the number. If provided the array will contain strings, not integers.
|
|
*
|
|
* @return {(number[]|string[])} The array of number values, or strings if a prefix or suffix was provided.
|
|
*/
|
|
var NumberArray = function (start, end, prefix, suffix)
|
|
{
|
|
var result = [];
|
|
|
|
var i;
|
|
var asString = false;
|
|
|
|
if (prefix || suffix)
|
|
{
|
|
asString = true;
|
|
|
|
if (!prefix)
|
|
{
|
|
prefix = '';
|
|
}
|
|
|
|
if (!suffix)
|
|
{
|
|
suffix = '';
|
|
}
|
|
}
|
|
|
|
if (end < start)
|
|
{
|
|
for (i = start; i >= end; i--)
|
|
{
|
|
if (asString)
|
|
{
|
|
result.push(prefix + i.toString() + suffix);
|
|
}
|
|
else
|
|
{
|
|
result.push(i);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = start; i <= end; i++)
|
|
{
|
|
if (asString)
|
|
{
|
|
result.push(prefix + i.toString() + suffix);
|
|
}
|
|
else
|
|
{
|
|
result.push(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
module.exports = NumberArray;
|
|
|
|
|
|
/***/ }),
|
|
/* 277 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var RoundAwayFromZero = __webpack_require__(40);
|
|
|
|
/**
|
|
* Create an array of numbers (positive and/or negative) progressing from `start`
|
|
* up to but not including `end` by advancing by `step`.
|
|
*
|
|
* If `start` is less than `end` a zero-length range is created unless a negative `step` is specified.
|
|
*
|
|
* Certain values for `start` and `end` (eg. NaN/undefined/null) are currently coerced to 0;
|
|
* for forward compatibility make sure to pass in actual numbers.
|
|
*
|
|
* @example
|
|
* NumberArrayStep(4);
|
|
* // => [0, 1, 2, 3]
|
|
*
|
|
* NumberArrayStep(1, 5);
|
|
* // => [1, 2, 3, 4]
|
|
*
|
|
* NumberArrayStep(0, 20, 5);
|
|
* // => [0, 5, 10, 15]
|
|
*
|
|
* NumberArrayStep(0, -4, -1);
|
|
* // => [0, -1, -2, -3]
|
|
*
|
|
* NumberArrayStep(1, 4, 0);
|
|
* // => [1, 1, 1]
|
|
*
|
|
* NumberArrayStep(0);
|
|
* // => []
|
|
*
|
|
* @function Phaser.Utils.Array.NumberArrayStep
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [start=0] - The start of the range.
|
|
* @param {number} [end=null] - The end of the range.
|
|
* @param {number} [step=1] - The value to increment or decrement by.
|
|
*
|
|
* @return {number[]} The array of number values.
|
|
*/
|
|
var NumberArrayStep = function (start, end, step)
|
|
{
|
|
if (start === undefined) { start = 0; }
|
|
if (end === undefined) { end = null; }
|
|
if (step === undefined) { step = 1; }
|
|
|
|
if (end === null)
|
|
{
|
|
end = start;
|
|
start = 0;
|
|
}
|
|
|
|
var result = [];
|
|
|
|
var total = Math.max(RoundAwayFromZero((end - start) / (step || 1)), 0);
|
|
|
|
for (var i = 0; i < total; i++)
|
|
{
|
|
result.push(start);
|
|
start += step;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
module.exports = NumberArrayStep;
|
|
|
|
|
|
/***/ }),
|
|
/* 278 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function swap (arr, i, j)
|
|
{
|
|
var tmp = arr[i];
|
|
arr[i] = arr[j];
|
|
arr[j] = tmp;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
function defaultCompare (a, b)
|
|
{
|
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* A [Floyd-Rivest](https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm) quick selection algorithm.
|
|
*
|
|
* Rearranges the array items so that all items in the [left, k] range are smaller than all items in [k, right];
|
|
* The k-th element will have the (k - left + 1)th smallest value in [left, right].
|
|
*
|
|
* The array is modified in-place.
|
|
*
|
|
* Based on code by [Vladimir Agafonkin](https://www.npmjs.com/~mourner)
|
|
*
|
|
* @function Phaser.Utils.Array.QuickSelect
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} arr - The array to sort.
|
|
* @param {integer} k - The k-th element index.
|
|
* @param {integer} [left=0] - The index of the left part of the range.
|
|
* @param {integer} [right] - The index of the right part of the range.
|
|
* @param {function} [compare] - An optional comparison function. Is passed two elements and should return 0, 1 or -1.
|
|
*/
|
|
var QuickSelect = function (arr, k, left, right, compare)
|
|
{
|
|
if (left === undefined) { left = 0; }
|
|
if (right === undefined) { right = arr.length - 1; }
|
|
if (compare === undefined) { compare = defaultCompare; }
|
|
|
|
while (right > left)
|
|
{
|
|
if (right - left > 600)
|
|
{
|
|
var n = right - left + 1;
|
|
var m = k - left + 1;
|
|
var z = Math.log(n);
|
|
var s = 0.5 * Math.exp(2 * z / 3);
|
|
var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
|
|
var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
|
|
var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
|
|
|
|
QuickSelect(arr, k, newLeft, newRight, compare);
|
|
}
|
|
|
|
var t = arr[k];
|
|
var i = left;
|
|
var j = right;
|
|
|
|
swap(arr, left, k);
|
|
|
|
if (compare(arr[right], t) > 0)
|
|
{
|
|
swap(arr, left, right);
|
|
}
|
|
|
|
while (i < j)
|
|
{
|
|
swap(arr, i, j);
|
|
|
|
i++;
|
|
j--;
|
|
|
|
while (compare(arr[i], t) < 0)
|
|
{
|
|
i++;
|
|
}
|
|
|
|
while (compare(arr[j], t) > 0)
|
|
{
|
|
j--;
|
|
}
|
|
}
|
|
|
|
if (compare(arr[left], t) === 0)
|
|
{
|
|
swap(arr, left, j);
|
|
}
|
|
else
|
|
{
|
|
j++;
|
|
swap(arr, j, right);
|
|
}
|
|
|
|
if (j <= k)
|
|
{
|
|
left = j + 1;
|
|
}
|
|
|
|
if (k <= j)
|
|
{
|
|
right = j - 1;
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = QuickSelect;
|
|
|
|
|
|
/***/ }),
|
|
/* 279 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var GetValue = __webpack_require__(10);
|
|
var Shuffle = __webpack_require__(58);
|
|
|
|
var BuildChunk = function (a, b, qty)
|
|
{
|
|
var out = [];
|
|
|
|
for (var aIndex = 0; aIndex < a.length; aIndex++)
|
|
{
|
|
for (var bIndex = 0; bIndex < b.length; bIndex++)
|
|
{
|
|
for (var i = 0; i < qty; i++)
|
|
{
|
|
out.push({ a: a[aIndex], b: b[bIndex] });
|
|
}
|
|
}
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
/**
|
|
* Creates an array populated with a range of values, based on the given arguments and configuration object.
|
|
*
|
|
* Range ([a,b,c], [1,2,3]) =
|
|
* a1, a2, a3, b1, b2, b3, c1, c2, c3
|
|
*
|
|
* Range ([a,b], [1,2,3], qty = 3) =
|
|
* a1, a1, a1, a2, a2, a2, a3, a3, a3, b1, b1, b1, b2, b2, b2, b3, b3, b3
|
|
*
|
|
* Range ([a,b,c], [1,2,3], repeat x1) =
|
|
* a1, a2, a3, b1, b2, b3, c1, c2, c3, a1, a2, a3, b1, b2, b3, c1, c2, c3
|
|
*
|
|
* Range ([a,b], [1,2], repeat -1 = endless, max = 14) =
|
|
* Maybe if max is set then repeat goes to -1 automatically?
|
|
* a1, a2, b1, b2, a1, a2, b1, b2, a1, a2, b1, b2, a1, a2 (capped at 14 elements)
|
|
*
|
|
* Range ([a], [1,2,3,4,5], random = true) =
|
|
* a4, a1, a5, a2, a3
|
|
*
|
|
* Range ([a, b], [1,2,3], random = true) =
|
|
* b3, a2, a1, b1, a3, b2
|
|
*
|
|
* Range ([a, b, c], [1,2,3], randomB = true) =
|
|
* a3, a1, a2, b2, b3, b1, c1, c3, c2
|
|
*
|
|
* Range ([a], [1,2,3,4,5], yoyo = true) =
|
|
* a1, a2, a3, a4, a5, a5, a4, a3, a2, a1
|
|
*
|
|
* Range ([a, b], [1,2,3], yoyo = true) =
|
|
* a1, a2, a3, b1, b2, b3, b3, b2, b1, a3, a2, a1
|
|
*
|
|
* @function Phaser.Utils.Array.Range
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} a - The first array of range elements.
|
|
* @param {array} b - The second array of range elements.
|
|
* @param {object} [options] - A range configuration object. Can contain: repeat, random, randomB, yoyo, max, qty.
|
|
*
|
|
* @return {array} An array of arranged elements.
|
|
*/
|
|
var Range = function (a, b, options)
|
|
{
|
|
var max = GetValue(options, 'max', 0);
|
|
var qty = GetValue(options, 'qty', 1);
|
|
var random = GetValue(options, 'random', false);
|
|
var randomB = GetValue(options, 'randomB', false);
|
|
var repeat = GetValue(options, 'repeat', 0);
|
|
var yoyo = GetValue(options, 'yoyo', false);
|
|
|
|
var out = [];
|
|
|
|
if (randomB)
|
|
{
|
|
Shuffle(b);
|
|
}
|
|
|
|
// Endless repeat, so limit by max
|
|
if (repeat === -1)
|
|
{
|
|
if (max === 0)
|
|
{
|
|
repeat = 0;
|
|
}
|
|
else
|
|
{
|
|
// Work out how many repeats we need
|
|
var total = (a.length * b.length) * qty;
|
|
|
|
if (yoyo)
|
|
{
|
|
total *= 2;
|
|
}
|
|
|
|
repeat = Math.ceil(max / total);
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i <= repeat; i++)
|
|
{
|
|
var chunk = BuildChunk(a, b, qty);
|
|
|
|
if (random)
|
|
{
|
|
Shuffle(chunk);
|
|
}
|
|
|
|
out = out.concat(chunk);
|
|
|
|
if (yoyo)
|
|
{
|
|
chunk.reverse();
|
|
|
|
out = out.concat(chunk);
|
|
}
|
|
}
|
|
|
|
if (max)
|
|
{
|
|
out.splice(max);
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = Range;
|
|
|
|
|
|
/***/ }),
|
|
/* 280 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SpliceOne = __webpack_require__(16);
|
|
|
|
/**
|
|
* Removes the given item, or array of items, from the array.
|
|
*
|
|
* The array is modified in-place.
|
|
*
|
|
* You can optionally specify a callback to be invoked for each item successfully removed from the array.
|
|
*
|
|
* @function Phaser.Utils.Array.Remove
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to be modified.
|
|
* @param {*|Array.<*>} item - The item, or array of items, to be removed from the array.
|
|
* @param {function} [callback] - A callback to be invoked for each item successfully removed from the array.
|
|
* @param {object} [context] - The context in which the callback is invoked.
|
|
*
|
|
* @return {*|Array.<*>} The item, or array of items, that were successfully removed from the array.
|
|
*/
|
|
var Remove = function (array, item, callback, context)
|
|
{
|
|
if (context === undefined) { context = array; }
|
|
|
|
var index;
|
|
|
|
// Fast path to avoid array mutation and iteration
|
|
if (!Array.isArray(item))
|
|
{
|
|
index = array.indexOf(item);
|
|
|
|
if (index !== -1)
|
|
{
|
|
SpliceOne(array, index);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, item);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// If we got this far, we have an array of items to remove
|
|
|
|
var itemLength = item.length - 1;
|
|
|
|
while (itemLength >= 0)
|
|
{
|
|
var entry = item[itemLength];
|
|
|
|
index = array.indexOf(entry);
|
|
|
|
if (index !== -1)
|
|
{
|
|
SpliceOne(array, index);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, entry);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Item wasn't found in the array, so remove it from our return results
|
|
item.pop();
|
|
}
|
|
|
|
itemLength--;
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = Remove;
|
|
|
|
|
|
/***/ }),
|
|
/* 281 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SpliceOne = __webpack_require__(16);
|
|
|
|
/**
|
|
* Removes the item from the given position in the array.
|
|
*
|
|
* The array is modified in-place.
|
|
*
|
|
* You can optionally specify a callback to be invoked for the item if it is successfully removed from the array.
|
|
*
|
|
* @function Phaser.Utils.Array.RemoveAt
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to be modified.
|
|
* @param {integer} index - The array index to remove the item from. The index must be in bounds or it will throw an error.
|
|
* @param {function} [callback] - A callback to be invoked for the item removed from the array.
|
|
* @param {object} [context] - The context in which the callback is invoked.
|
|
*
|
|
* @return {*} The item that was removed.
|
|
*/
|
|
var RemoveAt = function (array, index, callback, context)
|
|
{
|
|
if (context === undefined) { context = array; }
|
|
|
|
if (index < 0 || index > array.length - 1)
|
|
{
|
|
throw new Error('Index out of bounds');
|
|
}
|
|
|
|
var item = SpliceOne(array, index);
|
|
|
|
if (callback)
|
|
{
|
|
callback.call(context, item);
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = RemoveAt;
|
|
|
|
|
|
/***/ }),
|
|
/* 282 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Removes the item within the given range in the array.
|
|
*
|
|
* The array is modified in-place.
|
|
*
|
|
* You can optionally specify a callback to be invoked for the item/s successfully removed from the array.
|
|
*
|
|
* @function Phaser.Utils.Array.RemoveBetween
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to be modified.
|
|
* @param {integer} startIndex - The start index to remove from.
|
|
* @param {integer} endIndex - The end index to remove to.
|
|
* @param {function} [callback] - A callback to be invoked for the item removed from the array.
|
|
* @param {object} [context] - The context in which the callback is invoked.
|
|
*
|
|
* @return {Array.<*>} An array of items that were removed.
|
|
*/
|
|
var RemoveBetween = function (array, startIndex, endIndex, callback, context)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
if (context === undefined) { context = array; }
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
var size = endIndex - startIndex;
|
|
|
|
var removed = array.splice(startIndex, size);
|
|
|
|
if (callback)
|
|
{
|
|
for (var i = 0; i < removed.length; i++)
|
|
{
|
|
var entry = removed[i];
|
|
|
|
callback.call(context, entry);
|
|
}
|
|
}
|
|
|
|
return removed;
|
|
}
|
|
else
|
|
{
|
|
return [];
|
|
}
|
|
};
|
|
|
|
module.exports = RemoveBetween;
|
|
|
|
|
|
/***/ }),
|
|
/* 283 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SpliceOne = __webpack_require__(16);
|
|
|
|
/**
|
|
* Removes a random object from the given array and returns it.
|
|
* Will return null if there are no array items that fall within the specified range or if there is no item for the randomly chosen index.
|
|
*
|
|
* @function Phaser.Utils.Array.RemoveRandomElement
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The array to removed a random element from.
|
|
* @param {integer} [start=0] - The array index to start the search from.
|
|
* @param {integer} [length=array.length] - Optional restriction on the number of elements to randomly select from.
|
|
*
|
|
* @return {object} The random element that was removed, or `null` if there were no array elements that fell within the given range.
|
|
*/
|
|
var RemoveRandomElement = function (array, start, length)
|
|
{
|
|
if (start === undefined) { start = 0; }
|
|
if (length === undefined) { length = array.length; }
|
|
|
|
var randomIndex = start + Math.floor(Math.random() * length);
|
|
|
|
return SpliceOne(array, randomIndex);
|
|
};
|
|
|
|
module.exports = RemoveRandomElement;
|
|
|
|
|
|
/***/ }),
|
|
/* 284 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Replaces an element of the array with the new element.
|
|
* The new element cannot already be a member of the array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.Replace
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search within.
|
|
* @param {*} oldChild - The element in the array that will be replaced.
|
|
* @param {*} newChild - The element to be inserted into the array at the position of `oldChild`.
|
|
*
|
|
* @return {boolean} Returns true if the oldChild was successfully replaced, otherwise returns false.
|
|
*/
|
|
var Replace = function (array, oldChild, newChild)
|
|
{
|
|
var index1 = array.indexOf(oldChild);
|
|
var index2 = array.indexOf(newChild);
|
|
|
|
if (index1 !== -1 && index2 === -1)
|
|
{
|
|
array[index1] = newChild;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
};
|
|
|
|
module.exports = Replace;
|
|
|
|
|
|
/***/ }),
|
|
/* 285 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Moves the given element to the bottom of the array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.SendToBack
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array.
|
|
* @param {*} item - The element to move.
|
|
*
|
|
* @return {*} The element that was moved.
|
|
*/
|
|
var SendToBack = function (array, item)
|
|
{
|
|
var currentIndex = array.indexOf(item);
|
|
|
|
if (currentIndex !== -1 && currentIndex > 0)
|
|
{
|
|
array.splice(currentIndex, 1);
|
|
array.unshift(item);
|
|
}
|
|
|
|
return item;
|
|
};
|
|
|
|
module.exports = SendToBack;
|
|
|
|
|
|
/***/ }),
|
|
/* 286 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var SafeRange = __webpack_require__(5);
|
|
|
|
/**
|
|
* Scans the array for elements with the given property. If found, the property is set to the `value`.
|
|
*
|
|
* For example: `SetAll('visible', true)` would set all elements that have a `visible` property to `false`.
|
|
*
|
|
* Optionally you can specify a start and end index. For example if the array had 100 elements,
|
|
* and you set `startIndex` to 0 and `endIndex` to 50, it would update only the first 50 elements.
|
|
*
|
|
* @function Phaser.Utils.Array.SetAll
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The array to search.
|
|
* @param {string} property - The property to test for on each array element.
|
|
* @param {*} value - The value to set the property to.
|
|
* @param {integer} [startIndex] - An optional start index to search from.
|
|
* @param {integer} [endIndex] - An optional end index to search to.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var SetAll = function (array, property, value, startIndex, endIndex)
|
|
{
|
|
if (startIndex === undefined) { startIndex = 0; }
|
|
if (endIndex === undefined) { endIndex = array.length; }
|
|
|
|
if (SafeRange(array, startIndex, endIndex))
|
|
{
|
|
for (var i = startIndex; i < endIndex; i++)
|
|
{
|
|
var entry = array[i];
|
|
|
|
if (entry.hasOwnProperty(property))
|
|
{
|
|
entry[property] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = SetAll;
|
|
|
|
|
|
/***/ }),
|
|
/* 287 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Takes the given array and runs a numeric sort on it, ignoring any non-digits that
|
|
* may be in the entries.
|
|
*
|
|
* You should only run this on arrays containing strings.
|
|
*
|
|
* @function Phaser.Utils.Array.SortByDigits
|
|
* @since 3.50.0
|
|
*
|
|
* @param {string[]} array - The input array of strings.
|
|
*
|
|
* @return {string[]} The sorted input array.
|
|
*/
|
|
var SortByDigits = function (array)
|
|
{
|
|
var re = /\D/g;
|
|
|
|
array.sort(function (a, b)
|
|
{
|
|
return (parseInt(a.replace(re, ''), 10) - parseInt(b.replace(re, ''), 10));
|
|
});
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = SortByDigits;
|
|
|
|
|
|
/***/ }),
|
|
/* 288 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author Angry Bytes (and contributors)
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The comparator function.
|
|
*
|
|
* @ignore
|
|
*
|
|
* @param {*} a - The first item to test.
|
|
* @param {*} b - The second itemt to test.
|
|
*
|
|
* @return {boolean} True if they localCompare, otherwise false.
|
|
*/
|
|
function Compare (a, b)
|
|
{
|
|
return String(a).localeCompare(b);
|
|
}
|
|
|
|
/**
|
|
* Process the array contents.
|
|
*
|
|
* @ignore
|
|
*
|
|
* @param {array} array - The array to process.
|
|
* @param {function} compare - The comparison function.
|
|
*
|
|
* @return {array} - The processed array.
|
|
*/
|
|
function Process (array, compare)
|
|
{
|
|
// Short-circuit when there's nothing to sort.
|
|
var len = array.length;
|
|
|
|
if (len <= 1)
|
|
{
|
|
return array;
|
|
}
|
|
|
|
// Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc.
|
|
// Chunks are the size of the left or right hand in merge sort.
|
|
// Stop when the left-hand covers all of the array.
|
|
var buffer = new Array(len);
|
|
|
|
for (var chk = 1; chk < len; chk *= 2)
|
|
{
|
|
RunPass(array, compare, chk, buffer);
|
|
|
|
var tmp = array;
|
|
|
|
array = buffer;
|
|
|
|
buffer = tmp;
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Run a single pass with the given chunk size.
|
|
*
|
|
* @ignore
|
|
*
|
|
* @param {array} arr - The array to run the pass on.
|
|
* @param {function} comp - The comparison function.
|
|
* @param {number} chk - The number of iterations.
|
|
* @param {array} result - The array to store the result in.
|
|
*/
|
|
function RunPass (arr, comp, chk, result)
|
|
{
|
|
var len = arr.length;
|
|
var i = 0;
|
|
|
|
// Step size / double chunk size.
|
|
var dbl = chk * 2;
|
|
|
|
// Bounds of the left and right chunks.
|
|
var l, r, e;
|
|
|
|
// Iterators over the left and right chunk.
|
|
var li, ri;
|
|
|
|
// Iterate over pairs of chunks.
|
|
for (l = 0; l < len; l += dbl)
|
|
{
|
|
r = l + chk;
|
|
e = r + chk;
|
|
|
|
if (r > len)
|
|
{
|
|
r = len;
|
|
}
|
|
|
|
if (e > len)
|
|
{
|
|
e = len;
|
|
}
|
|
|
|
// Iterate both chunks in parallel.
|
|
li = l;
|
|
ri = r;
|
|
|
|
while (true)
|
|
{
|
|
// Compare the chunks.
|
|
if (li < r && ri < e)
|
|
{
|
|
// This works for a regular `sort()` compatible comparator,
|
|
// but also for a simple comparator like: `a > b`
|
|
if (comp(arr[li], arr[ri]) <= 0)
|
|
{
|
|
result[i++] = arr[li++];
|
|
}
|
|
else
|
|
{
|
|
result[i++] = arr[ri++];
|
|
}
|
|
}
|
|
else if (li < r)
|
|
{
|
|
// Nothing to compare, just flush what's left.
|
|
result[i++] = arr[li++];
|
|
}
|
|
else if (ri < e)
|
|
{
|
|
result[i++] = arr[ri++];
|
|
}
|
|
else
|
|
{
|
|
// Both iterators are at the chunk ends.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An in-place stable array sort, because `Array#sort()` is not guaranteed stable.
|
|
*
|
|
* This is an implementation of merge sort, without recursion.
|
|
*
|
|
* Function based on the Two-Screen/stable sort 0.1.8 from https://github.com/Two-Screen/stable
|
|
*
|
|
* @function Phaser.Utils.Array.StableSort
|
|
* @since 3.0.0
|
|
*
|
|
* @param {array} array - The input array to be sorted.
|
|
* @param {function} [compare] - The comparison function.
|
|
*
|
|
* @return {array} The sorted result.
|
|
*/
|
|
var StableSort = function (array, compare)
|
|
{
|
|
if (compare === undefined) { compare = Compare; }
|
|
|
|
var result = Process(array, compare);
|
|
|
|
// This simply copies back if the result isn't in the original array, which happens on an odd number of passes.
|
|
if (result !== array)
|
|
{
|
|
RunPass(result, null, array.length, array);
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = StableSort;
|
|
|
|
|
|
/***/ }),
|
|
/* 289 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Swaps the position of two elements in the given array.
|
|
* The elements must exist in the same array.
|
|
* The array is modified in-place.
|
|
*
|
|
* @function Phaser.Utils.Array.Swap
|
|
* @since 3.4.0
|
|
*
|
|
* @param {array} array - The input array.
|
|
* @param {*} item1 - The first element to swap.
|
|
* @param {*} item2 - The second element to swap.
|
|
*
|
|
* @return {array} The input array.
|
|
*/
|
|
var Swap = function (array, item1, item2)
|
|
{
|
|
if (item1 === item2)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var index1 = array.indexOf(item1);
|
|
var index2 = array.indexOf(item2);
|
|
|
|
if (index1 < 0 || index2 < 0)
|
|
{
|
|
throw new Error('Supplied items must be elements of the same array');
|
|
}
|
|
|
|
array[index1] = item2;
|
|
array[index2] = item1;
|
|
|
|
return array;
|
|
};
|
|
|
|
module.exports = Swap;
|
|
|
|
|
|
/***/ }),
|
|
/* 290 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.GameObjects.Components
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
Alpha: __webpack_require__(291),
|
|
AlphaSingle: __webpack_require__(292),
|
|
BlendMode: __webpack_require__(293),
|
|
ComputedSize: __webpack_require__(46),
|
|
Crop: __webpack_require__(294),
|
|
Depth: __webpack_require__(47),
|
|
Flip: __webpack_require__(48),
|
|
GetBounds: __webpack_require__(295),
|
|
Mask: __webpack_require__(304),
|
|
Origin: __webpack_require__(324),
|
|
PathFollower: __webpack_require__(325),
|
|
Pipeline: __webpack_require__(328),
|
|
ScrollFactor: __webpack_require__(49),
|
|
Size: __webpack_require__(330),
|
|
Texture: __webpack_require__(331),
|
|
TextureCrop: __webpack_require__(332),
|
|
Tint: __webpack_require__(333),
|
|
ToJSON: __webpack_require__(53),
|
|
Transform: __webpack_require__(50),
|
|
TransformMatrix: __webpack_require__(23),
|
|
Visible: __webpack_require__(51)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 291 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Clamp = __webpack_require__(4);
|
|
|
|
// bitmask flag for GameObject.renderMask
|
|
var _FLAG = 2; // 0010
|
|
|
|
/**
|
|
* Provides methods used for setting the alpha properties of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Alpha
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Alpha = {
|
|
|
|
/**
|
|
* Private internal value. Holds the global alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#_alpha
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alpha: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the top-left alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#_alphaTL
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alphaTL: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the top-right alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#_alphaTR
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alphaTR: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the bottom-left alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#_alphaBL
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alphaBL: 1,
|
|
|
|
/**
|
|
* Private internal value. Holds the bottom-right alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#_alphaBR
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alphaBR: 1,
|
|
|
|
/**
|
|
* Clears all alpha values associated with this Game Object.
|
|
*
|
|
* Immediately sets the alpha levels back to 1 (fully opaque).
|
|
*
|
|
* @method Phaser.GameObjects.Components.Alpha#clearAlpha
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
clearAlpha: function ()
|
|
{
|
|
return this.setAlpha(1);
|
|
},
|
|
|
|
/**
|
|
* Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
|
|
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
|
|
*
|
|
* If your game is running under WebGL you can optionally specify four different alpha values, each of which
|
|
* correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Alpha#setAlpha
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [topLeft=1] - The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object.
|
|
* @param {number} [topRight] - The alpha value used for the top-right of the Game Object. WebGL only.
|
|
* @param {number} [bottomLeft] - The alpha value used for the bottom-left of the Game Object. WebGL only.
|
|
* @param {number} [bottomRight] - The alpha value used for the bottom-right of the Game Object. WebGL only.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setAlpha: function (topLeft, topRight, bottomLeft, bottomRight)
|
|
{
|
|
if (topLeft === undefined) { topLeft = 1; }
|
|
|
|
// Treat as if there is only one alpha value for the whole Game Object
|
|
if (topRight === undefined)
|
|
{
|
|
this.alpha = topLeft;
|
|
}
|
|
else
|
|
{
|
|
this._alphaTL = Clamp(topLeft, 0, 1);
|
|
this._alphaTR = Clamp(topRight, 0, 1);
|
|
this._alphaBL = Clamp(bottomLeft, 0, 1);
|
|
this._alphaBR = Clamp(bottomRight, 0, 1);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The alpha value of the Game Object.
|
|
*
|
|
* This is a global value, impacting the entire Game Object, not just a region of it.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#alpha
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
alpha: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alpha;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alpha = v;
|
|
this._alphaTL = v;
|
|
this._alphaTR = v;
|
|
this._alphaBL = v;
|
|
this._alphaBR = v;
|
|
|
|
if (v === 0)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The alpha value starting from the top-left of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#alphaTopLeft
|
|
* @type {number}
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
alphaTopLeft: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alphaTL;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alphaTL = v;
|
|
|
|
if (v !== 0)
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The alpha value starting from the top-right of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#alphaTopRight
|
|
* @type {number}
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
alphaTopRight: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alphaTR;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alphaTR = v;
|
|
|
|
if (v !== 0)
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The alpha value starting from the bottom-left of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#alphaBottomLeft
|
|
* @type {number}
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
alphaBottomLeft: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alphaBL;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alphaBL = v;
|
|
|
|
if (v !== 0)
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The alpha value starting from the bottom-right of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Alpha#alphaBottomRight
|
|
* @type {number}
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
alphaBottomRight: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alphaBR;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alphaBR = v;
|
|
|
|
if (v !== 0)
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Alpha;
|
|
|
|
|
|
/***/ }),
|
|
/* 292 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Clamp = __webpack_require__(4);
|
|
|
|
// bitmask flag for GameObject.renderMask
|
|
var _FLAG = 2; // 0010
|
|
|
|
/**
|
|
* Provides methods used for setting the alpha property of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.AlphaSingle
|
|
* @since 3.22.0
|
|
*/
|
|
|
|
var AlphaSingle = {
|
|
|
|
/**
|
|
* Private internal value. Holds the global alpha value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.AlphaSingle#_alpha
|
|
* @type {number}
|
|
* @private
|
|
* @default 1
|
|
* @since 3.0.0
|
|
*/
|
|
_alpha: 1,
|
|
|
|
/**
|
|
* Clears all alpha values associated with this Game Object.
|
|
*
|
|
* Immediately sets the alpha levels back to 1 (fully opaque).
|
|
*
|
|
* @method Phaser.GameObjects.Components.AlphaSingle#clearAlpha
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
clearAlpha: function ()
|
|
{
|
|
return this.setAlpha(1);
|
|
},
|
|
|
|
/**
|
|
* Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
|
|
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
|
|
*
|
|
* @method Phaser.GameObjects.Components.AlphaSingle#setAlpha
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [value=1] - The alpha value applied across the whole Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setAlpha: function (value)
|
|
{
|
|
if (value === undefined) { value = 1; }
|
|
|
|
this.alpha = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The alpha value of the Game Object.
|
|
*
|
|
* This is a global value, impacting the entire Game Object, not just a region of it.
|
|
*
|
|
* @name Phaser.GameObjects.Components.AlphaSingle#alpha
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
alpha: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._alpha;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
var v = Clamp(value, 0, 1);
|
|
|
|
this._alpha = v;
|
|
|
|
if (v === 0)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = AlphaSingle;
|
|
|
|
|
|
/***/ }),
|
|
/* 293 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var BlendModes = __webpack_require__(17);
|
|
|
|
/**
|
|
* Provides methods used for setting the blend mode of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.BlendMode
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var BlendMode = {
|
|
|
|
/**
|
|
* Private internal value. Holds the current blend mode.
|
|
*
|
|
* @name Phaser.GameObjects.Components.BlendMode#_blendMode
|
|
* @type {integer}
|
|
* @private
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
_blendMode: BlendModes.NORMAL,
|
|
|
|
/**
|
|
* Sets the Blend Mode being used by this Game Object.
|
|
*
|
|
* This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
|
|
*
|
|
* Under WebGL only the following Blend Modes are available:
|
|
*
|
|
* * ADD
|
|
* * MULTIPLY
|
|
* * SCREEN
|
|
* * ERASE
|
|
*
|
|
* Canvas has more available depending on browser support.
|
|
*
|
|
* You can also create your own custom Blend Modes in WebGL.
|
|
*
|
|
* Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
|
|
* on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
|
|
* reasons try to be careful about the construction of your Scene and the frequency of which blend modes
|
|
* are used.
|
|
*
|
|
* @name Phaser.GameObjects.Components.BlendMode#blendMode
|
|
* @type {(Phaser.BlendModes|string)}
|
|
* @since 3.0.0
|
|
*/
|
|
blendMode: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._blendMode;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (typeof value === 'string')
|
|
{
|
|
value = BlendModes[value];
|
|
}
|
|
|
|
value |= 0;
|
|
|
|
if (value >= -1)
|
|
{
|
|
this._blendMode = value;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the Blend Mode being used by this Game Object.
|
|
*
|
|
* This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
|
|
*
|
|
* Under WebGL only the following Blend Modes are available:
|
|
*
|
|
* * ADD
|
|
* * MULTIPLY
|
|
* * SCREEN
|
|
* * ERASE (only works when rendering to a framebuffer, like a Render Texture)
|
|
*
|
|
* Canvas has more available depending on browser support.
|
|
*
|
|
* You can also create your own custom Blend Modes in WebGL.
|
|
*
|
|
* Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
|
|
* on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
|
|
* reasons try to be careful about the construction of your Scene and the frequency in which blend modes
|
|
* are used.
|
|
*
|
|
* @method Phaser.GameObjects.Components.BlendMode#setBlendMode
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|Phaser.BlendModes)} value - The BlendMode value. Either a string or a CONST.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setBlendMode: function (value)
|
|
{
|
|
this.blendMode = value;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = BlendMode;
|
|
|
|
|
|
/***/ }),
|
|
/* 294 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the texture of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Crop
|
|
* @since 3.12.0
|
|
*/
|
|
|
|
var Crop = {
|
|
|
|
/**
|
|
* The Texture this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Crop#texture
|
|
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
|
|
* @since 3.0.0
|
|
*/
|
|
texture: null,
|
|
|
|
/**
|
|
* The Texture Frame this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Crop#frame
|
|
* @type {Phaser.Textures.Frame}
|
|
* @since 3.0.0
|
|
*/
|
|
frame: null,
|
|
|
|
/**
|
|
* A boolean flag indicating if this Game Object is being cropped or not.
|
|
* You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
|
|
* Equally, calling `setCrop` with no arguments will reset the crop and disable it.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Crop#isCropped
|
|
* @type {boolean}
|
|
* @since 3.11.0
|
|
*/
|
|
isCropped: false,
|
|
|
|
/**
|
|
* Applies a crop to a texture based Game Object, such as a Sprite or Image.
|
|
*
|
|
* The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
|
|
*
|
|
* Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
|
|
* changes what is shown when rendered.
|
|
*
|
|
* The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
|
|
*
|
|
* Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
|
|
* half of it, you could call `setCrop(0, 0, 400, 600)`.
|
|
*
|
|
* It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop
|
|
* an area of 200x100 when applied to a Game Object that had a scale factor of 2.
|
|
*
|
|
* You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
|
|
*
|
|
* Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
|
|
*
|
|
* You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
|
|
* the renderer to skip several internal calculations.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Crop#setCrop
|
|
* @since 3.11.0
|
|
*
|
|
* @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
|
|
* @param {number} [y] - The y coordinate to start the crop from.
|
|
* @param {number} [width] - The width of the crop rectangle in pixels.
|
|
* @param {number} [height] - The height of the crop rectangle in pixels.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setCrop: function (x, y, width, height)
|
|
{
|
|
if (x === undefined)
|
|
{
|
|
this.isCropped = false;
|
|
}
|
|
else if (this.frame)
|
|
{
|
|
if (typeof x === 'number')
|
|
{
|
|
this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
|
|
}
|
|
else
|
|
{
|
|
var rect = x;
|
|
|
|
this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
|
|
}
|
|
|
|
this.isCropped = true;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Internal method that returns a blank, well-formed crop object for use by a Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Crop#resetCropObject
|
|
* @private
|
|
* @since 3.12.0
|
|
*
|
|
* @return {object} The crop object.
|
|
*/
|
|
resetCropObject: function ()
|
|
{
|
|
return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Crop;
|
|
|
|
|
|
/***/ }),
|
|
/* 295 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Rectangle = __webpack_require__(25);
|
|
var RotateAround = __webpack_require__(39);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* Provides methods used for obtaining the bounds of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.GetBounds
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var GetBounds = {
|
|
|
|
/**
|
|
* Processes the bounds output vector before returning it.
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#prepareBoundsOutput
|
|
* @private
|
|
* @since 3.18.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} output - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
prepareBoundsOutput: function (output, includeParent)
|
|
{
|
|
if (includeParent === undefined) { includeParent = false; }
|
|
|
|
if (this.rotation !== 0)
|
|
{
|
|
RotateAround(output, this.x, this.y, this.rotation);
|
|
}
|
|
|
|
if (includeParent && this.parentContainer)
|
|
{
|
|
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
|
|
|
|
parentMatrix.transformPoint(output.x, output.y, output);
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Gets the center coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getCenter
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getCenter: function (output)
|
|
{
|
|
if (output === undefined) { output = new Vector2(); }
|
|
|
|
output.x = this.x - (this.displayWidth * this.originX) + (this.displayWidth / 2);
|
|
output.y = this.y - (this.displayHeight * this.originY) + (this.displayHeight / 2);
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Gets the top-left corner coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getTopLeft
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getTopLeft: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = this.x - (this.displayWidth * this.originX);
|
|
output.y = this.y - (this.displayHeight * this.originY);
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the top-center coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getTopCenter
|
|
* @since 3.18.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getTopCenter: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2);
|
|
output.y = this.y - (this.displayHeight * this.originY);
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the top-right corner coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getTopRight
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getTopRight: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
|
|
output.y = this.y - (this.displayHeight * this.originY);
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the left-center coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getLeftCenter
|
|
* @since 3.18.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getLeftCenter: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = this.x - (this.displayWidth * this.originX);
|
|
output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2);
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the right-center coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getRightCenter
|
|
* @since 3.18.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getRightCenter: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
|
|
output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2);
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the bottom-left corner coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getBottomLeft
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getBottomLeft: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = this.x - (this.displayWidth * this.originX);
|
|
output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the bottom-center coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getBottomCenter
|
|
* @since 3.18.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getBottomCenter: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2);
|
|
output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the bottom-right corner coordinate of this Game Object, regardless of origin.
|
|
* The returned point is calculated in local space and does not factor in any parent containers
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getBottomRight
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created.
|
|
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
|
|
*
|
|
* @return {(Phaser.Math.Vector2|object)} The values stored in the output object.
|
|
*/
|
|
getBottomRight: function (output, includeParent)
|
|
{
|
|
if (!output) { output = new Vector2(); }
|
|
|
|
output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
|
|
output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;
|
|
|
|
return this.prepareBoundsOutput(output, includeParent);
|
|
},
|
|
|
|
/**
|
|
* Gets the bounds of this Game Object, regardless of origin.
|
|
* The values are stored and returned in a Rectangle, or Rectangle-like, object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.GetBounds#getBounds
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Rectangle} O - [output,$return]
|
|
*
|
|
* @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created.
|
|
*
|
|
* @return {(Phaser.Geom.Rectangle|object)} The values stored in the output object.
|
|
*/
|
|
getBounds: function (output)
|
|
{
|
|
if (output === undefined) { output = new Rectangle(); }
|
|
|
|
// We can use the output object to temporarily store the x/y coords in:
|
|
|
|
var TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy;
|
|
|
|
// Instead of doing a check if parent container is
|
|
// defined per corner we only do it once.
|
|
if (this.parentContainer)
|
|
{
|
|
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
|
|
|
|
this.getTopLeft(output);
|
|
parentMatrix.transformPoint(output.x, output.y, output);
|
|
|
|
TLx = output.x;
|
|
TLy = output.y;
|
|
|
|
this.getTopRight(output);
|
|
parentMatrix.transformPoint(output.x, output.y, output);
|
|
|
|
TRx = output.x;
|
|
TRy = output.y;
|
|
|
|
this.getBottomLeft(output);
|
|
parentMatrix.transformPoint(output.x, output.y, output);
|
|
|
|
BLx = output.x;
|
|
BLy = output.y;
|
|
|
|
this.getBottomRight(output);
|
|
parentMatrix.transformPoint(output.x, output.y, output);
|
|
|
|
BRx = output.x;
|
|
BRy = output.y;
|
|
}
|
|
else
|
|
{
|
|
this.getTopLeft(output);
|
|
|
|
TLx = output.x;
|
|
TLy = output.y;
|
|
|
|
this.getTopRight(output);
|
|
|
|
TRx = output.x;
|
|
TRy = output.y;
|
|
|
|
this.getBottomLeft(output);
|
|
|
|
BLx = output.x;
|
|
BLy = output.y;
|
|
|
|
this.getBottomRight(output);
|
|
|
|
BRx = output.x;
|
|
BRy = output.y;
|
|
}
|
|
|
|
output.x = Math.min(TLx, TRx, BLx, BRx);
|
|
output.y = Math.min(TLy, TRy, BLy, BRy);
|
|
output.width = Math.max(TLx, TRx, BLx, BRx) - output.x;
|
|
output.height = Math.max(TLy, TRy, BLy, BRy) - output.y;
|
|
|
|
return output;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = GetBounds;
|
|
|
|
|
|
/***/ }),
|
|
/* 296 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Checks if a given point is inside a Rectangle's bounds.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.Contains
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rect - The Rectangle to check.
|
|
* @param {number} x - The X coordinate of the point to check.
|
|
* @param {number} y - The Y coordinate of the point to check.
|
|
*
|
|
* @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`.
|
|
*/
|
|
var Contains = function (rect, x, y)
|
|
{
|
|
if (rect.width <= 0 || rect.height <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return (rect.x <= x && rect.x + rect.width >= x && rect.y <= y && rect.y + rect.height >= y);
|
|
};
|
|
|
|
module.exports = Contains;
|
|
|
|
|
|
/***/ }),
|
|
/* 297 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var GetPoint = __webpack_require__(59);
|
|
var Perimeter = __webpack_require__(60);
|
|
|
|
// Return an array of points from the perimeter of the rectangle
|
|
// each spaced out based on the quantity or step required
|
|
|
|
/**
|
|
* Return an array of points from the perimeter of the rectangle, each spaced out based on the quantity or step required.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.GetPoints
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point[]} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rectangle - The Rectangle object to get the points from.
|
|
* @param {number} step - Step between points. Used to calculate the number of points to return when quantity is falsey. Ignored if quantity is positive.
|
|
* @param {integer} quantity - The number of evenly spaced points from the rectangles perimeter to return. If falsey, step param will be used to calculate the number of points.
|
|
* @param {(array|Phaser.Geom.Point[])} [out] - An optional array to store the points in.
|
|
*
|
|
* @return {(array|Phaser.Geom.Point[])} An array of Points from the perimeter of the rectangle.
|
|
*/
|
|
var GetPoints = function (rectangle, quantity, stepRate, out)
|
|
{
|
|
if (out === undefined) { out = []; }
|
|
|
|
// If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead.
|
|
if (!quantity && stepRate > 0)
|
|
{
|
|
quantity = Perimeter(rectangle) / stepRate;
|
|
}
|
|
|
|
for (var i = 0; i < quantity; i++)
|
|
{
|
|
var position = i / quantity;
|
|
|
|
out.push(GetPoint(rectangle, position));
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = GetPoints;
|
|
|
|
|
|
/***/ }),
|
|
/* 298 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var GetPoint = __webpack_require__(299);
|
|
var GetPoints = __webpack_require__(300);
|
|
var GEOM_CONST = __webpack_require__(26);
|
|
var Random = __webpack_require__(302);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* @classdesc
|
|
* Defines a Line segment, a part of a line between two endpoints.
|
|
*
|
|
* @class Line
|
|
* @memberof Phaser.Geom
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x1=0] - The x coordinate of the lines starting point.
|
|
* @param {number} [y1=0] - The y coordinate of the lines starting point.
|
|
* @param {number} [x2=0] - The x coordinate of the lines ending point.
|
|
* @param {number} [y2=0] - The y coordinate of the lines ending point.
|
|
*/
|
|
var Line = new Class({
|
|
|
|
initialize:
|
|
|
|
function Line (x1, y1, x2, y2)
|
|
{
|
|
if (x1 === undefined) { x1 = 0; }
|
|
if (y1 === undefined) { y1 = 0; }
|
|
if (x2 === undefined) { x2 = 0; }
|
|
if (y2 === undefined) { y2 = 0; }
|
|
|
|
/**
|
|
* The geometry constant type of this object: `GEOM_CONST.LINE`.
|
|
* Used for fast type comparisons.
|
|
*
|
|
* @name Phaser.Geom.Line#type
|
|
* @type {integer}
|
|
* @readonly
|
|
* @since 3.19.0
|
|
*/
|
|
this.type = GEOM_CONST.LINE;
|
|
|
|
/**
|
|
* The x coordinate of the lines starting point.
|
|
*
|
|
* @name Phaser.Geom.Line#x1
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
this.x1 = x1;
|
|
|
|
/**
|
|
* The y coordinate of the lines starting point.
|
|
*
|
|
* @name Phaser.Geom.Line#y1
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
this.y1 = y1;
|
|
|
|
/**
|
|
* The x coordinate of the lines ending point.
|
|
*
|
|
* @name Phaser.Geom.Line#x2
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
this.x2 = x2;
|
|
|
|
/**
|
|
* The y coordinate of the lines ending point.
|
|
*
|
|
* @name Phaser.Geom.Line#y2
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
this.y2 = y2;
|
|
},
|
|
|
|
/**
|
|
* Get a point on a line that's a given percentage along its length.
|
|
*
|
|
* @method Phaser.Geom.Line#getPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [output,$return]
|
|
*
|
|
* @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line.
|
|
* @param {(Phaser.Geom.Point|object)} [output] - An optional point, or point-like object, to store the coordinates of the point on the line.
|
|
*
|
|
* @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point on the line.
|
|
*/
|
|
getPoint: function (position, output)
|
|
{
|
|
return GetPoint(this, position, output);
|
|
},
|
|
|
|
/**
|
|
* Get a number of points along a line's length.
|
|
*
|
|
* Provide a `quantity` to get an exact number of points along the line.
|
|
*
|
|
* Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
|
|
* providing a `stepRate`.
|
|
*
|
|
* @method Phaser.Geom.Line#getPoints
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point[]} O - [output,$return]
|
|
*
|
|
* @param {integer} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead.
|
|
* @param {integer} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`.
|
|
* @param {(array|Phaser.Geom.Point[])} [output] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line.
|
|
*
|
|
* @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line.
|
|
*/
|
|
getPoints: function (quantity, stepRate, output)
|
|
{
|
|
return GetPoints(this, quantity, stepRate, output);
|
|
},
|
|
|
|
/**
|
|
* Get a random Point on the Line.
|
|
*
|
|
* @method Phaser.Geom.Line#getRandomPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [point,$return]
|
|
*
|
|
* @param {(Phaser.Geom.Point|object)} [point] - An instance of a Point to be modified.
|
|
*
|
|
* @return {Phaser.Geom.Point} A random Point on the Line.
|
|
*/
|
|
getRandomPoint: function (point)
|
|
{
|
|
return Random(this, point);
|
|
},
|
|
|
|
/**
|
|
* Set new coordinates for the line endpoints.
|
|
*
|
|
* @method Phaser.Geom.Line#setTo
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x1=0] - The x coordinate of the lines starting point.
|
|
* @param {number} [y1=0] - The y coordinate of the lines starting point.
|
|
* @param {number} [x2=0] - The x coordinate of the lines ending point.
|
|
* @param {number} [y2=0] - The y coordinate of the lines ending point.
|
|
*
|
|
* @return {this} This Line object.
|
|
*/
|
|
setTo: function (x1, y1, x2, y2)
|
|
{
|
|
if (x1 === undefined) { x1 = 0; }
|
|
if (y1 === undefined) { y1 = 0; }
|
|
if (x2 === undefined) { x2 = 0; }
|
|
if (y2 === undefined) { y2 = 0; }
|
|
|
|
this.x1 = x1;
|
|
this.y1 = y1;
|
|
|
|
this.x2 = x2;
|
|
this.y2 = y2;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Returns a Vector2 object that corresponds to the start of this Line.
|
|
*
|
|
* @method Phaser.Geom.Line#getPointA
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [vec2,$return]
|
|
*
|
|
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
|
|
*
|
|
* @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the start of this Line.
|
|
*/
|
|
getPointA: function (vec2)
|
|
{
|
|
if (vec2 === undefined) { vec2 = new Vector2(); }
|
|
|
|
vec2.set(this.x1, this.y1);
|
|
|
|
return vec2;
|
|
},
|
|
|
|
/**
|
|
* Returns a Vector2 object that corresponds to the end of this Line.
|
|
*
|
|
* @method Phaser.Geom.Line#getPointB
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Math.Vector2} O - [vec2,$return]
|
|
*
|
|
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
|
|
*
|
|
* @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the end of this Line.
|
|
*/
|
|
getPointB: function (vec2)
|
|
{
|
|
if (vec2 === undefined) { vec2 = new Vector2(); }
|
|
|
|
vec2.set(this.x2, this.y2);
|
|
|
|
return vec2;
|
|
},
|
|
|
|
/**
|
|
* The left position of the Line.
|
|
*
|
|
* @name Phaser.Geom.Line#left
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
left: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.min(this.x1, this.x2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (this.x1 <= this.x2)
|
|
{
|
|
this.x1 = value;
|
|
}
|
|
else
|
|
{
|
|
this.x2 = value;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The right position of the Line.
|
|
*
|
|
* @name Phaser.Geom.Line#right
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
right: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.max(this.x1, this.x2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (this.x1 > this.x2)
|
|
{
|
|
this.x1 = value;
|
|
}
|
|
else
|
|
{
|
|
this.x2 = value;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The top position of the Line.
|
|
*
|
|
* @name Phaser.Geom.Line#top
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
top: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.min(this.y1, this.y2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (this.y1 <= this.y2)
|
|
{
|
|
this.y1 = value;
|
|
}
|
|
else
|
|
{
|
|
this.y2 = value;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The bottom position of the Line.
|
|
*
|
|
* @name Phaser.Geom.Line#bottom
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
bottom: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.max(this.y1, this.y2);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
if (this.y1 > this.y2)
|
|
{
|
|
this.y1 = value;
|
|
}
|
|
else
|
|
{
|
|
this.y2 = value;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = Line;
|
|
|
|
|
|
/***/ }),
|
|
/* 299 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Point = __webpack_require__(12);
|
|
|
|
/**
|
|
* Get a point on a line that's a given percentage along its length.
|
|
*
|
|
* @function Phaser.Geom.Line.GetPoint
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} line - The line.
|
|
* @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line.
|
|
* @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the point on the line.
|
|
*
|
|
* @return {(Phaser.Geom.Point|object)} The point on the line.
|
|
*/
|
|
var GetPoint = function (line, position, out)
|
|
{
|
|
if (out === undefined) { out = new Point(); }
|
|
|
|
out.x = line.x1 + (line.x2 - line.x1) * position;
|
|
out.y = line.y1 + (line.y2 - line.y1) * position;
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = GetPoint;
|
|
|
|
|
|
/***/ }),
|
|
/* 300 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Length = __webpack_require__(301);
|
|
var Point = __webpack_require__(12);
|
|
|
|
/**
|
|
* Get a number of points along a line's length.
|
|
*
|
|
* Provide a `quantity` to get an exact number of points along the line.
|
|
*
|
|
* Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
|
|
* providing a `stepRate`.
|
|
*
|
|
* @function Phaser.Geom.Line.GetPoints
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point[]} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} line - The line.
|
|
* @param {integer} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead.
|
|
* @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`.
|
|
* @param {(array|Phaser.Geom.Point[])} [out] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line.
|
|
*
|
|
* @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line.
|
|
*/
|
|
var GetPoints = function (line, quantity, stepRate, out)
|
|
{
|
|
if (out === undefined) { out = []; }
|
|
|
|
// If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead.
|
|
if (!quantity && stepRate > 0)
|
|
{
|
|
quantity = Length(line) / stepRate;
|
|
}
|
|
|
|
var x1 = line.x1;
|
|
var y1 = line.y1;
|
|
|
|
var x2 = line.x2;
|
|
var y2 = line.y2;
|
|
|
|
for (var i = 0; i < quantity; i++)
|
|
{
|
|
var position = i / quantity;
|
|
|
|
var x = x1 + (x2 - x1) * position;
|
|
var y = y1 + (y2 - y1) * position;
|
|
|
|
out.push(new Point(x, y));
|
|
}
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = GetPoints;
|
|
|
|
|
|
/***/ }),
|
|
/* 301 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Calculate the length of the given line.
|
|
*
|
|
* @function Phaser.Geom.Line.Length
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Geom.Line} line - The line to calculate the length of.
|
|
*
|
|
* @return {number} The length of the line.
|
|
*/
|
|
var Length = function (line)
|
|
{
|
|
return Math.sqrt((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));
|
|
};
|
|
|
|
module.exports = Length;
|
|
|
|
|
|
/***/ }),
|
|
/* 302 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Point = __webpack_require__(12);
|
|
|
|
/**
|
|
* Returns a random point on a given Line.
|
|
*
|
|
* @function Phaser.Geom.Line.Random
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Line} line - The Line to calculate the random Point on.
|
|
* @param {(Phaser.Geom.Point|object)} [out] - An instance of a Point to be modified.
|
|
*
|
|
* @return {(Phaser.Geom.Point|object)} A random Point on the Line.
|
|
*/
|
|
var Random = function (line, out)
|
|
{
|
|
if (out === undefined) { out = new Point(); }
|
|
|
|
var t = Math.random();
|
|
|
|
out.x = line.x1 + t * (line.x2 - line.x1);
|
|
out.y = line.y1 + t * (line.y2 - line.y1);
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = Random;
|
|
|
|
|
|
/***/ }),
|
|
/* 303 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Point = __webpack_require__(12);
|
|
|
|
/**
|
|
* Returns a random point within a Rectangle.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.Random
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Point} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rect - The Rectangle to return a point from.
|
|
* @param {Phaser.Geom.Point} out - The object to update with the point's coordinates.
|
|
*
|
|
* @return {Phaser.Geom.Point} The modified `out` object, or a new Point if none was provided.
|
|
*/
|
|
var Random = function (rect, out)
|
|
{
|
|
if (out === undefined) { out = new Point(); }
|
|
|
|
out.x = rect.x + (Math.random() * rect.width);
|
|
out.y = rect.y + (Math.random() * rect.height);
|
|
|
|
return out;
|
|
};
|
|
|
|
module.exports = Random;
|
|
|
|
|
|
/***/ }),
|
|
/* 304 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var BitmapMask = __webpack_require__(305);
|
|
var GeometryMask = __webpack_require__(323);
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the mask of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Mask
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Mask = {
|
|
|
|
/**
|
|
* The Mask this Game Object is using during render.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Mask#mask
|
|
* @type {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask}
|
|
* @since 3.0.0
|
|
*/
|
|
mask: null,
|
|
|
|
/**
|
|
* Sets the mask that this Game Object will use to render with.
|
|
*
|
|
* The mask must have been previously created and can be either a GeometryMask or a BitmapMask.
|
|
* Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
|
|
*
|
|
* If a mask is already set on this Game Object it will be immediately replaced.
|
|
*
|
|
* Masks are positioned in global space and are not relative to the Game Object to which they
|
|
* are applied. The reason for this is that multiple Game Objects can all share the same mask.
|
|
*
|
|
* Masks have no impact on physics or input detection. They are purely a rendering component
|
|
* that allows you to limit what is visible during the render pass.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Mask#setMask
|
|
* @since 3.6.2
|
|
*
|
|
* @param {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} mask - The mask this Game Object will use when rendering.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setMask: function (mask)
|
|
{
|
|
this.mask = mask;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Clears the mask that this Game Object was using.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Mask#clearMask
|
|
* @since 3.6.2
|
|
*
|
|
* @param {boolean} [destroyMask=false] - Destroy the mask before clearing it?
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
clearMask: function (destroyMask)
|
|
{
|
|
if (destroyMask === undefined) { destroyMask = false; }
|
|
|
|
if (destroyMask && this.mask)
|
|
{
|
|
this.mask.destroy();
|
|
}
|
|
|
|
this.mask = null;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Creates and returns a Bitmap Mask. This mask can be used by any Game Object,
|
|
* including this one.
|
|
*
|
|
* Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
|
|
*
|
|
* To create the mask you need to pass in a reference to a renderable Game Object.
|
|
* A renderable Game Object is one that uses a texture to render with, such as an
|
|
* Image, Sprite, Render Texture or BitmapText.
|
|
*
|
|
* If you do not provide a renderable object, and this Game Object has a texture,
|
|
* it will use itself as the object. This means you can call this method to create
|
|
* a Bitmap Mask from any renderable Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Mask#createBitmapMask
|
|
* @since 3.6.2
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} [renderable] - A renderable Game Object that uses a texture, such as a Sprite.
|
|
*
|
|
* @return {Phaser.Display.Masks.BitmapMask} This Bitmap Mask that was created.
|
|
*/
|
|
createBitmapMask: function (renderable)
|
|
{
|
|
if (renderable === undefined && (this.texture || this.shader))
|
|
{
|
|
// eslint-disable-next-line consistent-this
|
|
renderable = this;
|
|
}
|
|
|
|
return new BitmapMask(this.scene, renderable);
|
|
},
|
|
|
|
/**
|
|
* Creates and returns a Geometry Mask. This mask can be used by any Game Object,
|
|
* including this one.
|
|
*
|
|
* To create the mask you need to pass in a reference to a Graphics Game Object.
|
|
*
|
|
* If you do not provide a graphics object, and this Game Object is an instance
|
|
* of a Graphics object, then it will use itself to create the mask.
|
|
*
|
|
* This means you can call this method to create a Geometry Mask from any Graphics Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Mask#createGeometryMask
|
|
* @since 3.6.2
|
|
*
|
|
* @param {Phaser.GameObjects.Graphics} [graphics] - A Graphics Game Object. The geometry within it will be used as the mask.
|
|
*
|
|
* @return {Phaser.Display.Masks.GeometryMask} This Geometry Mask that was created.
|
|
*/
|
|
createGeometryMask: function (graphics)
|
|
{
|
|
if (graphics === undefined && this.type === 'Graphics')
|
|
{
|
|
// eslint-disable-next-line consistent-this
|
|
graphics = this;
|
|
}
|
|
|
|
return new GeometryMask(this.scene, graphics);
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Mask;
|
|
|
|
|
|
/***/ }),
|
|
/* 305 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
var GameEvents = __webpack_require__(306);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel.
|
|
* Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask,
|
|
* not a clipping path. It is only available when using the WebGL Renderer.
|
|
*
|
|
* A Bitmap Mask can use any Game Object to determine the alpha of each pixel of the masked Game Object(s).
|
|
* For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha
|
|
* of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the
|
|
* Bitmap Mask doesn't matter.
|
|
*
|
|
* For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an
|
|
* alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means
|
|
* that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects
|
|
* A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the
|
|
* corresponding pixel in the mask.
|
|
*
|
|
* Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however,
|
|
* combine Geometry Masks and Blend Modes together.
|
|
*
|
|
* The Bitmap Mask's location matches the location of its Game Object, not the location of the
|
|
* masked objects. Moving or transforming the underlying Game Object will change the mask
|
|
* (and affect the visibility of any masked objects), whereas moving or transforming a masked object
|
|
* will not affect the mask.
|
|
*
|
|
* The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a
|
|
* Scene's display list, it will only be used for the mask and its full texture will not be directly
|
|
* visible. Adding the underlying Game Object to a Scene will not cause any problems - it will
|
|
* render as a normal Game Object and will also serve as a mask.
|
|
*
|
|
* @class BitmapMask
|
|
* @memberof Phaser.Display.Masks
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scene} scene - The Scene which this Bitmap Mask will be used in.
|
|
* @param {Phaser.GameObjects.GameObject} renderable - A renderable Game Object that uses a texture, such as a Sprite.
|
|
*/
|
|
var BitmapMask = new Class({
|
|
|
|
initialize:
|
|
|
|
function BitmapMask (scene, renderable)
|
|
{
|
|
var renderer = scene.sys.game.renderer;
|
|
|
|
/**
|
|
* A reference to either the Canvas or WebGL Renderer that this Mask is using.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#renderer
|
|
* @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)}
|
|
* @since 3.11.0
|
|
*/
|
|
this.renderer = renderer;
|
|
|
|
/**
|
|
* A renderable Game Object that uses a texture, such as a Sprite.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#bitmapMask
|
|
* @type {Phaser.GameObjects.GameObject}
|
|
* @since 3.0.0
|
|
*/
|
|
this.bitmapMask = renderable;
|
|
|
|
/**
|
|
* The texture used for the mask's framebuffer.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#maskTexture
|
|
* @type {WebGLTexture}
|
|
* @default null
|
|
* @since 3.0.0
|
|
*/
|
|
this.maskTexture = null;
|
|
|
|
/**
|
|
* The texture used for the main framebuffer.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#mainTexture
|
|
* @type {WebGLTexture}
|
|
* @default null
|
|
* @since 3.0.0
|
|
*/
|
|
this.mainTexture = null;
|
|
|
|
/**
|
|
* Whether the Bitmap Mask is dirty and needs to be updated.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#dirty
|
|
* @type {boolean}
|
|
* @default true
|
|
* @since 3.0.0
|
|
*/
|
|
this.dirty = true;
|
|
|
|
/**
|
|
* The framebuffer to which a masked Game Object is rendered.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#mainFramebuffer
|
|
* @type {WebGLFramebuffer}
|
|
* @since 3.0.0
|
|
*/
|
|
this.mainFramebuffer = null;
|
|
|
|
/**
|
|
* The framebuffer to which the Bitmap Mask's masking Game Object is rendered.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#maskFramebuffer
|
|
* @type {WebGLFramebuffer}
|
|
* @since 3.0.0
|
|
*/
|
|
this.maskFramebuffer = null;
|
|
|
|
/**
|
|
* The previous framebuffer set in the renderer before this one was enabled.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#prevFramebuffer
|
|
* @type {WebGLFramebuffer}
|
|
* @since 3.17.0
|
|
*/
|
|
this.prevFramebuffer = null;
|
|
|
|
/**
|
|
* Whether to invert the masks alpha.
|
|
*
|
|
* If `true`, the alpha of the masking pixel will be inverted before it's multiplied with the masked pixel. Essentially, this means that a masked area will be visible only if the corresponding area in the mask is invisible.
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#invertAlpha
|
|
* @type {boolean}
|
|
* @since 3.1.2
|
|
*/
|
|
this.invertAlpha = false;
|
|
|
|
/**
|
|
* Is this mask a stencil mask?
|
|
*
|
|
* @name Phaser.Display.Masks.BitmapMask#isStencil
|
|
* @type {boolean}
|
|
* @readonly
|
|
* @since 3.17.0
|
|
*/
|
|
this.isStencil = false;
|
|
|
|
this.createMask();
|
|
|
|
scene.sys.game.events.on(GameEvents.CONTEXT_RESTORED, this.createMask, this);
|
|
},
|
|
|
|
/**
|
|
* Creates the WebGL Texture2D objects and Framebuffers required for this
|
|
* mask. If this mask has already been created, then `clearMask` is called first.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#createMask
|
|
* @since 3.50.0
|
|
*/
|
|
createMask: function ()
|
|
{
|
|
var renderer = this.renderer;
|
|
|
|
if (!renderer.gl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this.mainTexture)
|
|
{
|
|
this.clearMask();
|
|
}
|
|
|
|
var width = renderer.width;
|
|
var height = renderer.height;
|
|
var pot = ((width & (width - 1)) === 0 && (height & (height - 1)) === 0);
|
|
var gl = renderer.gl;
|
|
var wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
|
var filter = gl.LINEAR;
|
|
|
|
this.mainTexture = renderer.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height);
|
|
this.maskTexture = renderer.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height);
|
|
this.mainFramebuffer = renderer.createFramebuffer(width, height, this.mainTexture, true);
|
|
this.maskFramebuffer = renderer.createFramebuffer(width, height, this.maskTexture, true);
|
|
},
|
|
|
|
/**
|
|
* Deletes the `mainTexture` and `maskTexture` WebGL Textures and deletes
|
|
* the `mainFramebuffer` and `maskFramebuffer` too, nulling all references.
|
|
*
|
|
* This is called when this mask is destroyed, or if you try to creat a new
|
|
* mask from this object when one is already set.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#clearMask
|
|
* @since 3.50.0
|
|
*/
|
|
clearMask: function ()
|
|
{
|
|
var renderer = this.renderer;
|
|
|
|
if (!renderer.gl || !this.mainTexture)
|
|
{
|
|
return;
|
|
}
|
|
|
|
renderer.deleteTexture(this.mainTexture);
|
|
renderer.deleteTexture(this.maskTexture);
|
|
renderer.deleteFramebuffer(this.mainFramebuffer);
|
|
renderer.deleteFramebuffer(this.maskFramebuffer);
|
|
|
|
this.mainTexture = null;
|
|
this.maskTexture = null;
|
|
this.mainFramebuffer = null;
|
|
this.maskFramebuffer = null;
|
|
},
|
|
|
|
/**
|
|
* Sets a new masking Game Object for the Bitmap Mask.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#setBitmap
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.GameObjects.GameObject} renderable - A renderable Game Object that uses a texture, such as a Sprite.
|
|
*/
|
|
setBitmap: function (renderable)
|
|
{
|
|
this.bitmapMask = renderable;
|
|
},
|
|
|
|
/**
|
|
* Prepares the WebGL Renderer to render a Game Object with this mask applied.
|
|
*
|
|
* This renders the masking Game Object to the mask framebuffer and switches to the main framebuffer so that the masked Game Object will be rendered to it instead of being rendered directly to the frame.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#preRenderWebGL
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to prepare.
|
|
* @param {Phaser.GameObjects.GameObject} maskedObject - The masked Game Object which will be drawn.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
|
|
*/
|
|
preRenderWebGL: function (renderer, maskedObject, camera)
|
|
{
|
|
renderer.pipelines.BITMAPMASK_PIPELINE.beginMask(this, maskedObject, camera);
|
|
},
|
|
|
|
/**
|
|
* Finalizes rendering of a masked Game Object.
|
|
*
|
|
* This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#postRenderWebGL
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to clean up.
|
|
*/
|
|
postRenderWebGL: function (renderer, camera)
|
|
{
|
|
renderer.pipelines.BITMAPMASK_PIPELINE.endMask(this, camera);
|
|
},
|
|
|
|
/**
|
|
* This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#preRenderCanvas
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
|
|
* @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
|
|
*/
|
|
preRenderCanvas: function ()
|
|
{
|
|
// NOOP
|
|
},
|
|
|
|
/**
|
|
* This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#postRenderCanvas
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
|
|
*/
|
|
postRenderCanvas: function ()
|
|
{
|
|
// NOOP
|
|
},
|
|
|
|
/**
|
|
* Destroys this BitmapMask and nulls any references it holds.
|
|
*
|
|
* Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
|
|
* so be sure to call `clearMask` on any Game Object using it, before destroying it.
|
|
*
|
|
* @method Phaser.Display.Masks.BitmapMask#destroy
|
|
* @since 3.7.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.clearMask();
|
|
|
|
this.bitmapMask = null;
|
|
this.prevFramebuffer = null;
|
|
this.renderer = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = BitmapMask;
|
|
|
|
|
|
/***/ }),
|
|
/* 306 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* @namespace Phaser.Core.Events
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
BLUR: __webpack_require__(307),
|
|
BOOT: __webpack_require__(308),
|
|
CONTEXT_LOST: __webpack_require__(309),
|
|
CONTEXT_RESTORED: __webpack_require__(310),
|
|
DESTROY: __webpack_require__(311),
|
|
FOCUS: __webpack_require__(312),
|
|
HIDDEN: __webpack_require__(313),
|
|
PAUSE: __webpack_require__(314),
|
|
POST_RENDER: __webpack_require__(315),
|
|
POST_STEP: __webpack_require__(316),
|
|
PRE_RENDER: __webpack_require__(317),
|
|
PRE_STEP: __webpack_require__(318),
|
|
READY: __webpack_require__(319),
|
|
RESUME: __webpack_require__(320),
|
|
STEP: __webpack_require__(321),
|
|
VISIBLE: __webpack_require__(322)
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 307 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Blur Event.
|
|
*
|
|
* This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded
|
|
* enters a blurred state. The blur event is raised when the window loses focus. This can happen if a user swaps
|
|
* tab, or if they simply remove focus from the browser to another app.
|
|
*
|
|
* @event Phaser.Core.Events#BLUR
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'blur';
|
|
|
|
|
|
/***/ }),
|
|
/* 308 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Boot Event.
|
|
*
|
|
* This event is dispatched when the Phaser Game instance has finished booting, but before it is ready to start running.
|
|
* The global systems use this event to know when to set themselves up, dispatching their own `ready` events as required.
|
|
*
|
|
* @event Phaser.Core.Events#BOOT
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'boot';
|
|
|
|
|
|
/***/ }),
|
|
/* 309 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Context Lost Event.
|
|
*
|
|
* This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Lost event from the browser.
|
|
*
|
|
* The partner event is `CONTEXT_RESTORED`.
|
|
*
|
|
* @event Phaser.Core.Events#CONTEXT_LOST
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'contextlost';
|
|
|
|
|
|
/***/ }),
|
|
/* 310 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Context Restored Event.
|
|
*
|
|
* This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Restored event from the browser.
|
|
*
|
|
* The partner event is `CONTEXT_LOST`.
|
|
*
|
|
* @event Phaser.Core.Events#CONTEXT_RESTORED
|
|
* @since 3.19.0
|
|
*/
|
|
module.exports = 'contextrestored';
|
|
|
|
|
|
/***/ }),
|
|
/* 311 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Destroy Event.
|
|
*
|
|
* This event is dispatched when the game instance has been told to destroy itself.
|
|
* Lots of internal systems listen to this event in order to clear themselves out.
|
|
* Custom plugins and game code should also do the same.
|
|
*
|
|
* @event Phaser.Core.Events#DESTROY
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'destroy';
|
|
|
|
|
|
/***/ }),
|
|
/* 312 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Focus Event.
|
|
*
|
|
* This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded
|
|
* enters a focused state. The focus event is raised when the window re-gains focus, having previously lost it.
|
|
*
|
|
* @event Phaser.Core.Events#FOCUS
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'focus';
|
|
|
|
|
|
/***/ }),
|
|
/* 313 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Hidden Event.
|
|
*
|
|
* This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded
|
|
* enters a hidden state. Only browsers that support the Visibility API will cause this event to be emitted.
|
|
*
|
|
* In most modern browsers, when the document enters a hidden state, the Request Animation Frame and setTimeout, which
|
|
* control the main game loop, will automatically pause. There is no way to stop this from happening. It is something
|
|
* your game should account for in its own code, should the pause be an issue (i.e. for multiplayer games)
|
|
*
|
|
* @event Phaser.Core.Events#HIDDEN
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'hidden';
|
|
|
|
|
|
/***/ }),
|
|
/* 314 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Pause Event.
|
|
*
|
|
* This event is dispatched when the Game loop enters a paused state, usually as a result of the Visibility Handler.
|
|
*
|
|
* @event Phaser.Core.Events#PAUSE
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'pause';
|
|
|
|
|
|
/***/ }),
|
|
/* 315 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Post-Render Event.
|
|
*
|
|
* This event is dispatched right at the end of the render process.
|
|
*
|
|
* Every Scene will have rendered and been drawn to the canvas by the time this event is fired.
|
|
* Use it for any last minute post-processing before the next game step begins.
|
|
*
|
|
* @event Phaser.Core.Events#POST_RENDER
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance.
|
|
*/
|
|
module.exports = 'postrender';
|
|
|
|
|
|
/***/ }),
|
|
/* 316 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Post-Step Event.
|
|
*
|
|
* This event is dispatched after the Scene Manager has updated.
|
|
* Hook into it from plugins or systems that need to do things before the render starts.
|
|
*
|
|
* @event Phaser.Core.Events#POST_STEP
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'poststep';
|
|
|
|
|
|
/***/ }),
|
|
/* 317 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Pre-Render Event.
|
|
*
|
|
* This event is dispatched immediately before any of the Scenes have started to render.
|
|
*
|
|
* The renderer will already have been initialized this frame, clearing itself and preparing to receive the Scenes for rendering, but it won't have actually drawn anything yet.
|
|
*
|
|
* @event Phaser.Core.Events#PRE_RENDER
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance.
|
|
*/
|
|
module.exports = 'prerender';
|
|
|
|
|
|
/***/ }),
|
|
/* 318 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Pre-Step Event.
|
|
*
|
|
* This event is dispatched before the main Game Step starts. By this point in the game cycle none of the Scene updates have yet happened.
|
|
* Hook into it from plugins or systems that need to update before the Scene Manager does.
|
|
*
|
|
* @event Phaser.Core.Events#PRE_STEP
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'prestep';
|
|
|
|
|
|
/***/ }),
|
|
/* 319 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Ready Event.
|
|
*
|
|
* This event is dispatched when the Phaser Game instance has finished booting, the Texture Manager is fully ready,
|
|
* and all local systems are now able to start.
|
|
*
|
|
* @event Phaser.Core.Events#READY
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'ready';
|
|
|
|
|
|
/***/ }),
|
|
/* 320 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Resume Event.
|
|
*
|
|
* This event is dispatched when the game loop leaves a paused state and resumes running.
|
|
*
|
|
* @event Phaser.Core.Events#RESUME
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'resume';
|
|
|
|
|
|
/***/ }),
|
|
/* 321 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Step Event.
|
|
*
|
|
* This event is dispatched after the Game Pre-Step and before the Scene Manager steps.
|
|
* Hook into it from plugins or systems that need to update before the Scene Manager does, but after the core Systems have.
|
|
*
|
|
* @event Phaser.Core.Events#STEP
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
|
*/
|
|
module.exports = 'step';
|
|
|
|
|
|
/***/ }),
|
|
/* 322 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* The Game Visible Event.
|
|
*
|
|
* This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded
|
|
* enters a visible state, previously having been hidden.
|
|
*
|
|
* Only browsers that support the Visibility API will cause this event to be emitted.
|
|
*
|
|
* @event Phaser.Core.Events#VISIBLE
|
|
* @since 3.0.0
|
|
*/
|
|
module.exports = 'visible';
|
|
|
|
|
|
/***/ }),
|
|
/* 323 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Class = __webpack_require__(0);
|
|
|
|
/**
|
|
* @classdesc
|
|
* A Geometry Mask can be applied to a Game Object to hide any pixels of it which don't intersect
|
|
* a visible pixel from the geometry mask. The mask is essentially a clipping path which can only
|
|
* make a masked pixel fully visible or fully invisible without changing its alpha (opacity).
|
|
*
|
|
* A Geometry Mask uses a Graphics Game Object to determine which pixels of the masked Game Object(s)
|
|
* should be clipped. For any given point of a masked Game Object's texture, the pixel will only be displayed
|
|
* if the Graphics Game Object of the Geometry Mask has a visible pixel at the same position. The color and
|
|
* alpha of the pixel from the Geometry Mask do not matter.
|
|
*
|
|
* The Geometry Mask's location matches the location of its Graphics object, not the location of the masked objects.
|
|
* Moving or transforming the underlying Graphics object will change the mask (and affect the visibility
|
|
* of any masked objects), whereas moving or transforming a masked object will not affect the mask.
|
|
* You can think of the Geometry Mask (or rather, of its Graphics object) as an invisible curtain placed
|
|
* in front of all masked objects which has its own visual properties and, naturally, respects the camera's
|
|
* visual properties, but isn't affected by and doesn't follow the masked objects by itself.
|
|
*
|
|
* @class GeometryMask
|
|
* @memberof Phaser.Display.Masks
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scene} scene - This parameter is not used.
|
|
* @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics Game Object to use for the Geometry Mask. Doesn't have to be in the Display List.
|
|
*/
|
|
var GeometryMask = new Class({
|
|
|
|
initialize:
|
|
|
|
function GeometryMask (scene, graphicsGeometry)
|
|
{
|
|
/**
|
|
* The Graphics object which describes the Geometry Mask.
|
|
*
|
|
* @name Phaser.Display.Masks.GeometryMask#geometryMask
|
|
* @type {Phaser.GameObjects.Graphics}
|
|
* @since 3.0.0
|
|
*/
|
|
this.geometryMask = graphicsGeometry;
|
|
|
|
/**
|
|
* Similar to the BitmapMasks invertAlpha setting this to true will then hide all pixels
|
|
* drawn to the Geometry Mask.
|
|
*
|
|
* @name Phaser.Display.Masks.GeometryMask#invertAlpha
|
|
* @type {boolean}
|
|
* @since 3.16.0
|
|
*/
|
|
this.invertAlpha = false;
|
|
|
|
/**
|
|
* Is this mask a stencil mask?
|
|
*
|
|
* @name Phaser.Display.Masks.GeometryMask#isStencil
|
|
* @type {boolean}
|
|
* @readonly
|
|
* @since 3.17.0
|
|
*/
|
|
this.isStencil = true;
|
|
|
|
/**
|
|
* The current stencil level.
|
|
*
|
|
* @name Phaser.Display.Masks.GeometryMask#level
|
|
* @type {boolean}
|
|
* @private
|
|
* @since 3.17.0
|
|
*/
|
|
this.level = 0;
|
|
},
|
|
|
|
/**
|
|
* Sets a new Graphics object for the Geometry Mask.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#setShape
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics object which will be used for the Geometry Mask.
|
|
*
|
|
* @return {this} This Geometry Mask
|
|
*/
|
|
setShape: function (graphicsGeometry)
|
|
{
|
|
this.geometryMask = graphicsGeometry;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the `invertAlpha` property of this Geometry Mask.
|
|
* Inverting the alpha essentially flips the way the mask works.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#setInvertAlpha
|
|
* @since 3.17.0
|
|
*
|
|
* @param {boolean} [value=true] - Invert the alpha of this mask?
|
|
*
|
|
* @return {this} This Geometry Mask
|
|
*/
|
|
setInvertAlpha: function (value)
|
|
{
|
|
if (value === undefined) { value = true; }
|
|
|
|
this.invertAlpha = value;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Renders the Geometry Mask's underlying Graphics object to the OpenGL stencil buffer and enables the stencil test, which clips rendered pixels according to the mask.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#preRenderWebGL
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
|
|
* @param {Phaser.GameObjects.GameObject} child - The Game Object being rendered.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
|
|
*/
|
|
preRenderWebGL: function (renderer, child, camera)
|
|
{
|
|
var gl = renderer.gl;
|
|
|
|
// Force flushing before drawing to stencil buffer
|
|
renderer.flush();
|
|
|
|
if (renderer.maskStack.length === 0)
|
|
{
|
|
gl.enable(gl.STENCIL_TEST);
|
|
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
|
|
renderer.maskCount = 0;
|
|
}
|
|
|
|
if (renderer.currentCameraMask.mask !== this)
|
|
{
|
|
renderer.currentMask.mask = this;
|
|
}
|
|
|
|
renderer.maskStack.push({ mask: this, camera: camera });
|
|
|
|
this.applyStencil(renderer, camera, true);
|
|
|
|
renderer.maskCount++;
|
|
},
|
|
|
|
/**
|
|
* Applies the current stencil mask to the renderer.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#applyStencil
|
|
* @since 3.17.0
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
|
|
* @param {boolean} inc - Is this an INCR stencil or a DECR stencil?
|
|
*/
|
|
applyStencil: function (renderer, camera, inc)
|
|
{
|
|
var gl = renderer.gl;
|
|
var geometryMask = this.geometryMask;
|
|
var level = renderer.maskCount;
|
|
|
|
gl.colorMask(false, false, false, false);
|
|
|
|
if (inc)
|
|
{
|
|
gl.stencilFunc(gl.EQUAL, level, 0xFF);
|
|
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
|
|
}
|
|
else
|
|
{
|
|
gl.stencilFunc(gl.EQUAL, level + 1, 0xFF);
|
|
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
|
|
}
|
|
|
|
// Write stencil buffer
|
|
geometryMask.renderWebGL(renderer, geometryMask, camera);
|
|
|
|
renderer.flush();
|
|
|
|
gl.colorMask(true, true, true, true);
|
|
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
|
|
if (inc)
|
|
{
|
|
if (this.invertAlpha)
|
|
{
|
|
gl.stencilFunc(gl.NOTEQUAL, level + 1, 0xFF);
|
|
}
|
|
else
|
|
{
|
|
gl.stencilFunc(gl.EQUAL, level + 1, 0xFF);
|
|
}
|
|
}
|
|
else if (this.invertAlpha)
|
|
{
|
|
gl.stencilFunc(gl.NOTEQUAL, level, 0xFF);
|
|
}
|
|
else
|
|
{
|
|
gl.stencilFunc(gl.EQUAL, level, 0xFF);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Flushes all rendered pixels and disables the stencil test of a WebGL context, thus disabling the mask for it.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#postRenderWebGL
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw flush.
|
|
*/
|
|
postRenderWebGL: function (renderer)
|
|
{
|
|
var gl = renderer.gl;
|
|
|
|
renderer.maskStack.pop();
|
|
|
|
renderer.maskCount--;
|
|
|
|
if (renderer.maskStack.length === 0)
|
|
{
|
|
// If this is the only mask in the stack, flush and disable
|
|
renderer.flush();
|
|
|
|
renderer.currentMask.mask = null;
|
|
|
|
gl.disable(gl.STENCIL_TEST);
|
|
}
|
|
else
|
|
{
|
|
// Force flush before disabling stencil test
|
|
renderer.flush();
|
|
|
|
var prev = renderer.maskStack[renderer.maskStack.length - 1];
|
|
|
|
prev.mask.applyStencil(renderer, prev.camera, false);
|
|
|
|
if (renderer.currentCameraMask.mask !== prev.mask)
|
|
{
|
|
renderer.currentMask.mask = prev.mask;
|
|
renderer.currentMask.camera = prev.camera;
|
|
}
|
|
else
|
|
{
|
|
renderer.currentMask.mask = null;
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sets the clipping path of a 2D canvas context to the Geometry Mask's underlying Graphics object.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#preRenderCanvas
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance to set the clipping path on.
|
|
* @param {Phaser.GameObjects.GameObject} mask - The Game Object being rendered.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
|
|
*/
|
|
preRenderCanvas: function (renderer, mask, camera)
|
|
{
|
|
var geometryMask = this.geometryMask;
|
|
|
|
renderer.currentContext.save();
|
|
|
|
geometryMask.renderCanvas(renderer, geometryMask, camera, null, null, true);
|
|
|
|
renderer.currentContext.clip();
|
|
},
|
|
|
|
/**
|
|
* Restore the canvas context's previous clipping path, thus turning off the mask for it.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#postRenderCanvas
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance being restored.
|
|
*/
|
|
postRenderCanvas: function (renderer)
|
|
{
|
|
renderer.currentContext.restore();
|
|
},
|
|
|
|
/**
|
|
* Destroys this GeometryMask and nulls any references it holds.
|
|
*
|
|
* Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
|
|
* so be sure to call `clearMask` on any Game Object using it, before destroying it.
|
|
*
|
|
* @method Phaser.Display.Masks.GeometryMask#destroy
|
|
* @since 3.7.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.geometryMask = null;
|
|
}
|
|
|
|
});
|
|
|
|
module.exports = GeometryMask;
|
|
|
|
|
|
/***/ }),
|
|
/* 324 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the origin of a Game Object.
|
|
* Values are normalized, given in the range 0 to 1.
|
|
* Display values contain the calculated pixel values.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Origin
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Origin = {
|
|
|
|
/**
|
|
* A property indicating that a Game Object has this component.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Origin#_originComponent
|
|
* @type {boolean}
|
|
* @private
|
|
* @default true
|
|
* @since 3.2.0
|
|
*/
|
|
_originComponent: true,
|
|
|
|
/**
|
|
* The horizontal origin of this Game Object.
|
|
* The origin maps the relationship between the size and position of the Game Object.
|
|
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
|
|
* Setting the value to 0 means the position now relates to the left of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Origin#originX
|
|
* @type {number}
|
|
* @default 0.5
|
|
* @since 3.0.0
|
|
*/
|
|
originX: 0.5,
|
|
|
|
/**
|
|
* The vertical origin of this Game Object.
|
|
* The origin maps the relationship between the size and position of the Game Object.
|
|
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
|
|
* Setting the value to 0 means the position now relates to the top of the Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Origin#originY
|
|
* @type {number}
|
|
* @default 0.5
|
|
* @since 3.0.0
|
|
*/
|
|
originY: 0.5,
|
|
|
|
// private + read only
|
|
_displayOriginX: 0,
|
|
_displayOriginY: 0,
|
|
|
|
/**
|
|
* The horizontal display origin of this Game Object.
|
|
* The origin is a normalized value between 0 and 1.
|
|
* The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Origin#displayOriginX
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayOriginX: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._displayOriginX;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._displayOriginX = value;
|
|
this.originX = value / this.width;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The vertical display origin of this Game Object.
|
|
* The origin is a normalized value between 0 and 1.
|
|
* The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Origin#displayOriginY
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayOriginY: {
|
|
|
|
get: function ()
|
|
{
|
|
return this._displayOriginY;
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this._displayOriginY = value;
|
|
this.originY = value / this.height;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the origin of this Game Object.
|
|
*
|
|
* The values are given in the range 0 to 1.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Origin#setOrigin
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0.5] - The horizontal origin value.
|
|
* @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setOrigin: function (x, y)
|
|
{
|
|
if (x === undefined) { x = 0.5; }
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.originX = x;
|
|
this.originY = y;
|
|
|
|
return this.updateDisplayOrigin();
|
|
},
|
|
|
|
/**
|
|
* Sets the origin of this Game Object based on the Pivot values in its Frame.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Origin#setOriginFromFrame
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setOriginFromFrame: function ()
|
|
{
|
|
if (!this.frame || !this.frame.customPivot)
|
|
{
|
|
return this.setOrigin();
|
|
}
|
|
else
|
|
{
|
|
this.originX = this.frame.pivotX;
|
|
this.originY = this.frame.pivotY;
|
|
}
|
|
|
|
return this.updateDisplayOrigin();
|
|
},
|
|
|
|
/**
|
|
* Sets the display origin of this Game Object.
|
|
* The difference between this and setting the origin is that you can use pixel values for setting the display origin.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Origin#setDisplayOrigin
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} [x=0] - The horizontal display origin value.
|
|
* @param {number} [y=x] - The vertical display origin value. If not defined it will be set to the value of `x`.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setDisplayOrigin: function (x, y)
|
|
{
|
|
if (x === undefined) { x = 0; }
|
|
if (y === undefined) { y = x; }
|
|
|
|
this.displayOriginX = x;
|
|
this.displayOriginY = y;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Updates the Display Origin cached values internally stored on this Game Object.
|
|
* You don't usually call this directly, but it is exposed for edge-cases where you may.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Origin#updateDisplayOrigin
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
updateDisplayOrigin: function ()
|
|
{
|
|
this._displayOriginX = this.originX * this.width;
|
|
this._displayOriginY = this.originY * this.height;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Origin;
|
|
|
|
|
|
/***/ }),
|
|
/* 325 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var DegToRad = __webpack_require__(19);
|
|
var GetBoolean = __webpack_require__(326);
|
|
var GetValue = __webpack_require__(10);
|
|
var TWEEN_CONST = __webpack_require__(327);
|
|
var Vector2 = __webpack_require__(2);
|
|
|
|
/**
|
|
* Provides methods used for managing a Game Object following a Path.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.PathFollower
|
|
* @since 3.17.0
|
|
*/
|
|
|
|
var PathFollower = {
|
|
|
|
/**
|
|
* The Path this PathFollower is following. It can only follow one Path at a time.
|
|
*
|
|
* @name Phaser.GameObjects.Components.PathFollower#path
|
|
* @type {Phaser.Curves.Path}
|
|
* @since 3.0.0
|
|
*/
|
|
path: null,
|
|
|
|
/**
|
|
* Should the PathFollower automatically rotate to point in the direction of the Path?
|
|
*
|
|
* @name Phaser.GameObjects.Components.PathFollower#rotateToPath
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.0.0
|
|
*/
|
|
rotateToPath: false,
|
|
|
|
/**
|
|
* If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath)
|
|
* this value is added to the rotation value. This allows you to rotate objects to a path but control
|
|
* the angle of the rotation as well.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathRotationOffset
|
|
* @type {number}
|
|
* @default 0
|
|
* @since 3.0.0
|
|
*/
|
|
pathRotationOffset: 0,
|
|
|
|
/**
|
|
* An additional vector to add to the PathFollowers position, allowing you to offset it from the
|
|
* Path coordinates.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathOffset
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.0.0
|
|
*/
|
|
pathOffset: null,
|
|
|
|
/**
|
|
* A Vector2 that stores the current point of the path the follower is on.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathVector
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.0.0
|
|
*/
|
|
pathVector: null,
|
|
|
|
/**
|
|
* The distance the follower has traveled from the previous point to the current one, at the last update.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathDelta
|
|
* @type {Phaser.Math.Vector2}
|
|
* @since 3.23.0
|
|
*/
|
|
pathDelta: null,
|
|
|
|
/**
|
|
* The Tween used for following the Path.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathTween
|
|
* @type {Phaser.Tweens.Tween}
|
|
* @since 3.0.0
|
|
*/
|
|
pathTween: null,
|
|
|
|
/**
|
|
* Settings for the PathFollower.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#pathConfig
|
|
* @type {?Phaser.Types.GameObjects.PathFollower.PathConfig}
|
|
* @default null
|
|
* @since 3.0.0
|
|
*/
|
|
pathConfig: null,
|
|
|
|
/**
|
|
* Records the direction of the follower so it can change direction.
|
|
*
|
|
* @name Phaser.GameObjects.PathFollower#_prevDirection
|
|
* @type {integer}
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
_prevDirection: TWEEN_CONST.PLAYING_FORWARD,
|
|
|
|
/**
|
|
* Set the Path that this PathFollower should follow.
|
|
*
|
|
* Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#setPath
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time.
|
|
* @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config] - Settings for the PathFollower.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setPath: function (path, config)
|
|
{
|
|
if (config === undefined) { config = this.pathConfig; }
|
|
|
|
var tween = this.pathTween;
|
|
|
|
if (tween && tween.isPlaying())
|
|
{
|
|
tween.stop();
|
|
}
|
|
|
|
this.path = path;
|
|
|
|
if (config)
|
|
{
|
|
this.startFollow(config);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Set whether the PathFollower should automatically rotate to point in the direction of the Path.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#setRotateToPath
|
|
* @since 3.0.0
|
|
*
|
|
* @param {boolean} value - Whether the PathFollower should automatically rotate to point in the direction of the Path.
|
|
* @param {number} [offset=0] - Rotation offset in degrees.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
setRotateToPath: function (value, offset)
|
|
{
|
|
if (offset === undefined) { offset = 0; }
|
|
|
|
this.rotateToPath = value;
|
|
|
|
this.pathRotationOffset = offset;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Is this PathFollower actively following a Path or not?
|
|
*
|
|
* To be considered as `isFollowing` it must be currently moving on a Path, and not paused.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#isFollowing
|
|
* @since 3.0.0
|
|
*
|
|
* @return {boolean} `true` is this PathFollower is actively following a Path, otherwise `false`.
|
|
*/
|
|
isFollowing: function ()
|
|
{
|
|
var tween = this.pathTween;
|
|
|
|
return (tween && tween.isPlaying());
|
|
},
|
|
|
|
/**
|
|
* Starts this PathFollower following its given Path.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#startFollow
|
|
* @since 3.3.0
|
|
*
|
|
* @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config={}] - The duration of the follow, or a PathFollower config object.
|
|
* @param {number} [startAt=0] - Optional start position of the follow, between 0 and 1.
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
startFollow: function (config, startAt)
|
|
{
|
|
if (config === undefined) { config = {}; }
|
|
if (startAt === undefined) { startAt = 0; }
|
|
|
|
var tween = this.pathTween;
|
|
|
|
if (tween && tween.isPlaying())
|
|
{
|
|
tween.stop();
|
|
}
|
|
|
|
if (typeof config === 'number')
|
|
{
|
|
config = { duration: config };
|
|
}
|
|
|
|
// Override in case they've been specified in the config
|
|
config.from = GetValue(config, 'from', 0);
|
|
config.to = GetValue(config, 'to', 1);
|
|
|
|
var positionOnPath = GetBoolean(config, 'positionOnPath', false);
|
|
|
|
this.rotateToPath = GetBoolean(config, 'rotateToPath', false);
|
|
this.pathRotationOffset = GetValue(config, 'rotationOffset', 0);
|
|
|
|
// This works, but it's not an ideal way of doing it as the follower jumps position
|
|
var seek = GetValue(config, 'startAt', startAt);
|
|
|
|
if (seek)
|
|
{
|
|
config.onStart = function (tween)
|
|
{
|
|
var tweenData = tween.data[0];
|
|
tweenData.progress = seek;
|
|
tweenData.elapsed = tweenData.duration * seek;
|
|
var v = tweenData.ease(tweenData.progress);
|
|
tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v);
|
|
tweenData.target[tweenData.key] = tweenData.current;
|
|
};
|
|
}
|
|
|
|
if (!this.pathOffset)
|
|
{
|
|
this.pathOffset = new Vector2(this.x, this.y);
|
|
}
|
|
|
|
if (!this.pathVector)
|
|
{
|
|
this.pathVector = new Vector2();
|
|
}
|
|
|
|
if (!this.pathDelta)
|
|
{
|
|
this.pathDelta = new Vector2();
|
|
}
|
|
|
|
this.pathDelta.reset();
|
|
|
|
this.pathTween = this.scene.sys.tweens.addCounter(config);
|
|
|
|
// The starting point of the path, relative to this follower
|
|
this.path.getStartPoint(this.pathOffset);
|
|
|
|
if (positionOnPath)
|
|
{
|
|
this.x = this.pathOffset.x;
|
|
this.y = this.pathOffset.y;
|
|
}
|
|
|
|
this.pathOffset.x = this.x - this.pathOffset.x;
|
|
this.pathOffset.y = this.y - this.pathOffset.y;
|
|
|
|
this._prevDirection = TWEEN_CONST.PLAYING_FORWARD;
|
|
|
|
if (this.rotateToPath)
|
|
{
|
|
// Set the rotation now (in case the tween has a delay on it, etc)
|
|
var nextPoint = this.path.getPoint(0.1);
|
|
|
|
this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset);
|
|
}
|
|
|
|
this.pathConfig = config;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Pauses this PathFollower. It will still continue to render, but it will remain motionless at the
|
|
* point on the Path at which you paused it.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#pauseFollow
|
|
* @since 3.3.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
pauseFollow: function ()
|
|
{
|
|
var tween = this.pathTween;
|
|
|
|
if (tween && tween.isPlaying())
|
|
{
|
|
tween.pause();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Resumes a previously paused PathFollower.
|
|
*
|
|
* If the PathFollower was not paused this has no effect.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#resumeFollow
|
|
* @since 3.3.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
resumeFollow: function ()
|
|
{
|
|
var tween = this.pathTween;
|
|
|
|
if (tween && tween.isPaused())
|
|
{
|
|
tween.resume();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Stops this PathFollower from following the path any longer.
|
|
*
|
|
* This will invoke any 'stop' conditions that may exist on the Path, or for the follower.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#stopFollow
|
|
* @since 3.3.0
|
|
*
|
|
* @return {this} This Game Object.
|
|
*/
|
|
stopFollow: function ()
|
|
{
|
|
var tween = this.pathTween;
|
|
|
|
if (tween && tween.isPlaying())
|
|
{
|
|
tween.stop();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Internal update handler that advances this PathFollower along the path.
|
|
*
|
|
* Called automatically by the Scene step, should not typically be called directly.
|
|
*
|
|
* @method Phaser.GameObjects.Components.PathFollower#pathUpdate
|
|
* @since 3.17.0
|
|
*/
|
|
pathUpdate: function ()
|
|
{
|
|
var tween = this.pathTween;
|
|
|
|
if (tween)
|
|
{
|
|
var tweenData = tween.data[0];
|
|
var pathDelta = this.pathDelta;
|
|
var pathVector = this.pathVector;
|
|
|
|
pathDelta.copy(pathVector).negate();
|
|
|
|
if (tweenData.state === TWEEN_CONST.COMPLETE)
|
|
{
|
|
this.path.getPoint(1, pathVector);
|
|
|
|
pathDelta.add(pathVector);
|
|
pathVector.add(this.pathOffset);
|
|
|
|
this.setPosition(pathVector.x, pathVector.y);
|
|
|
|
return;
|
|
}
|
|
else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD)
|
|
{
|
|
// If delayed, etc then bail out
|
|
return;
|
|
}
|
|
|
|
this.path.getPoint(tween.getValue(), pathVector);
|
|
|
|
pathDelta.add(pathVector);
|
|
pathVector.add(this.pathOffset);
|
|
|
|
var oldX = this.x;
|
|
var oldY = this.y;
|
|
|
|
this.setPosition(pathVector.x, pathVector.y);
|
|
|
|
var speedX = this.x - oldX;
|
|
var speedY = this.y - oldY;
|
|
|
|
if (speedX === 0 && speedY === 0)
|
|
{
|
|
// Bail out early
|
|
return;
|
|
}
|
|
|
|
if (tweenData.state !== this._prevDirection)
|
|
{
|
|
// We've changed direction, so don't do a rotate this frame
|
|
this._prevDirection = tweenData.state;
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.rotateToPath)
|
|
{
|
|
this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = PathFollower;
|
|
|
|
|
|
/***/ }),
|
|
/* 326 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Retrieves the value of the given key from an object.
|
|
*
|
|
* @function Phaser.Tweens.Builders.GetBoolean
|
|
* @since 3.0.0
|
|
*
|
|
* @param {object} source - The object to retrieve the value from.
|
|
* @param {string} key - The key to look for in the `source` object.
|
|
* @param {*} defaultValue - The default value to return if the `key` doesn't exist or if no `source` object is provided.
|
|
*
|
|
* @return {*} The retrieved value.
|
|
*/
|
|
var GetBoolean = function (source, key, defaultValue)
|
|
{
|
|
if (!source)
|
|
{
|
|
return defaultValue;
|
|
}
|
|
else if (source.hasOwnProperty(key))
|
|
{
|
|
return source[key];
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
};
|
|
|
|
module.exports = GetBoolean;
|
|
|
|
|
|
/***/ }),
|
|
/* 327 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var TWEEN_CONST = {
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.CREATED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
CREATED: 0,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.INIT
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
INIT: 1,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
DELAY: 2,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.OFFSET_DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
OFFSET_DELAY: 3,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.PENDING_RENDER
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PENDING_RENDER: 4,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.PLAYING_FORWARD
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PLAYING_FORWARD: 5,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.PLAYING_BACKWARD
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PLAYING_BACKWARD: 6,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.HOLD_DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
HOLD_DELAY: 7,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.REPEAT_DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
REPEAT_DELAY: 8,
|
|
|
|
/**
|
|
* TweenData state.
|
|
*
|
|
* @name Phaser.Tweens.COMPLETE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
COMPLETE: 9,
|
|
|
|
// Tween specific (starts from 20 to cleanly allow extra TweenData consts in the future)
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.PENDING_ADD
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PENDING_ADD: 20,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.PAUSED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PAUSED: 21,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.LOOP_DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
LOOP_DELAY: 22,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.ACTIVE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
ACTIVE: 23,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.COMPLETE_DELAY
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
COMPLETE_DELAY: 24,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.PENDING_REMOVE
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
PENDING_REMOVE: 25,
|
|
|
|
/**
|
|
* Tween state.
|
|
*
|
|
* @name Phaser.Tweens.REMOVED
|
|
* @type {integer}
|
|
* @since 3.0.0
|
|
*/
|
|
REMOVED: 26
|
|
|
|
};
|
|
|
|
module.exports = TWEEN_CONST;
|
|
|
|
|
|
/***/ }),
|
|
/* 328 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var PIPELINE_CONST = __webpack_require__(329);
|
|
|
|
/**
|
|
* Provides methods used for setting the WebGL rendering pipeline of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Pipeline
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Pipeline = {
|
|
|
|
/**
|
|
* The initial WebGL pipeline of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Pipeline#defaultPipeline
|
|
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
|
|
* @default null
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
defaultPipeline: null,
|
|
|
|
/**
|
|
* The current WebGL pipeline of this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Pipeline#pipeline
|
|
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
|
|
* @default null
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
pipeline: null,
|
|
|
|
/**
|
|
* Sets the initial WebGL Pipeline of this Game Object.
|
|
*
|
|
* This should only be called during the instantiation of the Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Pipeline#initPipeline
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} [name=MultiPipeline] - The name of the pipeline to set on this Game Object. Defaults to the Multi Pipeline.
|
|
*
|
|
* @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
|
|
*/
|
|
initPipeline: function (name)
|
|
{
|
|
if (name === undefined) { name = PIPELINE_CONST.MULTI_PIPELINE; }
|
|
|
|
var renderer = this.scene.sys.game.renderer;
|
|
var pipelines = renderer.pipelines;
|
|
|
|
if (pipelines && pipelines.has(name))
|
|
{
|
|
this.defaultPipeline = pipelines.get(name);
|
|
this.pipeline = this.defaultPipeline;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* Sets the active WebGL Pipeline of this Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Pipeline#setPipeline
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} name - The name of the pipeline to set on this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setPipeline: function (name)
|
|
{
|
|
var renderer = this.scene.sys.game.renderer;
|
|
var pipelines = renderer.pipelines;
|
|
|
|
if (pipelines && pipelines.has(name))
|
|
{
|
|
this.pipeline = pipelines.get(name);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Resets the WebGL Pipeline of this Game Object back to the default it was created with.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Pipeline#resetPipeline
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
|
|
*/
|
|
resetPipeline: function ()
|
|
{
|
|
this.pipeline = this.defaultPipeline;
|
|
|
|
return (this.pipeline !== null);
|
|
},
|
|
|
|
/**
|
|
* Gets the name of the WebGL Pipeline this Game Object is currently using.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Pipeline#getPipelineName
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @return {string} The string-based name of the pipeline being used by this Game Object.
|
|
*/
|
|
getPipelineName: function ()
|
|
{
|
|
return this.pipeline.name;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Pipeline;
|
|
|
|
|
|
/***/ }),
|
|
/* 329 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var PIPELINE_CONST = {
|
|
|
|
/**
|
|
* The Bitmap Mask Pipeline.
|
|
*
|
|
* @name Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE
|
|
* @type {string}
|
|
* @const
|
|
* @since 3.50.0
|
|
*/
|
|
BITMAPMASK_PIPELINE: 'BitmapMaskPipeline',
|
|
|
|
/**
|
|
* The Light 2D Pipeline.
|
|
*
|
|
* @name Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE
|
|
* @type {string}
|
|
* @const
|
|
* @since 3.50.0
|
|
*/
|
|
LIGHT_PIPELINE: 'Light2D',
|
|
|
|
/**
|
|
* The Single Texture Pipeline.
|
|
*
|
|
* @name Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE
|
|
* @type {string}
|
|
* @const
|
|
* @since 3.50.0
|
|
*/
|
|
SINGLE_PIPELINE: 'SinglePipeline',
|
|
|
|
/**
|
|
* The Multi Texture Pipeline.
|
|
*
|
|
* @name Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE
|
|
* @type {string}
|
|
* @const
|
|
* @since 3.50.0
|
|
*/
|
|
MULTI_PIPELINE: 'MultiPipeline',
|
|
|
|
/**
|
|
* The Rope Pipeline.
|
|
*
|
|
* @name Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE
|
|
* @type {string}
|
|
* @const
|
|
* @since 3.50.0
|
|
*/
|
|
ROPE_PIPELINE: 'RopePipeline'
|
|
|
|
};
|
|
|
|
module.exports = PIPELINE_CONST;
|
|
|
|
|
|
/***/ }),
|
|
/* 330 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the size of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Size
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Size = {
|
|
|
|
/**
|
|
* A property indicating that a Game Object has this component.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Size#_sizeComponent
|
|
* @type {boolean}
|
|
* @private
|
|
* @default true
|
|
* @since 3.2.0
|
|
*/
|
|
_sizeComponent: true,
|
|
|
|
/**
|
|
* The native (un-scaled) width of this Game Object.
|
|
*
|
|
* Changing this value will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or use
|
|
* the `displayWidth` property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Size#width
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
width: 0,
|
|
|
|
/**
|
|
* The native (un-scaled) height of this Game Object.
|
|
*
|
|
* Changing this value will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or use
|
|
* the `displayHeight` property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Size#height
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
height: 0,
|
|
|
|
/**
|
|
* The displayed width of this Game Object.
|
|
*
|
|
* This value takes into account the scale factor.
|
|
*
|
|
* Setting this value will adjust the Game Object's scale property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Size#displayWidth
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayWidth: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.abs(this.scaleX * this.frame.realWidth);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.scaleX = value / this.frame.realWidth;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* The displayed height of this Game Object.
|
|
*
|
|
* This value takes into account the scale factor.
|
|
*
|
|
* Setting this value will adjust the Game Object's scale property.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Size#displayHeight
|
|
* @type {number}
|
|
* @since 3.0.0
|
|
*/
|
|
displayHeight: {
|
|
|
|
get: function ()
|
|
{
|
|
return Math.abs(this.scaleY * this.frame.realHeight);
|
|
},
|
|
|
|
set: function (value)
|
|
{
|
|
this.scaleY = value / this.frame.realHeight;
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the size of this Game Object to be that of the given Frame.
|
|
*
|
|
* This will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or call the
|
|
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
|
|
* to do so by giving pixel values.
|
|
*
|
|
* If you have enabled this Game Object for input, changing the size will _not_ change the
|
|
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Size#setSizeToFrame
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Textures.Frame} frame - The frame to base the size of this Game Object on.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setSizeToFrame: function (frame)
|
|
{
|
|
if (frame === undefined) { frame = this.frame; }
|
|
|
|
this.width = frame.realWidth;
|
|
this.height = frame.realHeight;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the internal size of this Game Object, as used for frame or physics body creation.
|
|
*
|
|
* This will not change the size that the Game Object is rendered in-game.
|
|
* For that you need to either set the scale of the Game Object (`setScale`) or call the
|
|
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
|
|
* to do so by giving pixel values.
|
|
*
|
|
* If you have enabled this Game Object for input, changing the size will _not_ change the
|
|
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Size#setSize
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} width - The width of this Game Object.
|
|
* @param {number} height - The height of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setSize: function (width, height)
|
|
{
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the display size of this Game Object.
|
|
*
|
|
* Calling this will adjust the scale.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Size#setDisplaySize
|
|
* @since 3.0.0
|
|
*
|
|
* @param {number} width - The width of this Game Object.
|
|
* @param {number} height - The height of this Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setDisplaySize: function (width, height)
|
|
{
|
|
this.displayWidth = width;
|
|
this.displayHeight = height;
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Size;
|
|
|
|
|
|
/***/ }),
|
|
/* 331 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// bitmask flag for GameObject.renderMask
|
|
var _FLAG = 8; // 1000
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the texture of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Texture
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Texture = {
|
|
|
|
/**
|
|
* The Texture this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Texture#texture
|
|
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
|
|
* @since 3.0.0
|
|
*/
|
|
texture: null,
|
|
|
|
/**
|
|
* The Texture Frame this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Texture#frame
|
|
* @type {Phaser.Textures.Frame}
|
|
* @since 3.0.0
|
|
*/
|
|
frame: null,
|
|
|
|
/**
|
|
* Internal flag. Not to be set by this Game Object.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Texture#isCropped
|
|
* @type {boolean}
|
|
* @private
|
|
* @since 3.11.0
|
|
*/
|
|
isCropped: false,
|
|
|
|
/**
|
|
* Sets the texture and frame this Game Object will use to render with.
|
|
*
|
|
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Texture#setTexture
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|Phaser.Textures.Texture)} key - The key of the texture to be used, as stored in the Texture Manager, or a Texture instance.
|
|
* @param {(string|integer)} [frame] - The name or index of the frame within the Texture.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setTexture: function (key, frame)
|
|
{
|
|
this.texture = this.scene.sys.textures.get(key);
|
|
|
|
return this.setFrame(frame);
|
|
},
|
|
|
|
/**
|
|
* Sets the frame this Game Object will use to render with.
|
|
*
|
|
* The Frame has to belong to the current Texture being used.
|
|
*
|
|
* It can be either a string or an index.
|
|
*
|
|
* Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
|
|
* It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Texture#setFrame
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|integer)} frame - The name or index of the frame within the Texture.
|
|
* @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
|
|
* @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setFrame: function (frame, updateSize, updateOrigin)
|
|
{
|
|
if (updateSize === undefined) { updateSize = true; }
|
|
if (updateOrigin === undefined) { updateOrigin = true; }
|
|
|
|
this.frame = this.texture.get(frame);
|
|
|
|
if (!this.frame.cutWidth || !this.frame.cutHeight)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
|
|
if (this._sizeComponent && updateSize)
|
|
{
|
|
this.setSizeToFrame();
|
|
}
|
|
|
|
if (this._originComponent && updateOrigin)
|
|
{
|
|
if (this.frame.customPivot)
|
|
{
|
|
this.setOrigin(this.frame.pivotX, this.frame.pivotY);
|
|
}
|
|
else
|
|
{
|
|
this.updateDisplayOrigin();
|
|
}
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Texture;
|
|
|
|
|
|
/***/ }),
|
|
/* 332 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
// bitmask flag for GameObject.renderMask
|
|
var _FLAG = 8; // 1000
|
|
|
|
/**
|
|
* Provides methods used for getting and setting the texture of a Game Object.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.TextureCrop
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var TextureCrop = {
|
|
|
|
/**
|
|
* The Texture this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TextureCrop#texture
|
|
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
|
|
* @since 3.0.0
|
|
*/
|
|
texture: null,
|
|
|
|
/**
|
|
* The Texture Frame this Game Object is using to render with.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TextureCrop#frame
|
|
* @type {Phaser.Textures.Frame}
|
|
* @since 3.0.0
|
|
*/
|
|
frame: null,
|
|
|
|
/**
|
|
* A boolean flag indicating if this Game Object is being cropped or not.
|
|
* You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
|
|
* Equally, calling `setCrop` with no arguments will reset the crop and disable it.
|
|
*
|
|
* @name Phaser.GameObjects.Components.TextureCrop#isCropped
|
|
* @type {boolean}
|
|
* @since 3.11.0
|
|
*/
|
|
isCropped: false,
|
|
|
|
/**
|
|
* Applies a crop to a texture based Game Object, such as a Sprite or Image.
|
|
*
|
|
* The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
|
|
*
|
|
* Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
|
|
* changes what is shown when rendered.
|
|
*
|
|
* The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
|
|
*
|
|
* Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
|
|
* half of it, you could call `setCrop(0, 0, 400, 600)`.
|
|
*
|
|
* It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop
|
|
* an area of 200x100 when applied to a Game Object that had a scale factor of 2.
|
|
*
|
|
* You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
|
|
*
|
|
* Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
|
|
*
|
|
* You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
|
|
* the renderer to skip several internal calculations.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TextureCrop#setCrop
|
|
* @since 3.11.0
|
|
*
|
|
* @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
|
|
* @param {number} [y] - The y coordinate to start the crop from.
|
|
* @param {number} [width] - The width of the crop rectangle in pixels.
|
|
* @param {number} [height] - The height of the crop rectangle in pixels.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setCrop: function (x, y, width, height)
|
|
{
|
|
if (x === undefined)
|
|
{
|
|
this.isCropped = false;
|
|
}
|
|
else if (this.frame)
|
|
{
|
|
if (typeof x === 'number')
|
|
{
|
|
this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
|
|
}
|
|
else
|
|
{
|
|
var rect = x;
|
|
|
|
this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
|
|
}
|
|
|
|
this.isCropped = true;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the texture and frame this Game Object will use to render with.
|
|
*
|
|
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TextureCrop#setTexture
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
|
|
* @param {(string|integer)} [frame] - The name or index of the frame within the Texture.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setTexture: function (key, frame)
|
|
{
|
|
this.texture = this.scene.sys.textures.get(key);
|
|
|
|
return this.setFrame(frame);
|
|
},
|
|
|
|
/**
|
|
* Sets the frame this Game Object will use to render with.
|
|
*
|
|
* The Frame has to belong to the current Texture being used.
|
|
*
|
|
* It can be either a string or an index.
|
|
*
|
|
* Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
|
|
* It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TextureCrop#setFrame
|
|
* @since 3.0.0
|
|
*
|
|
* @param {(string|integer)} frame - The name or index of the frame within the Texture.
|
|
* @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
|
|
* @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setFrame: function (frame, updateSize, updateOrigin)
|
|
{
|
|
if (updateSize === undefined) { updateSize = true; }
|
|
if (updateOrigin === undefined) { updateOrigin = true; }
|
|
|
|
this.frame = this.texture.get(frame);
|
|
|
|
if (!this.frame.cutWidth || !this.frame.cutHeight)
|
|
{
|
|
this.renderFlags &= ~_FLAG;
|
|
}
|
|
else
|
|
{
|
|
this.renderFlags |= _FLAG;
|
|
}
|
|
|
|
if (this._sizeComponent && updateSize)
|
|
{
|
|
this.setSizeToFrame();
|
|
}
|
|
|
|
if (this._originComponent && updateOrigin)
|
|
{
|
|
if (this.frame.customPivot)
|
|
{
|
|
this.setOrigin(this.frame.pivotX, this.frame.pivotY);
|
|
}
|
|
else
|
|
{
|
|
this.updateDisplayOrigin();
|
|
}
|
|
}
|
|
|
|
if (this.isCropped)
|
|
{
|
|
this.frame.updateCropUVs(this._crop, this.flipX, this.flipY);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Internal method that returns a blank, well-formed crop object for use by a Game Object.
|
|
*
|
|
* @method Phaser.GameObjects.Components.TextureCrop#resetCropObject
|
|
* @private
|
|
* @since 3.12.0
|
|
*
|
|
* @return {object} The crop object.
|
|
*/
|
|
resetCropObject: function ()
|
|
{
|
|
return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = TextureCrop;
|
|
|
|
|
|
/***/ }),
|
|
/* 333 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Provides methods used for setting the tint of a Game Object.
|
|
* Should be applied as a mixin and not used directly.
|
|
*
|
|
* @namespace Phaser.GameObjects.Components.Tint
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
var Tint = {
|
|
|
|
/**
|
|
* The tint value being applied to the top-left vertice of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tintTopLeft
|
|
* @type {number}
|
|
* @default 0xffffff
|
|
* @since 3.0.0
|
|
*/
|
|
tintTopLeft: 0xffffff,
|
|
|
|
/**
|
|
* The tint value being applied to the top-right vertice of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tintTopRight
|
|
* @type {number}
|
|
* @default 0xffffff
|
|
* @since 3.0.0
|
|
*/
|
|
tintTopRight: 0xffffff,
|
|
|
|
/**
|
|
* The tint value being applied to the bottom-left vertice of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tintBottomLeft
|
|
* @type {number}
|
|
* @default 0xffffff
|
|
* @since 3.0.0
|
|
*/
|
|
tintBottomLeft: 0xffffff,
|
|
|
|
/**
|
|
* The tint value being applied to the bottom-right vertice of the Game Object.
|
|
* This value is interpolated from the corner to the center of the Game Object.
|
|
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tintBottomRight
|
|
* @type {number}
|
|
* @default 0xffffff
|
|
* @since 3.0.0
|
|
*/
|
|
tintBottomRight: 0xffffff,
|
|
|
|
/**
|
|
* The tint fill mode.
|
|
*
|
|
* `false` = An additive tint (the default), where vertices colors are blended with the texture.
|
|
* `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tintFill
|
|
* @type {boolean}
|
|
* @default false
|
|
* @since 3.11.0
|
|
*/
|
|
tintFill: false,
|
|
|
|
/**
|
|
* Clears all tint values associated with this Game Object.
|
|
*
|
|
* Immediately sets the color values back to 0xffffff and the tint type to 'additive',
|
|
* which results in no visible change to the texture.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Tint#clearTint
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
clearTint: function ()
|
|
{
|
|
this.setTint(0xffffff);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets an additive tint on this Game Object.
|
|
*
|
|
* The tint works by taking the pixel color values from the Game Objects texture, and then
|
|
* multiplying it by the color value of the tint. You can provide either one color value,
|
|
* in which case the whole Game Object will be tinted in that color. Or you can provide a color
|
|
* per corner. The colors are blended together across the extent of the Game Object.
|
|
*
|
|
* To modify the tint color once set, either call this method again with new values or use the
|
|
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
|
|
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
|
|
*
|
|
* To remove a tint call `clearTint`.
|
|
*
|
|
* To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Tint#setTint
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*
|
|
* @param {integer} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object.
|
|
* @param {integer} [topRight] - The tint being applied to the top-right of the Game Object.
|
|
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
|
|
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setTint: function (topLeft, topRight, bottomLeft, bottomRight)
|
|
{
|
|
if (topLeft === undefined) { topLeft = 0xffffff; }
|
|
|
|
if (topRight === undefined)
|
|
{
|
|
topRight = topLeft;
|
|
bottomLeft = topLeft;
|
|
bottomRight = topLeft;
|
|
}
|
|
|
|
this.tintTopLeft = topLeft;
|
|
this.tintTopRight = topRight;
|
|
this.tintBottomLeft = bottomLeft;
|
|
this.tintBottomRight = bottomRight;
|
|
|
|
this.tintFill = false;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets a fill-based tint on this Game Object.
|
|
*
|
|
* Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
|
|
* with those in the tint. You can use this for effects such as making a player flash 'white'
|
|
* if hit by something. You can provide either one color value, in which case the whole
|
|
* Game Object will be rendered in that color. Or you can provide a color per corner. The colors
|
|
* are blended together across the extent of the Game Object.
|
|
*
|
|
* To modify the tint color once set, either call this method again with new values or use the
|
|
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
|
|
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
|
|
*
|
|
* To remove a tint call `clearTint`.
|
|
*
|
|
* To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`.
|
|
*
|
|
* @method Phaser.GameObjects.Components.Tint#setTintFill
|
|
* @webglOnly
|
|
* @since 3.11.0
|
|
*
|
|
* @param {integer} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object.
|
|
* @param {integer} [topRight] - The tint being applied to the top-right of the Game Object.
|
|
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
|
|
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
|
|
*
|
|
* @return {this} This Game Object instance.
|
|
*/
|
|
setTintFill: function (topLeft, topRight, bottomLeft, bottomRight)
|
|
{
|
|
this.setTint(topLeft, topRight, bottomLeft, bottomRight);
|
|
|
|
this.tintFill = true;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The tint value being applied to the whole of the Game Object.
|
|
* This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#tint
|
|
* @type {integer}
|
|
* @webglOnly
|
|
* @since 3.0.0
|
|
*/
|
|
tint: {
|
|
|
|
set: function (value)
|
|
{
|
|
this.setTint(value, value, value, value);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Does this Game Object have a tint applied?
|
|
*
|
|
* It checks to see if the 4 tint properties are set to the value 0xffffff
|
|
* and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted.
|
|
*
|
|
* @name Phaser.GameObjects.Components.Tint#isTinted
|
|
* @type {boolean}
|
|
* @webglOnly
|
|
* @readonly
|
|
* @since 3.11.0
|
|
*/
|
|
isTinted: {
|
|
|
|
get: function ()
|
|
{
|
|
var white = 0xffffff;
|
|
|
|
return (
|
|
this.tintFill ||
|
|
this.tintTopLeft !== white ||
|
|
this.tintTopRight !== white ||
|
|
this.tintBottomLeft !== white ||
|
|
this.tintBottomRight !== white
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = Tint;
|
|
|
|
|
|
/***/ }),
|
|
/* 334 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author Felipe Alfonso <@bitnenfer>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var renderWebGL = __webpack_require__(1);
|
|
var renderCanvas = __webpack_require__(1);
|
|
|
|
if (true)
|
|
{
|
|
renderWebGL = __webpack_require__(335);
|
|
}
|
|
|
|
if (true)
|
|
{
|
|
renderCanvas = __webpack_require__(336);
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
renderWebGL: renderWebGL,
|
|
renderCanvas: renderCanvas
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 335 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author Felipe Alfonso <@bitnenfer>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method Phaser.GameObjects.Container#renderWebGL
|
|
* @since 3.4.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
|
|
* @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var ContainerWebGLRenderer = function (renderer, container, camera, parentMatrix)
|
|
{
|
|
var children = container.list;
|
|
|
|
if (children.length === 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var transformMatrix = container.localTransform;
|
|
|
|
if (parentMatrix)
|
|
{
|
|
transformMatrix.loadIdentity();
|
|
transformMatrix.multiply(parentMatrix);
|
|
transformMatrix.translate(container.x, container.y);
|
|
transformMatrix.rotate(container.rotation);
|
|
transformMatrix.scale(container.scaleX, container.scaleY);
|
|
}
|
|
else
|
|
{
|
|
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
|
|
}
|
|
|
|
var containerHasBlendMode = (container.blendMode !== -1);
|
|
|
|
if (!containerHasBlendMode)
|
|
{
|
|
// If Container is SKIP_TEST then set blend mode to be Normal
|
|
renderer.setBlendMode(0);
|
|
}
|
|
|
|
var alpha = container.alpha;
|
|
|
|
var scrollFactorX = container.scrollFactorX;
|
|
var scrollFactorY = container.scrollFactorY;
|
|
|
|
var list = children;
|
|
var childCount = children.length;
|
|
|
|
for (var i = 0; i < childCount; i++)
|
|
{
|
|
var child = children[i];
|
|
|
|
if (!child.willRender(camera))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var childAlphaTopLeft;
|
|
var childAlphaTopRight;
|
|
var childAlphaBottomLeft;
|
|
var childAlphaBottomRight;
|
|
|
|
if (child.alphaTopLeft !== undefined)
|
|
{
|
|
childAlphaTopLeft = child.alphaTopLeft;
|
|
childAlphaTopRight = child.alphaTopRight;
|
|
childAlphaBottomLeft = child.alphaBottomLeft;
|
|
childAlphaBottomRight = child.alphaBottomRight;
|
|
}
|
|
else
|
|
{
|
|
var childAlpha = child.alpha;
|
|
|
|
childAlphaTopLeft = childAlpha;
|
|
childAlphaTopRight = childAlpha;
|
|
childAlphaBottomLeft = childAlpha;
|
|
childAlphaBottomRight = childAlpha;
|
|
}
|
|
|
|
var childScrollFactorX = child.scrollFactorX;
|
|
var childScrollFactorY = child.scrollFactorY;
|
|
|
|
if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
|
|
{
|
|
// If Container doesn't have its own blend mode, then a child can have one
|
|
renderer.setBlendMode(child.blendMode);
|
|
}
|
|
|
|
var mask = child.mask;
|
|
|
|
if (mask)
|
|
{
|
|
mask.preRenderWebGL(renderer, child, camera);
|
|
}
|
|
|
|
var type = child.type;
|
|
|
|
if (type !== renderer.currentType)
|
|
{
|
|
renderer.newType = true;
|
|
renderer.currentType = type;
|
|
}
|
|
|
|
renderer.nextTypeMatch = (i < childCount - 1) ? (list[i + 1].type === renderer.currentType) : false;
|
|
|
|
// Set parent values
|
|
child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
|
|
|
|
child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha);
|
|
|
|
// Render
|
|
child.renderWebGL(renderer, child, camera, transformMatrix);
|
|
|
|
// Restore original values
|
|
|
|
child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight);
|
|
|
|
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
|
|
|
|
if (mask)
|
|
{
|
|
mask.postRenderWebGL(renderer, camera);
|
|
}
|
|
|
|
renderer.newType = false;
|
|
}
|
|
};
|
|
|
|
module.exports = ContainerWebGLRenderer;
|
|
|
|
|
|
/***/ }),
|
|
/* 336 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @author Felipe Alfonso <@bitnenfer>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Renders this Game Object with the Canvas Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method Phaser.GameObjects.Container#renderCanvas
|
|
* @since 3.4.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
|
|
* @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var ContainerCanvasRenderer = function (renderer, container, camera, parentMatrix)
|
|
{
|
|
var children = container.list;
|
|
|
|
if (children.length === 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var transformMatrix = container.localTransform;
|
|
|
|
if (parentMatrix)
|
|
{
|
|
transformMatrix.loadIdentity();
|
|
transformMatrix.multiply(parentMatrix);
|
|
transformMatrix.translate(container.x, container.y);
|
|
transformMatrix.rotate(container.rotation);
|
|
transformMatrix.scale(container.scaleX, container.scaleY);
|
|
}
|
|
else
|
|
{
|
|
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
|
|
}
|
|
|
|
var containerHasBlendMode = (container.blendMode !== -1);
|
|
|
|
if (!containerHasBlendMode)
|
|
{
|
|
// If Container is SKIP_TEST then set blend mode to be Normal
|
|
renderer.setBlendMode(0);
|
|
}
|
|
|
|
var alpha = container._alpha;
|
|
var scrollFactorX = container.scrollFactorX;
|
|
var scrollFactorY = container.scrollFactorY;
|
|
|
|
if (container.mask)
|
|
{
|
|
container.mask.preRenderCanvas(renderer, null, camera);
|
|
}
|
|
|
|
for (var i = 0; i < children.length; i++)
|
|
{
|
|
var child = children[i];
|
|
|
|
if (!child.willRender(camera))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var childAlpha = child.alpha;
|
|
var childScrollFactorX = child.scrollFactorX;
|
|
var childScrollFactorY = child.scrollFactorY;
|
|
|
|
if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
|
|
{
|
|
// If Container doesn't have its own blend mode, then a child can have one
|
|
renderer.setBlendMode(child.blendMode);
|
|
}
|
|
|
|
// Set parent values
|
|
child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
|
|
child.setAlpha(childAlpha * alpha);
|
|
|
|
// Render
|
|
child.renderCanvas(renderer, child, camera, transformMatrix);
|
|
|
|
// Restore original values
|
|
child.setAlpha(childAlpha);
|
|
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
|
|
}
|
|
|
|
if (container.mask)
|
|
{
|
|
container.mask.postRenderCanvas(renderer);
|
|
}
|
|
};
|
|
|
|
module.exports = ContainerCanvasRenderer;
|
|
|
|
|
|
/***/ }),
|
|
/* 337 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var Rectangle = __webpack_require__(25);
|
|
|
|
/**
|
|
* Creates a new Rectangle or repositions and/or resizes an existing Rectangle so that it encompasses the two given Rectangles, i.e. calculates their union.
|
|
*
|
|
* @function Phaser.Geom.Rectangle.Union
|
|
* @since 3.0.0
|
|
*
|
|
* @generic {Phaser.Geom.Rectangle} O - [out,$return]
|
|
*
|
|
* @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to use.
|
|
* @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to use.
|
|
* @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the union in.
|
|
*
|
|
* @return {Phaser.Geom.Rectangle} The modified `out` Rectangle, or a new Rectangle if none was provided.
|
|
*/
|
|
var Union = function (rectA, rectB, out)
|
|
{
|
|
if (out === undefined) { out = new Rectangle(); }
|
|
|
|
// Cache vars so we can use one of the input rects as the output rect
|
|
var x = Math.min(rectA.x, rectB.x);
|
|
var y = Math.min(rectA.y, rectB.y);
|
|
var w = Math.max(rectA.right, rectB.right) - x;
|
|
var h = Math.max(rectA.bottom, rectB.bottom) - y;
|
|
|
|
return out.setTo(x, y, w, h);
|
|
};
|
|
|
|
module.exports = Union;
|
|
|
|
|
|
/***/ }),
|
|
/* 338 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var renderWebGL = __webpack_require__(1);
|
|
var renderCanvas = __webpack_require__(1);
|
|
|
|
if (true)
|
|
{
|
|
renderWebGL = __webpack_require__(339);
|
|
}
|
|
|
|
if (true)
|
|
{
|
|
renderCanvas = __webpack_require__(340);
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
renderWebGL: renderWebGL,
|
|
renderCanvas: renderCanvas
|
|
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 339 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var CounterClockwise = __webpack_require__(8);
|
|
var Clamp = __webpack_require__(4);
|
|
var RadToDeg = __webpack_require__(9);
|
|
var Wrap = __webpack_require__(6);
|
|
|
|
/**
|
|
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method SpineContainerWebGLRenderer#renderWebGL
|
|
* @since 3.50.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
|
|
* @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var SpineContainerWebGLRenderer = function (renderer, container, camera, parentMatrix)
|
|
{
|
|
var plugin = container.plugin;
|
|
var sceneRenderer = plugin.sceneRenderer;
|
|
var children = container.list;
|
|
|
|
if (children.length === 0)
|
|
{
|
|
if (sceneRenderer.batcher.isDrawing && renderer.finalType)
|
|
{
|
|
sceneRenderer.end();
|
|
|
|
renderer.pipelines.rebind();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var transformMatrix = container.localTransform;
|
|
|
|
if (parentMatrix)
|
|
{
|
|
transformMatrix.loadIdentity();
|
|
transformMatrix.multiply(parentMatrix);
|
|
transformMatrix.translate(container.x, container.y);
|
|
transformMatrix.rotate(container.rotation);
|
|
transformMatrix.scale(container.scaleX, container.scaleY);
|
|
}
|
|
else
|
|
{
|
|
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
|
|
}
|
|
|
|
var alpha = container.alpha;
|
|
var scrollFactorX = container.scrollFactorX;
|
|
var scrollFactorY = container.scrollFactorY;
|
|
|
|
var GameObjectRenderMask = 15;
|
|
|
|
if (renderer.newType)
|
|
{
|
|
// flush + clear if this is a new type
|
|
renderer.pipelines.clear();
|
|
|
|
sceneRenderer.begin();
|
|
}
|
|
|
|
for (var i = 0; i < children.length; i++)
|
|
{
|
|
var src = children[i];
|
|
|
|
var skeleton = src.skeleton;
|
|
var childAlpha = skeleton.color.a;
|
|
|
|
var willRender = !(GameObjectRenderMask !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || childAlpha === 0);
|
|
|
|
if (!skeleton || !willRender)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var camMatrix = renderer._tempMatrix1;
|
|
var spriteMatrix = renderer._tempMatrix2;
|
|
var calcMatrix = renderer._tempMatrix3;
|
|
|
|
spriteMatrix.applyITRS(src.x, src.y, src.rotation, Math.abs(src.scaleX), Math.abs(src.scaleY));
|
|
|
|
camMatrix.copyFrom(camera.matrix);
|
|
|
|
// Multiply the camera by the parent matrix
|
|
camMatrix.multiplyWithOffset(transformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY);
|
|
|
|
// Undo the camera scroll
|
|
spriteMatrix.e = src.x;
|
|
spriteMatrix.f = src.y;
|
|
|
|
// Multiply by the Sprite matrix, store result in calcMatrix
|
|
camMatrix.multiply(spriteMatrix, calcMatrix);
|
|
|
|
var viewportHeight = renderer.height;
|
|
|
|
skeleton.x = calcMatrix.tx;
|
|
skeleton.y = viewportHeight - calcMatrix.ty;
|
|
|
|
skeleton.scaleX = calcMatrix.scaleX;
|
|
skeleton.scaleY = calcMatrix.scaleY;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
skeleton.scaleX *= -1;
|
|
|
|
src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
|
|
}
|
|
else
|
|
{
|
|
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
|
src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
|
|
}
|
|
|
|
if (src.scaleY < 0)
|
|
{
|
|
skeleton.scaleY *= -1;
|
|
|
|
if (src.scaleX < 0)
|
|
{
|
|
src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
else
|
|
{
|
|
src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
|
}
|
|
}
|
|
|
|
if (camera.renderToTexture || renderer.currentFramebuffer !== null)
|
|
{
|
|
skeleton.y = calcMatrix.ty;
|
|
skeleton.scaleY *= -1;
|
|
}
|
|
|
|
// Add autoUpdate option
|
|
skeleton.updateWorldTransform();
|
|
|
|
skeleton.color.a = Clamp(childAlpha * alpha, 0, 1);
|
|
|
|
// Draw the current skeleton
|
|
sceneRenderer.drawSkeleton(skeleton, src.preMultipliedAlpha);
|
|
|
|
// Restore alpha
|
|
skeleton.color.a = childAlpha;
|
|
}
|
|
|
|
if (!renderer.nextTypeMatch)
|
|
{
|
|
// The next object in the display list is not a Spine Game Object or Spine Container, so we end the batch
|
|
sceneRenderer.end();
|
|
|
|
// And rebind the previous pipeline
|
|
renderer.pipelines.rebind();
|
|
}
|
|
};
|
|
|
|
module.exports = SpineContainerWebGLRenderer;
|
|
|
|
|
|
/***/ }),
|
|
/* 340 */
|
|
/***/ (function(module, exports) {
|
|
|
|
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
/**
|
|
* Renders this Game Object with the Canvas Renderer to the given Camera.
|
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
|
* This method should not be called directly. It is a utility function of the Render module.
|
|
*
|
|
* @method Phaser.GameObjects.Container#renderCanvas
|
|
* @since 3.4.0
|
|
* @private
|
|
*
|
|
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
|
|
* @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
|
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
|
*/
|
|
var SpineContainerCanvasRenderer = function (renderer, container, camera, parentMatrix)
|
|
{
|
|
var children = container.list;
|
|
|
|
if (children.length === 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var transformMatrix = container.localTransform;
|
|
|
|
if (parentMatrix)
|
|
{
|
|
transformMatrix.loadIdentity();
|
|
transformMatrix.multiply(parentMatrix);
|
|
transformMatrix.translate(container.x, container.y);
|
|
transformMatrix.rotate(container.rotation);
|
|
transformMatrix.scale(container.scaleX, container.scaleY);
|
|
}
|
|
else
|
|
{
|
|
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
|
|
}
|
|
|
|
var containerHasBlendMode = (container.blendMode !== -1);
|
|
|
|
if (!containerHasBlendMode)
|
|
{
|
|
// If Container is SKIP_TEST then set blend mode to be Normal
|
|
renderer.setBlendMode(0);
|
|
}
|
|
|
|
var alpha = container._alpha;
|
|
var scrollFactorX = container.scrollFactorX;
|
|
var scrollFactorY = container.scrollFactorY;
|
|
|
|
if (container.mask)
|
|
{
|
|
container.mask.preRenderCanvas(renderer, null, camera);
|
|
}
|
|
|
|
for (var i = 0; i < children.length; i++)
|
|
{
|
|
var child = children[i];
|
|
|
|
if (!child.willRender(camera))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var childAlpha = child.alpha;
|
|
var childScrollFactorX = child.scrollFactorX;
|
|
var childScrollFactorY = child.scrollFactorY;
|
|
|
|
if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
|
|
{
|
|
// If Container doesn't have its own blend mode, then a child can have one
|
|
renderer.setBlendMode(child.blendMode);
|
|
}
|
|
|
|
// Set parent values
|
|
child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
|
|
child.setAlpha(childAlpha * alpha);
|
|
|
|
// Render
|
|
child.renderCanvas(renderer, child, interpolationPercentage, camera, transformMatrix);
|
|
|
|
// Restore original values
|
|
child.setAlpha(childAlpha);
|
|
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
|
|
}
|
|
|
|
if (container.mask)
|
|
{
|
|
container.mask.postRenderCanvas(renderer);
|
|
}
|
|
};
|
|
|
|
module.exports = SpineContainerCanvasRenderer;
|
|
|
|
|
|
/***/ })
|
|
/******/ ]); |