diff --git a/dist/phaser-arcade-physics.js b/dist/phaser-arcade-physics.js index c422285c7..6dff2cc5a 100644 --- a/dist/phaser-arcade-physics.js +++ b/dist/phaser-arcade-physics.js @@ -434,7 +434,7 @@ module.exports = GetFastValue; // and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl var Class = __webpack_require__(0); -var FuzzyEqual = __webpack_require__(121); +var FuzzyEqual = __webpack_require__(123); /** * @classdesc @@ -2073,11 +2073,11 @@ if (true) { var Class = __webpack_require__(0); var Contains = __webpack_require__(56); -var GetPoint = __webpack_require__(166); +var GetPoint = __webpack_require__(167); var GetPoints = __webpack_require__(300); var GEOM_CONST = __webpack_require__(55); var Line = __webpack_require__(45); -var Random = __webpack_require__(169); +var Random = __webpack_require__(170); /** * @classdesc @@ -2599,13 +2599,13 @@ module.exports = { Mask: __webpack_require__(303), Origin: __webpack_require__(630), PathFollower: __webpack_require__(631), - Pipeline: __webpack_require__(170), + Pipeline: __webpack_require__(171), ScrollFactor: __webpack_require__(306), Size: __webpack_require__(632), Texture: __webpack_require__(633), TextureCrop: __webpack_require__(634), Tint: __webpack_require__(635), - ToJSON: __webpack_require__(172), + ToJSON: __webpack_require__(173), Transform: __webpack_require__(307), TransformMatrix: __webpack_require__(25), Visible: __webpack_require__(308) @@ -2849,7 +2849,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MATH = __webpack_require__(189); +var MATH = __webpack_require__(190); var GetValue = __webpack_require__(6); /** @@ -3029,7 +3029,7 @@ module.exports = MATH_CONST; */ var Class = __webpack_require__(0); -var ComponentsToJSON = __webpack_require__(172); +var ComponentsToJSON = __webpack_require__(173); var DataManager = __webpack_require__(98); var EventEmitter = __webpack_require__(9); var Events = __webpack_require__(75); @@ -3954,107 +3954,6 @@ module.exports = GameObjectCreator; /***/ }), /* 17 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TransformMatrix = __webpack_require__(25); - -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; - - -/***/ }), -/* 19 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -4154,6 +4053,107 @@ var Extend = function () module.exports = Extend; +/***/ }), +/* 18 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TransformMatrix = __webpack_require__(25); + +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; + + /***/ }), /* 20 */ /***/ (function(module, exports) { @@ -4395,12 +4395,12 @@ module.exports = { var Class = __webpack_require__(0); var CONST = __webpack_require__(20); -var Events = __webpack_require__(90); +var Events = __webpack_require__(91); var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(152); -var MergeXHRSettings = __webpack_require__(235); -var XHRLoader = __webpack_require__(495); -var XHRSettings = __webpack_require__(153); +var GetURL = __webpack_require__(153); +var MergeXHRSettings = __webpack_require__(237); +var XHRLoader = __webpack_require__(511); +var XHRSettings = __webpack_require__(154); /** * @classdesc @@ -6338,7 +6338,7 @@ module.exports = PropertyValueSet; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var GetAdvancedValue = __webpack_require__(13); /** @@ -6539,7 +6539,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Takes a reference to the Canvas Renderer, a Canvas Rendering Context, a Game Object, a Camera and a parent matrix @@ -6607,7 +6607,7 @@ module.exports = SetTransform; */ var CONST = __webpack_require__(39); -var Smoothing = __webpack_require__(188); +var Smoothing = __webpack_require__(189); // The pool into which the canvas elements are placed. var pool = []; @@ -6871,7 +6871,7 @@ var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var Line = __webpack_require__(45); -var PIPELINES_CONST = __webpack_require__(72); +var PIPELINES_CONST = __webpack_require__(65); /** * @classdesc @@ -7262,6 +7262,345 @@ module.exports = Shape; /***/ }), /* 33 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + DIFFERENCE: 11, + + /** + * Exclusion blend mode. For Canvas only. + * Like difference, but with lower contrast. + * + * @name Phaser.BlendModes.EXCLUSION + * @type {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + LUMINOSITY: 16, + + /** + * Alpha erase blend mode. For Canvas and WebGL. + * + * @name Phaser.BlendModes.ERASE + * @type {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + LIGHTER: 25, + + /** + * Copy blend mode. For Canvas only. + * Only the new shape is shown. + * + * @name Phaser.BlendModes.COPY + * @type {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + XOR: 27 + +}; + + +/***/ }), +/* 34 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7291,7 +7630,7 @@ module.exports = DegToRad; /***/ }), -/* 34 */ +/* 35 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7329,7 +7668,7 @@ module.exports = { /***/ }), -/* 35 */ +/* 36 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7341,7 +7680,7 @@ module.exports = { var Class = __webpack_require__(0); var GetColor = __webpack_require__(100); var GetColor32 = __webpack_require__(322); -var HSVToRGB = __webpack_require__(184); +var HSVToRGB = __webpack_require__(185); var RGBToHSV = __webpack_require__(323); /** @@ -8192,7 +8531,7 @@ module.exports = Color; /***/ }), -/* 36 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -9238,7 +9577,7 @@ module.exports = Vector3; /***/ }), -/* 37 */ +/* 38 */ /***/ (function(module, exports) { /** @@ -9292,345 +9631,6 @@ module.exports = { }; -/***/ }), -/* 38 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - DIFFERENCE: 11, - - /** - * Exclusion blend mode. For Canvas only. - * Like difference, but with lower contrast. - * - * @name Phaser.BlendModes.EXCLUSION - * @type {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - LUMINOSITY: 16, - - /** - * Alpha erase blend mode. For Canvas and WebGL. - * - * @name Phaser.BlendModes.ERASE - * @type {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - LIGHTER: 25, - - /** - * Copy blend mode. For Canvas only. - * Only the new shape is shown. - * - * @name Phaser.BlendModes.COPY - * @type {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - XOR: 27 - -}; - - /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { @@ -9657,11 +9657,11 @@ var CONST = { * @type {string} * @since 3.0.0 */ - VERSION: '3.50.0', + VERSION: '3.50.1', - BlendModes: __webpack_require__(38), + BlendModes: __webpack_require__(33), - ScaleModes: __webpack_require__(263), + ScaleModes: __webpack_require__(164), /** * This setting will auto-detect if the browser is capable of suppporting WebGL. @@ -9966,9 +9966,9 @@ module.exports = PropertyValueInc; var Class = __webpack_require__(0); var GetPoint = __webpack_require__(301); -var GetPoints = __webpack_require__(167); +var GetPoints = __webpack_require__(168); var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(168); +var Random = __webpack_require__(169); var Vector2 = __webpack_require__(3); /** @@ -10923,44 +10923,6 @@ module.exports = Contains; /***/ }), /* 57 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets the strokeStyle and lineWidth on the target context based on the given Shape. - * - * @method Phaser.GameObjects.Shape#LineStyleCanvas - * @since 3.13.0 - * @private - * - * @param {CanvasRenderingContext2D} ctx - The context to set the stroke style on. - * @param {Phaser.GameObjects.Shape} src - The Game Object to set the stroke style from. - * @param {number} [altColor] - An alternative color to render with. - * @param {number} [altAlpha] - An alternative alpha to render with. - */ -var LineStyleCanvas = function (ctx, src, altColor, altAlpha) -{ - var strokeColor = (altColor) ? altColor : src.strokeColor; - var strokeAlpha = (altAlpha) ? altAlpha : src.strokeAlpha; - - var red = ((strokeColor & 0xFF0000) >>> 16); - var green = ((strokeColor & 0xFF00) >>> 8); - var blue = (strokeColor & 0xFF); - - ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; - ctx.lineWidth = src.lineWidth; -}; - -module.exports = LineStyleCanvas; - - -/***/ }), -/* 58 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -10970,2708 +10932,15 @@ module.exports = LineStyleCanvas; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -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 `.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 `.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; - - -/***/ }), -/* 59 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Arcade Physics consts. - * - * @ignore - */ - -var CONST = { - - /** - * Dynamic Body. - * - * @name Phaser.Physics.Arcade.DYNAMIC_BODY - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.Group#physicsType - */ - DYNAMIC_BODY: 0, - - /** - * Static Body. - * - * @name Phaser.Physics.Arcade.STATIC_BODY - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.StaticBody#physicsType - */ - STATIC_BODY: 1, - - /** - * Arcade Physics Group containing Dynamic Bodies. - * - * @name Phaser.Physics.Arcade.GROUP - * @readonly - * @type {number} - * @since 3.0.0 - */ - GROUP: 2, - - /** - * A Tilemap Layer. - * - * @name Phaser.Physics.Arcade.TILEMAPLAYER - * @readonly - * @type {number} - * @since 3.0.0 - */ - TILEMAPLAYER: 3, - - /** - * Facing no direction (initial value). - * - * @name Phaser.Physics.Arcade.FACING_NONE - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_NONE: 10, - - /** - * Facing up. - * - * @name Phaser.Physics.Arcade.FACING_UP - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_UP: 11, - - /** - * Facing down. - * - * @name Phaser.Physics.Arcade.FACING_DOWN - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_DOWN: 12, - - /** - * Facing left. - * - * @name Phaser.Physics.Arcade.FACING_LEFT - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_LEFT: 13, - - /** - * Facing right. - * - * @name Phaser.Physics.Arcade.FACING_RIGHT - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_RIGHT: 14 - -}; - -module.exports = CONST; - - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTileAt = __webpack_require__(155); -var GetTilesWithin = __webpack_require__(26); - -/** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * @function Phaser.Tilemaps.Components.CalculateFacesWithin - * @since 3.0.0 - * - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var CalculateFacesWithin = function (tileX, tileY, width, height, layer) -{ - var above = null; - var below = null; - var left = null; - var right = null; - - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; - - if (tile) - { - if (tile.collides) - { - above = GetTileAt(tile.x, tile.y - 1, true, layer); - below = GetTileAt(tile.x, tile.y + 1, true, layer); - left = GetTileAt(tile.x - 1, tile.y, true, layer); - right = GetTileAt(tile.x + 1, tile.y, true, layer); - - tile.faceTop = (above && above.collides) ? false : true; - tile.faceBottom = (below && below.collides) ? false : true; - tile.faceLeft = (left && left.collides) ? false : true; - tile.faceRight = (right && right.collides) ? false : true; - } - else - { - tile.resetFaces(); - } - } - } -}; - -module.exports = CalculateFacesWithin; - - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Contains = __webpack_require__(62); -var GetPoint = __webpack_require__(294); -var GetPoints = __webpack_require__(295); -var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(165); - -/** - * @classdesc - * A Circle object. - * - * This is a geometry object, containing numerical values and related methods to inspect and modify them. - * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. - * To render a Circle you should look at the capabilities of the Graphics class. - * - * @class Circle - * @memberof Phaser.Geom - * @constructor - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * @param {number} [radius=0] - The radius of the circle. - */ -var Circle = new Class({ - - initialize: - - function Circle (x, y, radius) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 0; } - - /** - * The geometry constant type of this object: `GEOM_CONST.CIRCLE`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Circle#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.CIRCLE; - - /** - * The x position of the center of the circle. - * - * @name Phaser.Geom.Circle#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = x; - - /** - * The y position of the center of the circle. - * - * @name Phaser.Geom.Circle#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = y; - - /** - * The internal radius of the circle. - * - * @name Phaser.Geom.Circle#_radius - * @type {number} - * @private - * @since 3.0.0 - */ - this._radius = radius; - - /** - * The internal diameter of the circle. - * - * @name Phaser.Geom.Circle#_diameter - * @type {number} - * @private - * @since 3.0.0 - */ - this._diameter = radius * 2; - }, - - /** - * Check to see if the Circle contains the given x / y coordinates. - * - * @method Phaser.Geom.Circle#contains - * @since 3.0.0 - * - * @param {number} x - The x coordinate to check within the circle. - * @param {number} y - The y coordinate to check within the circle. - * - * @return {boolean} True if the coordinates are within the circle, otherwise false. - */ - contains: function (x, y) - { - return Contains(this, x, y); - }, - - /** - * Returns a Point object containing the coordinates of a point on the circumference of the Circle - * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point - * at 180 degrees around the circle. - * - * @method Phaser.Geom.Circle#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle. - */ - getPoint: function (position, point) - { - return GetPoint(this, position, point); - }, - - /** - * Returns an array of Point objects containing the coordinates of the points around the circumference of the Circle, - * based on the given quantity or stepRate values. - * - * @method Phaser.Geom.Circle#getPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [output,$return] - * - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the circumference of the circle and dividing it by the stepRate. - * @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle. - */ - getPoints: function (quantity, stepRate, output) - { - return GetPoints(this, quantity, stepRate, output); - }, - - /** - * Returns a uniformly distributed random point from anywhere within the Circle. - * - * @method Phaser.Geom.Circle#getRandomPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. - * - * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. - */ - getRandomPoint: function (point) - { - return Random(this, point); - }, - - /** - * Sets the x, y and radius of this circle. - * - * @method Phaser.Geom.Circle#setTo - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * @param {number} [radius=0] - The radius of the circle. - * - * @return {this} This Circle object. - */ - setTo: function (x, y, radius) - { - this.x = x; - this.y = y; - this._radius = radius; - this._diameter = radius * 2; - - return this; - }, - - /** - * Sets this Circle to be empty with a radius of zero. - * Does not change its position. - * - * @method Phaser.Geom.Circle#setEmpty - * @since 3.0.0 - * - * @return {this} This Circle object. - */ - setEmpty: function () - { - this._radius = 0; - this._diameter = 0; - - return this; - }, - - /** - * Sets the position of this Circle. - * - * @method Phaser.Geom.Circle#setPosition - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * - * @return {this} This Circle object. - */ - setPosition: function (x, y) - { - if (y === undefined) { y = x; } - - this.x = x; - this.y = y; - - return this; - }, - - /** - * Checks to see if the Circle is empty: has a radius of zero. - * - * @method Phaser.Geom.Circle#isEmpty - * @since 3.0.0 - * - * @return {boolean} True if the Circle is empty, otherwise false. - */ - isEmpty: function () - { - return (this._radius <= 0); - }, - - /** - * The radius of the Circle. - * - * @name Phaser.Geom.Circle#radius - * @type {number} - * @since 3.0.0 - */ - radius: { - - get: function () - { - return this._radius; - }, - - set: function (value) - { - this._radius = value; - this._diameter = value * 2; - } - - }, - - /** - * The diameter of the Circle. - * - * @name Phaser.Geom.Circle#diameter - * @type {number} - * @since 3.0.0 - */ - diameter: { - - get: function () - { - return this._diameter; - }, - - set: function (value) - { - this._diameter = value; - this._radius = value * 0.5; - } - - }, - - /** - * The left position of the Circle. - * - * @name Phaser.Geom.Circle#left - * @type {number} - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.x - this._radius; - }, - - set: function (value) - { - this.x = value + this._radius; - } - - }, - - /** - * The right position of the Circle. - * - * @name Phaser.Geom.Circle#right - * @type {number} - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.x + this._radius; - }, - - set: function (value) - { - this.x = value - this._radius; - } - - }, - - /** - * The top position of the Circle. - * - * @name Phaser.Geom.Circle#top - * @type {number} - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.y - this._radius; - }, - - set: function (value) - { - this.y = value + this._radius; - } - - }, - - /** - * The bottom position of the Circle. - * - * @name Phaser.Geom.Circle#bottom - * @type {number} - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.y + this._radius; - }, - - set: function (value) - { - this.y = value - this._radius; - } - - } - -}); - -module.exports = Circle; - - -/***/ }), -/* 62 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Check to see if the Circle contains the given x / y coordinates. - * - * @function Phaser.Geom.Circle.Contains - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The Circle to check. - * @param {number} x - The x coordinate to check within the circle. - * @param {number} y - The y coordinate to check within the circle. - * - * @return {boolean} True if the coordinates are within the circle, otherwise false. - */ -var Contains = function (circle, x, y) -{ - // Check if x/y are within the bounds first - if (circle.radius > 0 && x >= circle.left && x <= circle.right && y >= circle.top && y <= circle.bottom) - { - var dx = (circle.x - x) * (circle.x - x); - var dy = (circle.y - y) * (circle.y - y); - - return (dx + dy) <= (circle.radius * circle.radius); - } - else - { - return false; - } -}; - -module.exports = Contains; - - -/***/ }), -/* 63 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 64 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector3 = __webpack_require__(36); - -/** - * @ignore - */ -var EPSILON = 0.000001; - -/** - * @classdesc - * A four-dimensional matrix. - * - * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji - * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - * - * @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 {this} This Matrix4. - */ - set: function (src) - { - return this.copy(src); - }, - - /** - * Sets all values of this Matrix4. - * - * @method Phaser.Math.Matrix4#setValues - * @since 3.50.0 - * - * @param {number} m00 - The m00 value. - * @param {number} m01 - The m01 value. - * @param {number} m02 - The m02 value. - * @param {number} m03 - The m03 value. - * @param {number} m10 - The m10 value. - * @param {number} m11 - The m11 value. - * @param {number} m12 - The m12 value. - * @param {number} m13 - The m13 value. - * @param {number} m20 - The m20 value. - * @param {number} m21 - The m21 value. - * @param {number} m22 - The m22 value. - * @param {number} m23 - The m23 value. - * @param {number} m30 - The m30 value. - * @param {number} m31 - The m31 value. - * @param {number} m32 - The m32 value. - * @param {number} m33 - The m33 value. - * - * @return {this} This Matrix4 instance. - */ - setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) - { - var out = this.val; - - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - - return this; - }, - - /** - * 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 {this} This Matrix4. - */ - copy: function (src) - { - var a = src.val; - - return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - }, - - /** - * Set the values of this Matrix from the given array. - * - * @method Phaser.Math.Matrix4#fromArray - * @since 3.0.0 - * - * @param {number[]} a - The array to copy the values from. Must have at least 16 elements. - * - * @return {this} This Matrix4. - */ - fromArray: function (a) - { - return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - }, - - /** - * 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 () - { - return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - }, - - /** - * 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 {this} This Matrix4. - */ - transform: function (position, scale, rotation) - { - var rotMatrix = _tempMat1.fromQuat(rotation); - - var rm = rotMatrix.val; - - var sx = scale.x; - var sy = scale.y; - var sz = scale.z; - - return this.setValues( - rm[0] * sx, - rm[1] * sx, - rm[2] * sx, - 0, - - rm[4] * sy, - rm[5] * sy, - rm[6] * sy, - 0, - - rm[8] * sz, - rm[9] * sz, - rm[10] * sz, - 0, - - position.x, - position.y, - position.z, - 1 - ); - }, - - /** - * 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 {this} 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 {this} 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 {this} This Matrix4. - */ - identity: function () - { - return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - }, - - /** - * Transpose this Matrix. - * - * @method Phaser.Math.Matrix4#transpose - * @since 3.0.0 - * - * @return {this} 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 - * - * @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4. - * - * @return {this} This Matrix4. - */ - getInverse: function (m) - { - this.copy(m); - - return this.invert(); - }, - - /** - * Invert this Matrix. - * - * @method Phaser.Math.Matrix4#invert - * @since 3.0.0 - * - * @return {this} 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; - - return this.setValues( - (a11 * b11 - a12 * b10 + a13 * b09) * det, - (a02 * b10 - a01 * b11 - a03 * b09) * det, - (a31 * b05 - a32 * b04 + a33 * b03) * det, - (a22 * b04 - a21 * b05 - a23 * b03) * det, - (a12 * b08 - a10 * b11 - a13 * b07) * det, - (a00 * b11 - a02 * b08 + a03 * b07) * det, - (a32 * b02 - a30 * b05 - a33 * b01) * det, - (a20 * b05 - a22 * b02 + a23 * b01) * det, - (a10 * b10 - a11 * b08 + a13 * b06) * det, - (a01 * b08 - a00 * b10 - a03 * b06) * det, - (a30 * b04 - a31 * b02 + a33 * b00) * det, - (a21 * b02 - a20 * b04 - a23 * b00) * det, - (a11 * b07 - a10 * b09 - a12 * b06) * det, - (a00 * b09 - a01 * b07 + a02 * b06) * det, - (a31 * b01 - a30 * b03 - a32 * b00) * det, - (a20 * b03 - a21 * b01 + a22 * b00) * det - ); - }, - - /** - * Calculate the adjoint, or adjugate, of this Matrix. - * - * @method Phaser.Math.Matrix4#adjoint - * @since 3.0.0 - * - * @return {this} 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]; - - return this.setValues( - (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)), - -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)), - (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)), - -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)), - -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)), - (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)), - -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)), - (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)), - (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)), - -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)), - (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)), - -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)), - -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)), - (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)), - -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)), - (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)) - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - multiplyLocal: function (src) - { - var a = this.val; - var b = src.val; - - return this.setValues( - a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12], - a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13], - a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14], - a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15], - - a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12], - a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13], - a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14], - a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15], - - a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12], - a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13], - a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14], - a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15], - - a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12], - a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13], - a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14], - a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15] - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - multiplyMatrices: function (a, b) - { - var am = a.val; - var bm = b.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]; - - return this.setValues( - a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41, - a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41, - a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41, - a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41, - a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42, - a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42, - a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42, - a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42, - a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43, - a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43, - a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43, - a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43, - a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44, - a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44, - a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44, - a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - translate: function (v) - { - return this.translateXYZ(v.x, v.y, v.z); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - scale: function (v) - { - return this.scaleXYZ(v.x, v.y, v.z); - }, - - /** - * 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 {this} 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 {this} 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; - - return this.setValues( - 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 - ); - }, - - /** - * 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 {this} 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 this; - } - - 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]; - - var a30 = a[12]; - var a31 = a[13]; - var a32 = a[14]; - var a33 = a[15]; - - // 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 - return this.setValues( - a00 * b00 + a10 * b01 + a20 * b02, - a01 * b00 + a11 * b01 + a21 * b02, - a02 * b00 + a12 * b01 + a22 * b02, - a03 * b00 + a13 * b01 + a23 * b02, - a00 * b10 + a10 * b11 + a20 * b12, - a01 * b10 + a11 * b11 + a21 * b12, - a02 * b10 + a12 * b11 + a22 * b12, - a03 * b10 + a13 * b11 + a23 * b12, - a00 * b20 + a10 * b21 + a20 * b22, - a01 * b20 + a11 * b21 + a21 * b22, - a02 * b20 + a12 * b21 + a22 * b22, - a03 * b20 + a13 * b21 + a23 * b22, - a30, a31, a32, a33 - ); - }, - - /** - * 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 {this} 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 {this} 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 {this} 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 {this} This Matrix4. - */ - fromRotationTranslation: function (q, v) - { - // Quaternion math - 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; - - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, - - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, - - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, - - v.x, - v.y, - v.z, - 1 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - 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; - - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, - - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, - - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, - - 0, - 0, - 0, - 1 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - frustum: function (left, right, bottom, top, near, far) - { - var rl = 1 / (right - left); - var tb = 1 / (top - bottom); - var nf = 1 / (near - far); - - return this.setValues( - (near * 2) * rl, - 0, - 0, - 0, - - 0, - (near * 2) * tb, - 0, - 0, - - (right + left) * rl, - (top + bottom) * tb, - (far + near) * nf, - -1, - - 0, - 0, - (far * near * 2) * nf, - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - perspective: function (fovy, aspect, near, far) - { - var f = 1.0 / Math.tan(fovy / 2); - var nf = 1 / (near - far); - - return this.setValues( - f / aspect, - 0, - 0, - 0, - - 0, - f, - 0, - 0, - - 0, - 0, - (far + near) * nf, - -1, - - 0, - 0, - (2 * far * near) * nf, - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - perspectiveLH: function (width, height, near, far) - { - return this.setValues( - (2 * near) / width, - 0, - 0, - 0, - - 0, - (2 * near) / height, - 0, - 0, - - 0, - 0, - -far / (near - far), - 1, - - 0, - 0, - (near * far) / (near - far), - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - ortho: function (left, right, bottom, top, near, far) - { - 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; - - return this.setValues( - -2 * lr, - 0, - 0, - 0, - - 0, - -2 * bt, - 0, - 0, - - 0, - 0, - 2 * nf, - 0, - - (left + right) * lr, - (top + bottom) * bt, - (far + near) * nf, - 1 - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - lookAt: function (eye, center, up) - { - 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; - } - - return this.setValues( - x0, - y0, - z0, - 0, - - x1, - y1, - z1, - 0, - - x2, - y2, - z2, - 0, - - -(x0 * eyex + x1 * eyey + x2 * eyez), - -(y0 * eyex + y1 * eyey + y2 * eyez), - -(z0 * eyex + z1 * eyey + z2 * eyez), - 1 - ); - }, - - /** - * 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 {this} 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 {this} 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) - { - this.multiplyLocal(viewMatrix); - } - - if (projectionMatrix) - { - this.multiplyLocal(projectionMatrix); - } - - return this; - }, - - /** - * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4. - * - * @method Phaser.Math.Matrix4#multiplyToMat4 - * @since 3.50.0 - * - * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one. - * @param {Phaser.Math.Matrix4} out - The receiving Matrix. - * - * @return {Phaser.Math.Matrix4} This `out` Matrix4. - */ - multiplyToMat4: function (src, out) - { - var a = this.val; - var b = src.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 = b[0]; - var b01 = b[1]; - var b02 = b[2]; - var b03 = b[3]; - var b10 = b[4]; - var b11 = b[5]; - var b12 = b[6]; - var b13 = b[7]; - var b20 = b[8]; - var b21 = b[9]; - var b22 = b[10]; - var b23 = b[11]; - var b30 = b[12]; - var b31 = b[13]; - var b32 = b[14]; - var b33 = b[15]; - - return out.setValues( - b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, - b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31, - b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32, - b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33, - - b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, - b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, - b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, - b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, - - b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, - b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, - b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, - b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, - - b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, - b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, - b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, - b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33 - ); - }, - - /** - * Takes the rotation and position vectors and builds this Matrix4 from them. - * - * @method Phaser.Math.Matrix4#fromRotationXYTranslation - * @since 3.50.0 - * - * @param {Phaser.Math.Vector3} rotation - The rotation vector. - * @param {Phaser.Math.Vector3} position - The position vector. - * @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`) - * - * @return {this} This Matrix4. - */ - fromRotationXYTranslation: function (rotation, position, translateFirst) - { - var x = position.x; - var y = position.y; - var z = position.z; - - var sx = Math.sin(rotation.x); - var cx = Math.cos(rotation.x); - - var sy = Math.sin(rotation.y); - var cy = Math.cos(rotation.y); - - var a30 = x; - var a31 = y; - var a32 = z; - - // Rotate X - - var b21 = -sx; - - // Rotate Y - - var c01 = 0 - b21 * sy; - - var c02 = 0 - cx * sy; - - var c21 = b21 * cy; - - var c22 = cx * cy; - - // Translate - if (!translateFirst) - { - // a30 = cy * x + 0 * y + sy * z; - a30 = cy * x + sy * z; - a31 = c01 * x + cx * y + c21 * z; - a32 = c02 * x + sx * y + c22 * z; - } - - return this.setValues( - cy, - c01, - c02, - 0, - 0, - cx, - sx, - 0, - sy, - c21, - c22, - 0, - a30, - a31, - a32, - 1 - ); - }, - - /** - * 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)); - } - -}); - -/** - * @ignore - */ -var _tempMat1 = new Matrix4(); - -/** - * @ignore - */ -var _tempMat2 = new Matrix4(); - -/** - * @ignore - */ -var _x = new Vector3(); - -/** - * @ignore - */ -var _y = new Vector3(); - -/** - * @ignore - */ -var _z = new Vector3(); - -module.exports = Matrix4; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DeepCopy = __webpack_require__(171); +var DeepCopy = __webpack_require__(172); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(575); +var Events = __webpack_require__(368); var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(65); -var RendererEvents = __webpack_require__(94); -var RenderTarget = __webpack_require__(162); +var Matrix4 = __webpack_require__(67); +var RendererEvents = __webpack_require__(88); +var RenderTarget = __webpack_require__(139); var Utils = __webpack_require__(12); -var WebGLShader = __webpack_require__(576); +var WebGLShader = __webpack_require__(369); /** * @classdesc @@ -15769,10 +13038,2847 @@ var WebGLPipeline = new Class({ module.exports = WebGLPipeline; +/***/ }), +/* 58 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets the strokeStyle and lineWidth on the target context based on the given Shape. + * + * @method Phaser.GameObjects.Shape#LineStyleCanvas + * @since 3.13.0 + * @private + * + * @param {CanvasRenderingContext2D} ctx - The context to set the stroke style on. + * @param {Phaser.GameObjects.Shape} src - The Game Object to set the stroke style from. + * @param {number} [altColor] - An alternative color to render with. + * @param {number} [altAlpha] - An alternative alpha to render with. + */ +var LineStyleCanvas = function (ctx, src, altColor, altAlpha) +{ + var strokeColor = (altColor) ? altColor : src.strokeColor; + var strokeAlpha = (altAlpha) ? altAlpha : src.strokeAlpha; + + var red = ((strokeColor & 0xFF0000) >>> 16); + var green = ((strokeColor & 0xFF00) >>> 8); + var blue = (strokeColor & 0xFF); + + ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; + ctx.lineWidth = src.lineWidth; +}; + +module.exports = LineStyleCanvas; + + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var GetValue = __webpack_require__(6); +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 `.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 `.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; + + +/***/ }), +/* 60 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Arcade Physics consts. + * + * @ignore + */ + +var CONST = { + + /** + * Dynamic Body. + * + * @name Phaser.Physics.Arcade.DYNAMIC_BODY + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#physicsType + * @see Phaser.Physics.Arcade.Group#physicsType + */ + DYNAMIC_BODY: 0, + + /** + * Static Body. + * + * @name Phaser.Physics.Arcade.STATIC_BODY + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#physicsType + * @see Phaser.Physics.Arcade.StaticBody#physicsType + */ + STATIC_BODY: 1, + + /** + * Arcade Physics Group containing Dynamic Bodies. + * + * @name Phaser.Physics.Arcade.GROUP + * @readonly + * @type {number} + * @since 3.0.0 + */ + GROUP: 2, + + /** + * A Tilemap Layer. + * + * @name Phaser.Physics.Arcade.TILEMAPLAYER + * @readonly + * @type {number} + * @since 3.0.0 + */ + TILEMAPLAYER: 3, + + /** + * Facing no direction (initial value). + * + * @name Phaser.Physics.Arcade.FACING_NONE + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_NONE: 10, + + /** + * Facing up. + * + * @name Phaser.Physics.Arcade.FACING_UP + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_UP: 11, + + /** + * Facing down. + * + * @name Phaser.Physics.Arcade.FACING_DOWN + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_DOWN: 12, + + /** + * Facing left. + * + * @name Phaser.Physics.Arcade.FACING_LEFT + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_LEFT: 13, + + /** + * Facing right. + * + * @name Phaser.Physics.Arcade.FACING_RIGHT + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_RIGHT: 14 + +}; + +module.exports = CONST; + + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTileAt = __webpack_require__(156); +var GetTilesWithin = __webpack_require__(26); + +/** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * @function Phaser.Tilemaps.Components.CalculateFacesWithin + * @since 3.0.0 + * + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var CalculateFacesWithin = function (tileX, tileY, width, height, layer) +{ + var above = null; + var below = null; + var left = null; + var right = null; + + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) + { + var tile = tiles[i]; + + if (tile) + { + if (tile.collides) + { + above = GetTileAt(tile.x, tile.y - 1, true, layer); + below = GetTileAt(tile.x, tile.y + 1, true, layer); + left = GetTileAt(tile.x - 1, tile.y, true, layer); + right = GetTileAt(tile.x + 1, tile.y, true, layer); + + tile.faceTop = (above && above.collides) ? false : true; + tile.faceBottom = (below && below.collides) ? false : true; + tile.faceLeft = (left && left.collides) ? false : true; + tile.faceRight = (right && right.collides) ? false : true; + } + else + { + tile.resetFaces(); + } + } + } +}; + +module.exports = CalculateFacesWithin; + + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Contains = __webpack_require__(63); +var GetPoint = __webpack_require__(294); +var GetPoints = __webpack_require__(295); +var GEOM_CONST = __webpack_require__(55); +var Random = __webpack_require__(166); + +/** + * @classdesc + * A Circle object. + * + * This is a geometry object, containing numerical values and related methods to inspect and modify them. + * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. + * To render a Circle you should look at the capabilities of the Graphics class. + * + * @class Circle + * @memberof Phaser.Geom + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * @param {number} [radius=0] - The radius of the circle. + */ +var Circle = new Class({ + + initialize: + + function Circle (x, y, radius) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 0; } + + /** + * The geometry constant type of this object: `GEOM_CONST.CIRCLE`. + * Used for fast type comparisons. + * + * @name Phaser.Geom.Circle#type + * @type {number} + * @readonly + * @since 3.19.0 + */ + this.type = GEOM_CONST.CIRCLE; + + /** + * The x position of the center of the circle. + * + * @name Phaser.Geom.Circle#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = x; + + /** + * The y position of the center of the circle. + * + * @name Phaser.Geom.Circle#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = y; + + /** + * The internal radius of the circle. + * + * @name Phaser.Geom.Circle#_radius + * @type {number} + * @private + * @since 3.0.0 + */ + this._radius = radius; + + /** + * The internal diameter of the circle. + * + * @name Phaser.Geom.Circle#_diameter + * @type {number} + * @private + * @since 3.0.0 + */ + this._diameter = radius * 2; + }, + + /** + * Check to see if the Circle contains the given x / y coordinates. + * + * @method Phaser.Geom.Circle#contains + * @since 3.0.0 + * + * @param {number} x - The x coordinate to check within the circle. + * @param {number} y - The y coordinate to check within the circle. + * + * @return {boolean} True if the coordinates are within the circle, otherwise false. + */ + contains: function (x, y) + { + return Contains(this, x, y); + }, + + /** + * Returns a Point object containing the coordinates of a point on the circumference of the Circle + * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point + * at 180 degrees around the circle. + * + * @method Phaser.Geom.Circle#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle. + */ + getPoint: function (position, point) + { + return GetPoint(this, position, point); + }, + + /** + * Returns an array of Point objects containing the coordinates of the points around the circumference of the Circle, + * based on the given quantity or stepRate values. + * + * @method Phaser.Geom.Circle#getPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [output,$return] + * + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the circumference of the circle and dividing it by the stepRate. + * @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle. + */ + getPoints: function (quantity, stepRate, output) + { + return GetPoints(this, quantity, stepRate, output); + }, + + /** + * Returns a uniformly distributed random point from anywhere within the Circle. + * + * @method Phaser.Geom.Circle#getRandomPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. + * + * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. + */ + getRandomPoint: function (point) + { + return Random(this, point); + }, + + /** + * Sets the x, y and radius of this circle. + * + * @method Phaser.Geom.Circle#setTo + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * @param {number} [radius=0] - The radius of the circle. + * + * @return {this} This Circle object. + */ + setTo: function (x, y, radius) + { + this.x = x; + this.y = y; + this._radius = radius; + this._diameter = radius * 2; + + return this; + }, + + /** + * Sets this Circle to be empty with a radius of zero. + * Does not change its position. + * + * @method Phaser.Geom.Circle#setEmpty + * @since 3.0.0 + * + * @return {this} This Circle object. + */ + setEmpty: function () + { + this._radius = 0; + this._diameter = 0; + + return this; + }, + + /** + * Sets the position of this Circle. + * + * @method Phaser.Geom.Circle#setPosition + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * + * @return {this} This Circle object. + */ + setPosition: function (x, y) + { + if (y === undefined) { y = x; } + + this.x = x; + this.y = y; + + return this; + }, + + /** + * Checks to see if the Circle is empty: has a radius of zero. + * + * @method Phaser.Geom.Circle#isEmpty + * @since 3.0.0 + * + * @return {boolean} True if the Circle is empty, otherwise false. + */ + isEmpty: function () + { + return (this._radius <= 0); + }, + + /** + * The radius of the Circle. + * + * @name Phaser.Geom.Circle#radius + * @type {number} + * @since 3.0.0 + */ + radius: { + + get: function () + { + return this._radius; + }, + + set: function (value) + { + this._radius = value; + this._diameter = value * 2; + } + + }, + + /** + * The diameter of the Circle. + * + * @name Phaser.Geom.Circle#diameter + * @type {number} + * @since 3.0.0 + */ + diameter: { + + get: function () + { + return this._diameter; + }, + + set: function (value) + { + this._diameter = value; + this._radius = value * 0.5; + } + + }, + + /** + * The left position of the Circle. + * + * @name Phaser.Geom.Circle#left + * @type {number} + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.x - this._radius; + }, + + set: function (value) + { + this.x = value + this._radius; + } + + }, + + /** + * The right position of the Circle. + * + * @name Phaser.Geom.Circle#right + * @type {number} + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.x + this._radius; + }, + + set: function (value) + { + this.x = value - this._radius; + } + + }, + + /** + * The top position of the Circle. + * + * @name Phaser.Geom.Circle#top + * @type {number} + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.y - this._radius; + }, + + set: function (value) + { + this.y = value + this._radius; + } + + }, + + /** + * The bottom position of the Circle. + * + * @name Phaser.Geom.Circle#bottom + * @type {number} + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.y + this._radius; + }, + + set: function (value) + { + this.y = value - this._radius; + } + + } + +}); + +module.exports = Circle; + + +/***/ }), +/* 63 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check to see if the Circle contains the given x / y coordinates. + * + * @function Phaser.Geom.Circle.Contains + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle to check. + * @param {number} x - The x coordinate to check within the circle. + * @param {number} y - The y coordinate to check within the circle. + * + * @return {boolean} True if the coordinates are within the circle, otherwise false. + */ +var Contains = function (circle, x, y) +{ + // Check if x/y are within the bounds first + if (circle.radius > 0 && x >= circle.left && x <= circle.right && y >= circle.top && y <= circle.bottom) + { + var dx = (circle.x - x) * (circle.x - x); + var dy = (circle.y - y) * (circle.y - y); + + return (dx + dy) <= (circle.radius * circle.radius); + } + else + { + return false; + } +}; + +module.exports = Contains; + + +/***/ }), +/* 64 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 65 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 Point Light Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + POINTLIGHT_PIPELINE: 'PointLightPipeline', + + /** + * 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', + + /** + * The Graphics and Shapes Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + GRAPHICS_PIPELINE: 'GraphicsPipeline', + + /** + * The Post FX Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + POSTFX_PIPELINE: 'PostFXPipeline', + + /** + * The Utility Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + UTILITY_PIPELINE: 'UtilityPipeline' +}; + +module.exports = PIPELINE_CONST; + + +/***/ }), +/* 66 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + /***/ }), /* 67 */ /***/ (function(module, exports, __webpack_require__) { +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector3 = __webpack_require__(37); + +/** + * @ignore + */ +var EPSILON = 0.000001; + +/** + * @classdesc + * A four-dimensional matrix. + * + * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji + * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + * + * @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 {this} This Matrix4. + */ + set: function (src) + { + return this.copy(src); + }, + + /** + * Sets all values of this Matrix4. + * + * @method Phaser.Math.Matrix4#setValues + * @since 3.50.0 + * + * @param {number} m00 - The m00 value. + * @param {number} m01 - The m01 value. + * @param {number} m02 - The m02 value. + * @param {number} m03 - The m03 value. + * @param {number} m10 - The m10 value. + * @param {number} m11 - The m11 value. + * @param {number} m12 - The m12 value. + * @param {number} m13 - The m13 value. + * @param {number} m20 - The m20 value. + * @param {number} m21 - The m21 value. + * @param {number} m22 - The m22 value. + * @param {number} m23 - The m23 value. + * @param {number} m30 - The m30 value. + * @param {number} m31 - The m31 value. + * @param {number} m32 - The m32 value. + * @param {number} m33 - The m33 value. + * + * @return {this} This Matrix4 instance. + */ + setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) + { + var out = this.val; + + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + + return this; + }, + + /** + * 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 {this} This Matrix4. + */ + copy: function (src) + { + var a = src.val; + + return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + }, + + /** + * Set the values of this Matrix from the given array. + * + * @method Phaser.Math.Matrix4#fromArray + * @since 3.0.0 + * + * @param {number[]} a - The array to copy the values from. Must have at least 16 elements. + * + * @return {this} This Matrix4. + */ + fromArray: function (a) + { + return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + }, + + /** + * 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 () + { + return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + }, + + /** + * 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 {this} This Matrix4. + */ + transform: function (position, scale, rotation) + { + var rotMatrix = _tempMat1.fromQuat(rotation); + + var rm = rotMatrix.val; + + var sx = scale.x; + var sy = scale.y; + var sz = scale.z; + + return this.setValues( + rm[0] * sx, + rm[1] * sx, + rm[2] * sx, + 0, + + rm[4] * sy, + rm[5] * sy, + rm[6] * sy, + 0, + + rm[8] * sz, + rm[9] * sz, + rm[10] * sz, + 0, + + position.x, + position.y, + position.z, + 1 + ); + }, + + /** + * 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 {this} 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 {this} 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 {this} This Matrix4. + */ + identity: function () + { + return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + }, + + /** + * Transpose this Matrix. + * + * @method Phaser.Math.Matrix4#transpose + * @since 3.0.0 + * + * @return {this} 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 + * + * @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4. + * + * @return {this} This Matrix4. + */ + getInverse: function (m) + { + this.copy(m); + + return this.invert(); + }, + + /** + * Invert this Matrix. + * + * @method Phaser.Math.Matrix4#invert + * @since 3.0.0 + * + * @return {this} 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; + + return this.setValues( + (a11 * b11 - a12 * b10 + a13 * b09) * det, + (a02 * b10 - a01 * b11 - a03 * b09) * det, + (a31 * b05 - a32 * b04 + a33 * b03) * det, + (a22 * b04 - a21 * b05 - a23 * b03) * det, + (a12 * b08 - a10 * b11 - a13 * b07) * det, + (a00 * b11 - a02 * b08 + a03 * b07) * det, + (a32 * b02 - a30 * b05 - a33 * b01) * det, + (a20 * b05 - a22 * b02 + a23 * b01) * det, + (a10 * b10 - a11 * b08 + a13 * b06) * det, + (a01 * b08 - a00 * b10 - a03 * b06) * det, + (a30 * b04 - a31 * b02 + a33 * b00) * det, + (a21 * b02 - a20 * b04 - a23 * b00) * det, + (a11 * b07 - a10 * b09 - a12 * b06) * det, + (a00 * b09 - a01 * b07 + a02 * b06) * det, + (a31 * b01 - a30 * b03 - a32 * b00) * det, + (a20 * b03 - a21 * b01 + a22 * b00) * det + ); + }, + + /** + * Calculate the adjoint, or adjugate, of this Matrix. + * + * @method Phaser.Math.Matrix4#adjoint + * @since 3.0.0 + * + * @return {this} 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]; + + return this.setValues( + (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)), + -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)), + (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)), + -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)), + -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)), + (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)), + -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)), + (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)), + (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)), + -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)), + (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)), + -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)), + -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)), + (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)), + -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)), + (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)) + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + multiplyLocal: function (src) + { + var a = this.val; + var b = src.val; + + return this.setValues( + a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12], + a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13], + a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14], + a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15], + + a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12], + a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13], + a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14], + a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15], + + a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12], + a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13], + a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14], + a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15], + + a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12], + a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13], + a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14], + a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15] + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + multiplyMatrices: function (a, b) + { + var am = a.val; + var bm = b.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]; + + return this.setValues( + a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41, + a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41, + a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41, + a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41, + a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42, + a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42, + a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42, + a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42, + a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43, + a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43, + a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43, + a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43, + a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44, + a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44, + a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44, + a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + translate: function (v) + { + return this.translateXYZ(v.x, v.y, v.z); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + scale: function (v) + { + return this.scaleXYZ(v.x, v.y, v.z); + }, + + /** + * 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 {this} 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 {this} 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; + + return this.setValues( + 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 + ); + }, + + /** + * 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 {this} 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 this; + } + + 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]; + + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + + // 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 + return this.setValues( + a00 * b00 + a10 * b01 + a20 * b02, + a01 * b00 + a11 * b01 + a21 * b02, + a02 * b00 + a12 * b01 + a22 * b02, + a03 * b00 + a13 * b01 + a23 * b02, + a00 * b10 + a10 * b11 + a20 * b12, + a01 * b10 + a11 * b11 + a21 * b12, + a02 * b10 + a12 * b11 + a22 * b12, + a03 * b10 + a13 * b11 + a23 * b12, + a00 * b20 + a10 * b21 + a20 * b22, + a01 * b20 + a11 * b21 + a21 * b22, + a02 * b20 + a12 * b21 + a22 * b22, + a03 * b20 + a13 * b21 + a23 * b22, + a30, a31, a32, a33 + ); + }, + + /** + * 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 {this} 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 {this} 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 {this} 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 {this} This Matrix4. + */ + fromRotationTranslation: function (q, v) + { + // Quaternion math + 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; + + return this.setValues( + 1 - (yy + zz), + xy + wz, + xz - wy, + 0, + + xy - wz, + 1 - (xx + zz), + yz + wx, + 0, + + xz + wy, + yz - wx, + 1 - (xx + yy), + 0, + + v.x, + v.y, + v.z, + 1 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + 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; + + return this.setValues( + 1 - (yy + zz), + xy + wz, + xz - wy, + 0, + + xy - wz, + 1 - (xx + zz), + yz + wx, + 0, + + xz + wy, + yz - wx, + 1 - (xx + yy), + 0, + + 0, + 0, + 0, + 1 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + frustum: function (left, right, bottom, top, near, far) + { + var rl = 1 / (right - left); + var tb = 1 / (top - bottom); + var nf = 1 / (near - far); + + return this.setValues( + (near * 2) * rl, + 0, + 0, + 0, + + 0, + (near * 2) * tb, + 0, + 0, + + (right + left) * rl, + (top + bottom) * tb, + (far + near) * nf, + -1, + + 0, + 0, + (far * near * 2) * nf, + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + perspective: function (fovy, aspect, near, far) + { + var f = 1.0 / Math.tan(fovy / 2); + var nf = 1 / (near - far); + + return this.setValues( + f / aspect, + 0, + 0, + 0, + + 0, + f, + 0, + 0, + + 0, + 0, + (far + near) * nf, + -1, + + 0, + 0, + (2 * far * near) * nf, + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + perspectiveLH: function (width, height, near, far) + { + return this.setValues( + (2 * near) / width, + 0, + 0, + 0, + + 0, + (2 * near) / height, + 0, + 0, + + 0, + 0, + -far / (near - far), + 1, + + 0, + 0, + (near * far) / (near - far), + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + ortho: function (left, right, bottom, top, near, far) + { + 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; + + return this.setValues( + -2 * lr, + 0, + 0, + 0, + + 0, + -2 * bt, + 0, + 0, + + 0, + 0, + 2 * nf, + 0, + + (left + right) * lr, + (top + bottom) * bt, + (far + near) * nf, + 1 + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + lookAt: function (eye, center, up) + { + 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; + } + + return this.setValues( + x0, + y0, + z0, + 0, + + x1, + y1, + z1, + 0, + + x2, + y2, + z2, + 0, + + -(x0 * eyex + x1 * eyey + x2 * eyez), + -(y0 * eyex + y1 * eyey + y2 * eyez), + -(z0 * eyex + z1 * eyey + z2 * eyez), + 1 + ); + }, + + /** + * 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 {this} 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 {this} 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) + { + this.multiplyLocal(viewMatrix); + } + + if (projectionMatrix) + { + this.multiplyLocal(projectionMatrix); + } + + return this; + }, + + /** + * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4. + * + * @method Phaser.Math.Matrix4#multiplyToMat4 + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one. + * @param {Phaser.Math.Matrix4} out - The receiving Matrix. + * + * @return {Phaser.Math.Matrix4} This `out` Matrix4. + */ + multiplyToMat4: function (src, out) + { + var a = this.val; + var b = src.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 = b[0]; + var b01 = b[1]; + var b02 = b[2]; + var b03 = b[3]; + var b10 = b[4]; + var b11 = b[5]; + var b12 = b[6]; + var b13 = b[7]; + var b20 = b[8]; + var b21 = b[9]; + var b22 = b[10]; + var b23 = b[11]; + var b30 = b[12]; + var b31 = b[13]; + var b32 = b[14]; + var b33 = b[15]; + + return out.setValues( + b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, + b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31, + b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32, + b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33, + + b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, + b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, + b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, + b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, + + b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, + b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, + b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, + b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, + + b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, + b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, + b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, + b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33 + ); + }, + + /** + * Takes the rotation and position vectors and builds this Matrix4 from them. + * + * @method Phaser.Math.Matrix4#fromRotationXYTranslation + * @since 3.50.0 + * + * @param {Phaser.Math.Vector3} rotation - The rotation vector. + * @param {Phaser.Math.Vector3} position - The position vector. + * @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`) + * + * @return {this} This Matrix4. + */ + fromRotationXYTranslation: function (rotation, position, translateFirst) + { + var x = position.x; + var y = position.y; + var z = position.z; + + var sx = Math.sin(rotation.x); + var cx = Math.cos(rotation.x); + + var sy = Math.sin(rotation.y); + var cy = Math.cos(rotation.y); + + var a30 = x; + var a31 = y; + var a32 = z; + + // Rotate X + + var b21 = -sx; + + // Rotate Y + + var c01 = 0 - b21 * sy; + + var c02 = 0 - cx * sy; + + var c21 = b21 * cy; + + var c22 = cx * cy; + + // Translate + if (!translateFirst) + { + // a30 = cy * x + 0 * y + sy * z; + a30 = cy * x + sy * z; + a31 = c01 * x + cx * y + c21 * z; + a32 = c02 * x + sx * y + c22 * z; + } + + return this.setValues( + cy, + c01, + c02, + 0, + 0, + cx, + sx, + 0, + sy, + c21, + c22, + 0, + a30, + a31, + a32, + 1 + ); + }, + + /** + * 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)); + } + +}); + +/** + * @ignore + */ +var _tempMat1 = new Matrix4(); + +/** + * @ignore + */ +var _tempMat2 = new Matrix4(); + +/** + * @ignore + */ +var _x = new Vector3(); + +/** + * @ignore + */ +var _y = new Vector3(); + +/** + * @ignore + */ +var _z = new Vector3(); + +module.exports = Matrix4; + + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + "use strict"; /** * @author Richard Davey @@ -16534,7 +16640,7 @@ module.exports = earcut; /***/ }), -/* 68 */ +/* 69 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -16578,7 +16684,7 @@ module.exports = { /***/ }), -/* 69 */ +/* 70 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -16852,8 +16958,8 @@ module.exports = ImageFile; /***/ }), -/* 70 */, -/* 71 */ +/* 71 */, +/* 72 */ /***/ (function(module, exports) { /** @@ -16887,112 +16993,6 @@ var SetTileCollision = function (tile, collides) module.exports = SetTileCollision; -/***/ }), -/* 72 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 Point Light Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - POINTLIGHT_PIPELINE: 'PointLightPipeline', - - /** - * 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', - - /** - * The Graphics and Shapes Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - GRAPHICS_PIPELINE: 'GraphicsPipeline', - - /** - * The Post FX Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - POSTFX_PIPELINE: 'PostFXPipeline', - - /** - * The Utility Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - UTILITY_PIPELINE: 'UtilityPipeline' -}; - -module.exports = PIPELINE_CONST; - - /***/ }), /* 73 */ /***/ (function(module, exports, __webpack_require__) { @@ -17003,7 +17003,7 @@ module.exports = PIPELINE_CONST; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(161); +var AnimationState = __webpack_require__(162); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); @@ -17873,7 +17873,7 @@ module.exports = StableSort; */ var EaseMap = __webpack_require__(132); -var UppercaseFirst = __webpack_require__(200); +var UppercaseFirst = __webpack_require__(202); /** * This internal function is used to return the correct ease function for a Tween. @@ -18055,12 +18055,12 @@ module.exports = StrokePathWebGL; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(110); -var GetPoint = __webpack_require__(454); -var GetPoints = __webpack_require__(455); +var Contains = __webpack_require__(112); +var GetPoint = __webpack_require__(470); +var GetPoints = __webpack_require__(471); var GEOM_CONST = __webpack_require__(55); var Line = __webpack_require__(45); -var Random = __webpack_require__(177); +var Random = __webpack_require__(178); /** * @classdesc @@ -18504,7 +18504,7 @@ module.exports = Triangle; var CONST = __webpack_require__(29); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var Rectangle = __webpack_require__(480); +var Rectangle = __webpack_require__(496); /** * @classdesc @@ -19530,6 +19530,30 @@ module.exports = SetCenterY; /* 88 */ /***/ (function(module, exports, __webpack_require__) { +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Events + */ + +module.exports = { + + POST_RENDER: __webpack_require__(626), + PRE_RENDER: __webpack_require__(627), + RENDER: __webpack_require__(628), + RESIZE: __webpack_require__(629) + +}; + + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + /** * @author Richard Davey * @copyright 2020 Photon Storm Ltd. @@ -19616,7 +19640,7 @@ module.exports = Remove; /***/ }), -/* 89 */ +/* 90 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -19626,7 +19650,7 @@ module.exports = Remove; */ var Class = __webpack_require__(0); -var FromPoints = __webpack_require__(194); +var FromPoints = __webpack_require__(196); var Rectangle = __webpack_require__(10); var Vector2 = __webpack_require__(3); @@ -20233,7 +20257,7 @@ module.exports = Curve; /***/ }), -/* 90 */ +/* 91 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -20263,7 +20287,7 @@ module.exports = { /***/ }), -/* 91 */ +/* 92 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -20339,7 +20363,7 @@ module.exports = LineToLine; /***/ }), -/* 92 */ +/* 93 */ /***/ (function(module, exports) { /** @@ -20367,31 +20391,7 @@ module.exports = Angle; /***/ }), -/* 93 */, -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Renderer.Events - */ - -module.exports = { - - POST_RENDER: __webpack_require__(626), - PRE_RENDER: __webpack_require__(627), - RENDER: __webpack_require__(628), - RESIZE: __webpack_require__(629) - -}; - - -/***/ }), +/* 94 */, /* 95 */ /***/ (function(module, exports, __webpack_require__) { @@ -20401,7 +20401,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); /** * Return a value based on the range between `min` and `max` and the percentage given. @@ -21988,6 +21988,638 @@ module.exports = { /***/ }), /* 104 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WEBGL_CONST = { + + /** + * 8-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.BYTE + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + BYTE: { enum: 0x1400, size: 1 }, + + /** + * 8-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_BYTE + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_BYTE: { enum: 0x1401, size: 1 }, + + /** + * 16-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.SHORT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + SHORT: { enum: 0x1402, size: 2 }, + + /** + * 16-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_SHORT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_SHORT: { enum: 0x1403, size: 2 }, + + /** + * 32-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.INT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + INT: { enum: 0x1404, size: 4 }, + + /** + * 32-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_INT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_INT: { enum: 0x1405, size: 4 }, + + /** + * 32-bit IEEE floating point number. + * + * @name Phaser.Renderer.WebGL.FLOAT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + FLOAT: { enum: 0x1406, size: 4 } + +}; + +module.exports = WEBGL_CONST; + + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); +var ShaderSourceFS = __webpack_require__(874); +var ShaderSourceVS = __webpack_require__(875); +var TransformMatrix = __webpack_require__(25); +var Utils = __webpack_require__(12); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); + +/** + * @classdesc + * + * The Multi Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL. + * Virtually all Game Objects use this pipeline by default, including Sprites, Graphics + * and Tilemaps. It handles the batching of quads and tris, as well as methods for + * drawing and batching geometry data. + * + * Prior to Phaser v3.50 this pipeline was called the `TextureTintPipeline`. + * + * In previous versions of Phaser only one single texture unit was supported at any one time. + * The Multi Pipeline is an evolution of the old Texture Tint Pipeline, updated to support + * multi-textures for increased performance. + * + * The fragment shader it uses can be found in `shaders/src/Multi.frag`. + * The vertex shader it uses can be found in `shaders/src/Multi.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * `inTexId` (float, offset 16) + * `inTintEffect` (float, offset 20) + * `inTint` (vec4, offset 24, normalized) + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uMainSampler` (sampler2D array) + * + * If you wish to create a custom pipeline extending from this one, you can use two string + * declarations in your fragment shader source: `%count%` and `%forloop%`, where `count` is + * used to set the number of `sampler2Ds` available, and `forloop` is a block of GLSL code + * that will get the currently bound texture unit. + * + * This pipeline will automatically inject that code for you, should those values exist + * in your shader source. If you wish to handle this yourself, you can also use the + * function `Utils.parseFragmentShaderMaxTextures`. + * + * If you wish to create a pipeline that works from a single texture, or that doesn't have + * internal texture iteration, please see the `SinglePipeline` instead. + * + * @class MultiPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var MultiPipeline = new Class({ + + Extends: WebGLPipeline, + + initialize: + + function MultiPipeline (config) + { + var renderer = config.game.renderer; + + var fragmentShaderSource = GetFastValue(config, 'fragShader', ShaderSourceFS); + + config.fragShader = Utils.parseFragmentShaderMaxTextures(fragmentShaderSource, renderer.maxTextures); + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inTexCoord', + size: 2 + }, + { + name: 'inTexId' + }, + { + name: 'inTintEffect' + }, + { + name: 'inTint', + size: 4, + type: WEBGL_CONST.UNSIGNED_BYTE, + normalized: true + } + ]); + + WebGLPipeline.call(this, config); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix1 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix1 = new TransformMatrix(); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix2 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix3 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix3 = new TransformMatrix(); + }, + + /** + * Called every time the pipeline is bound by the renderer. + * Sets the shader program, vertex buffer and other resources. + * Should only be called when changing pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#bind + * @since 3.50.0 + * + * @return {this} This WebGLPipeline instance. + */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); + }, + + /** + * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchSprite + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set. + */ + batchSprite: function (gameObject, camera, parentTransformMatrix) + { + this.manager.set(this, gameObject); + + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; + var calcMatrix = this._tempMatrix3; + + var frame = gameObject.frame; + var texture = frame.glTexture; + + var u0 = frame.u0; + var v0 = frame.v0; + var u1 = frame.u1; + var v1 = frame.v1; + var frameX = frame.x; + var frameY = frame.y; + var frameWidth = frame.cutWidth; + var frameHeight = frame.cutHeight; + var customPivot = frame.customPivot; + + var displayOriginX = gameObject.displayOriginX; + var displayOriginY = gameObject.displayOriginY; + + var x = -displayOriginX + frameX; + var y = -displayOriginY + frameY; + + if (gameObject.isCropped) + { + var crop = gameObject._crop; + + if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) + { + frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); + } + + u0 = crop.u0; + v0 = crop.v0; + u1 = crop.u1; + v1 = crop.v1; + + frameWidth = crop.width; + frameHeight = crop.height; + + frameX = crop.x; + frameY = crop.y; + + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } + + var flipX = 1; + var flipY = 1; + + if (gameObject.flipX) + { + if (!customPivot) + { + x += (-frame.realWidth + (displayOriginX * 2)); + } + + flipX = -1; + } + + // Auto-invert the flipY if this is coming from a GLTexture + + if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) + { + if (!customPivot) + { + y += (-frame.realHeight + (displayOriginY * 2)); + } + + flipY = -1; + } + + spriteMatrix.applyITRS(gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); + + camMatrix.copyFrom(camera.matrix); + + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); + + // Undo the camera scroll + spriteMatrix.e = gameObject.x; + spriteMatrix.f = gameObject.y; + } + else + { + spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX; + spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY; + } + + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + + var xw = x + frameWidth; + var yh = y + frameHeight; + + var roundPixels = camera.roundPixels; + + var tx0 = calcMatrix.getXRound(x, y, roundPixels); + var ty0 = calcMatrix.getYRound(x, y, roundPixels); + + var tx1 = calcMatrix.getXRound(x, yh, roundPixels); + var ty1 = calcMatrix.getYRound(x, yh, roundPixels); + + var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); + var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); + + var tx3 = calcMatrix.getXRound(xw, y, roundPixels); + var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + + var getTint = Utils.getTintAppendFloatAlpha; + var cameraAlpha = camera.alpha; + + var tintTL = getTint(gameObject.tintTopLeft, cameraAlpha * gameObject._alphaTL); + var tintTR = getTint(gameObject.tintTopRight, cameraAlpha * gameObject._alphaTR); + var tintBL = getTint(gameObject.tintBottomLeft, cameraAlpha * gameObject._alphaBL); + var tintBR = getTint(gameObject.tintBottomRight, cameraAlpha * gameObject._alphaBR); + + if (this.shouldFlush(6)) + { + this.flush(); + } + + var unit = this.setGameObject(gameObject, frame); + + this.manager.preBatch(gameObject); + + this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); + + this.manager.postBatch(gameObject); + }, + + /** + * Generic function for batching a textured quad using argument values instead of a Game Object. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTexture + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject. + * @param {WebGLTexture} texture - Raw WebGLTexture associated with the quad. + * @param {number} textureWidth - Real texture width. + * @param {number} textureHeight - Real texture height. + * @param {number} srcX - X coordinate of the quad. + * @param {number} srcY - Y coordinate of the quad. + * @param {number} srcWidth - Width of the quad. + * @param {number} srcHeight - Height of the quad. + * @param {number} scaleX - X component of scale. + * @param {number} scaleY - Y component of scale. + * @param {number} rotation - Rotation of the quad. + * @param {boolean} flipX - Indicates if the quad is horizontally flipped. + * @param {boolean} flipY - Indicates if the quad is vertically flipped. + * @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll. + * @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll. + * @param {number} displayOriginX - Horizontal origin in pixels. + * @param {number} displayOriginY - Vertical origin in pixels. + * @param {number} frameX - X coordinate of the texture frame. + * @param {number} frameY - Y coordinate of the texture frame. + * @param {number} frameWidth - Width of the texture frame. + * @param {number} frameHeight - Height of the texture frame. + * @param {number} tintTL - Tint for top left. + * @param {number} tintTR - Tint for top right. + * @param {number} tintBL - Tint for bottom left. + * @param {number} tintBR - Tint for bottom right. + * @param {number} tintEffect - The tint effect. + * @param {number} uOffset - Horizontal offset on texture coordinate. + * @param {number} vOffset - Vertical offset on texture coordinate. + * @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container. + * @param {boolean} [skipFlip=false] - Skip the renderTexture check. + * @param {number} [textureUnit] - Use the currently bound texture unit? + */ + batchTexture: function ( + gameObject, + texture, + textureWidth, textureHeight, + srcX, srcY, + srcWidth, srcHeight, + scaleX, scaleY, + rotation, + flipX, flipY, + scrollFactorX, scrollFactorY, + displayOriginX, displayOriginY, + frameX, frameY, frameWidth, frameHeight, + tintTL, tintTR, tintBL, tintBR, tintEffect, + uOffset, vOffset, + camera, + parentTransformMatrix, + skipFlip, + textureUnit) + { + this.manager.set(this, gameObject); + + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; + var calcMatrix = this._tempMatrix3; + + var u0 = (frameX / textureWidth) + uOffset; + var v0 = (frameY / textureHeight) + vOffset; + var u1 = (frameX + frameWidth) / textureWidth + uOffset; + var v1 = (frameY + frameHeight) / textureHeight + vOffset; + + var width = srcWidth; + var height = srcHeight; + + var x = -displayOriginX; + var y = -displayOriginY; + + if (gameObject.isCropped) + { + var crop = gameObject._crop; + + var cropWidth = crop.width; + var cropHeight = crop.height; + + width = cropWidth; + height = cropHeight; + + srcWidth = cropWidth; + srcHeight = cropHeight; + + frameX = crop.x; + frameY = crop.y; + + var ox = frameX; + var oy = frameY; + + if (flipX) + { + ox = (frameWidth - crop.x - cropWidth); + } + + if (flipY) + { + oy = (frameHeight - crop.y - cropHeight); + } + + u0 = (ox / textureWidth) + uOffset; + v0 = (oy / textureHeight) + vOffset; + u1 = (ox + cropWidth) / textureWidth + uOffset; + v1 = (oy + cropHeight) / textureHeight + vOffset; + + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } + + // Invert the flipY if this is a RenderTexture + flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0); + + if (flipX) + { + width *= -1; + x += srcWidth; + } + + if (flipY) + { + height *= -1; + y += srcHeight; + } + + var xw = x + width; + var yh = y + height; + + spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); + + camMatrix.copyFrom(camera.matrix); + + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); + + // Undo the camera scroll + spriteMatrix.e = srcX; + spriteMatrix.f = srcY; + } + else + { + spriteMatrix.e -= camera.scrollX * scrollFactorX; + spriteMatrix.f -= camera.scrollY * scrollFactorY; + } + + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + + var roundPixels = camera.roundPixels; + + var tx0 = calcMatrix.getXRound(x, y, roundPixels); + var ty0 = calcMatrix.getYRound(x, y, roundPixels); + + var tx1 = calcMatrix.getXRound(x, yh, roundPixels); + var ty1 = calcMatrix.getYRound(x, yh, roundPixels); + + var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); + var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); + + var tx3 = calcMatrix.getXRound(xw, y, roundPixels); + var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + + if (textureUnit === undefined) + { + textureUnit = this.renderer.setTexture2D(texture); + } + + if (gameObject) + { + this.manager.preBatch(gameObject); + } + + this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); + + if (gameObject) + { + this.manager.postBatch(gameObject); + } + }, + + /** + * Adds a Texture Frame into the batch for rendering. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTextureFrame + * @since 3.12.0 + * + * @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered. + * @param {number} x - The horizontal position to render the texture at. + * @param {number} y - The vertical position to render the texture at. + * @param {number} tint - The tint color. + * @param {number} alpha - The alpha value. + * @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix. + */ + batchTextureFrame: function ( + frame, + x, y, + tint, alpha, + transformMatrix, + parentTransformMatrix + ) + { + this.manager.set(this); + + var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); + var calcMatrix = this._tempMatrix2; + + var xw = x + frame.width; + var yh = y + frame.height; + + if (parentTransformMatrix) + { + spriteMatrix.multiply(parentTransformMatrix, calcMatrix); + } + else + { + calcMatrix = spriteMatrix; + } + + var tx0 = calcMatrix.getX(x, y); + var ty0 = calcMatrix.getY(x, y); + + var tx1 = calcMatrix.getX(x, yh); + var ty1 = calcMatrix.getY(x, yh); + + var tx2 = calcMatrix.getX(xw, yh); + var ty2 = calcMatrix.getY(xw, yh); + + var tx3 = calcMatrix.getX(xw, y); + var ty3 = calcMatrix.getY(xw, y); + + var unit = this.renderer.setTextureSource(frame.source); + + tint = Utils.getTintAppendFloatAlpha(tint, alpha); + + this.batchQuad(null, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit); + } + +}); + +module.exports = MultiPipeline; + + +/***/ }), +/* 106 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -21997,8 +22629,8 @@ module.exports = { */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); -var Extend = __webpack_require__(19); +var Clamp = __webpack_require__(18); +var Extend = __webpack_require__(17); /** * @classdesc @@ -22844,7 +23476,7 @@ module.exports = Frame; /***/ }), -/* 105 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -22853,7 +23485,7 @@ module.exports = Frame; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(203); +var ArrayUtils = __webpack_require__(205); var Class = __webpack_require__(0); var NOOP = __webpack_require__(1); var StableSort = __webpack_require__(79); @@ -23660,7 +24292,7 @@ module.exports = List; /***/ }), -/* 106 */ +/* 108 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -23670,11 +24302,11 @@ module.exports = List; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(107); -var GetPoint = __webpack_require__(423); -var GetPoints = __webpack_require__(424); +var Contains = __webpack_require__(109); +var GetPoint = __webpack_require__(439); +var GetPoints = __webpack_require__(440); var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(176); +var Random = __webpack_require__(177); /** * @classdesc @@ -24042,7 +24674,7 @@ module.exports = Ellipse; /***/ }), -/* 107 */ +/* 109 */ /***/ (function(module, exports) { /** @@ -24084,7 +24716,7 @@ module.exports = Contains; /***/ }), -/* 108 */ +/* 110 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -24097,12 +24729,12 @@ var Actions = __webpack_require__(269); var Class = __webpack_require__(0); var Events = __webpack_require__(75); var EventEmitter = __webpack_require__(9); -var GetAll = __webpack_require__(202); +var GetAll = __webpack_require__(204); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var IsPlainObject = __webpack_require__(7); -var Range = __webpack_require__(415); -var Set = __webpack_require__(147); +var Range = __webpack_require__(431); +var Set = __webpack_require__(148); var Sprite = __webpack_require__(73); /** @@ -25812,7 +26444,7 @@ module.exports = Group; /***/ }), -/* 109 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -25874,7 +26506,7 @@ module.exports = FillPathWebGL; /***/ }), -/* 110 */ +/* 112 */ /***/ (function(module, exports) { /** @@ -25927,7 +26559,7 @@ module.exports = Contains; /***/ }), -/* 111 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -25938,7 +26570,7 @@ module.exports = Contains; var Class = __webpack_require__(0); var Rectangle = __webpack_require__(10); -var RectangleToRectangle = __webpack_require__(112); +var RectangleToRectangle = __webpack_require__(114); var Vector2 = __webpack_require__(3); /** @@ -26491,7 +27123,7 @@ module.exports = Face; /***/ }), -/* 112 */ +/* 114 */ /***/ (function(module, exports) { /** @@ -26529,7 +27161,7 @@ module.exports = RectangleToRectangle; /***/ }), -/* 113 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -26540,7 +27172,7 @@ module.exports = RectangleToRectangle; var Class = __webpack_require__(0); var Utils = __webpack_require__(12); -var Vector3 = __webpack_require__(36); +var Vector3 = __webpack_require__(37); /** * @classdesc @@ -26824,9 +27456,9 @@ module.exports = Vertex; /***/ }), -/* 114 */, -/* 115 */, -/* 116 */ +/* 116 */, +/* 117 */, +/* 118 */ /***/ (function(module, exports) { /** @@ -26856,7 +27488,7 @@ module.exports = IsInLayerBounds; /***/ }), -/* 117 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -27096,7 +27728,7 @@ module.exports = LayerData; /***/ }), -/* 118 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -27332,7 +27964,7 @@ module.exports = MapData; /***/ }), -/* 119 */ +/* 121 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -27736,7 +28368,7 @@ module.exports = Tileset; /***/ }), -/* 120 */ +/* 122 */ /***/ (function(module, exports) { /** @@ -27870,7 +28502,7 @@ module.exports = ALIGN_CONST; /***/ }), -/* 121 */ +/* 123 */ /***/ (function(module, exports) { /** @@ -27903,638 +28535,6 @@ var Equal = function (a, b, epsilon) module.exports = Equal; -/***/ }), -/* 122 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var WEBGL_CONST = { - - /** - * 8-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.BYTE - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - BYTE: { enum: 0x1400, size: 1 }, - - /** - * 8-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_BYTE - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_BYTE: { enum: 0x1401, size: 1 }, - - /** - * 16-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.SHORT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - SHORT: { enum: 0x1402, size: 2 }, - - /** - * 16-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_SHORT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_SHORT: { enum: 0x1403, size: 2 }, - - /** - * 32-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.INT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - INT: { enum: 0x1404, size: 4 }, - - /** - * 32-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_INT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_INT: { enum: 0x1405, size: 4 }, - - /** - * 32-bit IEEE floating point number. - * - * @name Phaser.Renderer.WebGL.FLOAT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - FLOAT: { enum: 0x1406, size: 4 } - -}; - -module.exports = WEBGL_CONST; - - -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(874); -var ShaderSourceVS = __webpack_require__(875); -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); - -/** - * @classdesc - * - * The Multi Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL. - * Virtually all Game Objects use this pipeline by default, including Sprites, Graphics - * and Tilemaps. It handles the batching of quads and tris, as well as methods for - * drawing and batching geometry data. - * - * Prior to Phaser v3.50 this pipeline was called the `TextureTintPipeline`. - * - * In previous versions of Phaser only one single texture unit was supported at any one time. - * The Multi Pipeline is an evolution of the old Texture Tint Pipeline, updated to support - * multi-textures for increased performance. - * - * The fragment shader it uses can be found in `shaders/src/Multi.frag`. - * The vertex shader it uses can be found in `shaders/src/Multi.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) - * `inTexId` (float, offset 16) - * `inTintEffect` (float, offset 20) - * `inTint` (vec4, offset 24, normalized) - * - * The default shader uniforms for this pipeline are: - * - * `uProjectionMatrix` (mat4) - * `uMainSampler` (sampler2D array) - * - * If you wish to create a custom pipeline extending from this one, you can use two string - * declarations in your fragment shader source: `%count%` and `%forloop%`, where `count` is - * used to set the number of `sampler2Ds` available, and `forloop` is a block of GLSL code - * that will get the currently bound texture unit. - * - * This pipeline will automatically inject that code for you, should those values exist - * in your shader source. If you wish to handle this yourself, you can also use the - * function `Utils.parseFragmentShaderMaxTextures`. - * - * If you wish to create a pipeline that works from a single texture, or that doesn't have - * internal texture iteration, please see the `SinglePipeline` instead. - * - * @class MultiPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. - */ -var MultiPipeline = new Class({ - - Extends: WebGLPipeline, - - initialize: - - function MultiPipeline (config) - { - var renderer = config.game.renderer; - - var fragmentShaderSource = GetFastValue(config, 'fragShader', ShaderSourceFS); - - config.fragShader = Utils.parseFragmentShaderMaxTextures(fragmentShaderSource, renderer.maxTextures); - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inTexCoord', - size: 2 - }, - { - name: 'inTexId' - }, - { - name: 'inTintEffect' - }, - { - name: 'inTint', - size: 4, - type: WEBGL_CONST.UNSIGNED_BYTE, - normalized: true - } - ]); - - WebGLPipeline.call(this, config); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix1 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix1 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix2 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix3 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix3 = new TransformMatrix(); - }, - - /** - * Called every time the pipeline is bound by the renderer. - * Sets the shader program, vertex buffer and other resources. - * Should only be called when changing pipeline. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#bind - * @since 3.50.0 - * - * @return {this} This WebGLPipeline instance. - */ - boot: function () - { - WebGLPipeline.prototype.boot.call(this); - - this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); - }, - - /** - * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchSprite - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set. - */ - batchSprite: function (gameObject, camera, parentTransformMatrix) - { - this.manager.set(this, gameObject); - - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; - - var frame = gameObject.frame; - var texture = frame.glTexture; - - var u0 = frame.u0; - var v0 = frame.v0; - var u1 = frame.u1; - var v1 = frame.v1; - var frameX = frame.x; - var frameY = frame.y; - var frameWidth = frame.cutWidth; - var frameHeight = frame.cutHeight; - var customPivot = frame.customPivot; - - var displayOriginX = gameObject.displayOriginX; - var displayOriginY = gameObject.displayOriginY; - - var x = -displayOriginX + frameX; - var y = -displayOriginY + frameY; - - if (gameObject.isCropped) - { - var crop = gameObject._crop; - - if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) - { - frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); - } - - u0 = crop.u0; - v0 = crop.v0; - u1 = crop.u1; - v1 = crop.v1; - - frameWidth = crop.width; - frameHeight = crop.height; - - frameX = crop.x; - frameY = crop.y; - - x = -displayOriginX + frameX; - y = -displayOriginY + frameY; - } - - var flipX = 1; - var flipY = 1; - - if (gameObject.flipX) - { - if (!customPivot) - { - x += (-frame.realWidth + (displayOriginX * 2)); - } - - flipX = -1; - } - - // Auto-invert the flipY if this is coming from a GLTexture - - if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) - { - if (!customPivot) - { - y += (-frame.realHeight + (displayOriginY * 2)); - } - - flipY = -1; - } - - spriteMatrix.applyITRS(gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); - - camMatrix.copyFrom(camera.matrix); - - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); - - // Undo the camera scroll - spriteMatrix.e = gameObject.x; - spriteMatrix.f = gameObject.y; - } - else - { - spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX; - spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY; - } - - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(spriteMatrix, calcMatrix); - - var xw = x + frameWidth; - var yh = y + frameHeight; - - var roundPixels = camera.roundPixels; - - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); - - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); - - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); - - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); - - var getTint = Utils.getTintAppendFloatAlpha; - var cameraAlpha = camera.alpha; - - var tintTL = getTint(gameObject.tintTopLeft, cameraAlpha * gameObject._alphaTL); - var tintTR = getTint(gameObject.tintTopRight, cameraAlpha * gameObject._alphaTR); - var tintBL = getTint(gameObject.tintBottomLeft, cameraAlpha * gameObject._alphaBL); - var tintBR = getTint(gameObject.tintBottomRight, cameraAlpha * gameObject._alphaBR); - - if (this.shouldFlush(6)) - { - this.flush(); - } - - var unit = this.setGameObject(gameObject, frame); - - this.manager.preBatch(gameObject); - - this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); - - this.manager.postBatch(gameObject); - }, - - /** - * Generic function for batching a textured quad using argument values instead of a Game Object. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTexture - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject. - * @param {WebGLTexture} texture - Raw WebGLTexture associated with the quad. - * @param {number} textureWidth - Real texture width. - * @param {number} textureHeight - Real texture height. - * @param {number} srcX - X coordinate of the quad. - * @param {number} srcY - Y coordinate of the quad. - * @param {number} srcWidth - Width of the quad. - * @param {number} srcHeight - Height of the quad. - * @param {number} scaleX - X component of scale. - * @param {number} scaleY - Y component of scale. - * @param {number} rotation - Rotation of the quad. - * @param {boolean} flipX - Indicates if the quad is horizontally flipped. - * @param {boolean} flipY - Indicates if the quad is vertically flipped. - * @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll. - * @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll. - * @param {number} displayOriginX - Horizontal origin in pixels. - * @param {number} displayOriginY - Vertical origin in pixels. - * @param {number} frameX - X coordinate of the texture frame. - * @param {number} frameY - Y coordinate of the texture frame. - * @param {number} frameWidth - Width of the texture frame. - * @param {number} frameHeight - Height of the texture frame. - * @param {number} tintTL - Tint for top left. - * @param {number} tintTR - Tint for top right. - * @param {number} tintBL - Tint for bottom left. - * @param {number} tintBR - Tint for bottom right. - * @param {number} tintEffect - The tint effect. - * @param {number} uOffset - Horizontal offset on texture coordinate. - * @param {number} vOffset - Vertical offset on texture coordinate. - * @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container. - * @param {boolean} [skipFlip=false] - Skip the renderTexture check. - * @param {number} [textureUnit] - Use the currently bound texture unit? - */ - batchTexture: function ( - gameObject, - texture, - textureWidth, textureHeight, - srcX, srcY, - srcWidth, srcHeight, - scaleX, scaleY, - rotation, - flipX, flipY, - scrollFactorX, scrollFactorY, - displayOriginX, displayOriginY, - frameX, frameY, frameWidth, frameHeight, - tintTL, tintTR, tintBL, tintBR, tintEffect, - uOffset, vOffset, - camera, - parentTransformMatrix, - skipFlip, - textureUnit) - { - this.manager.set(this, gameObject); - - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; - - var u0 = (frameX / textureWidth) + uOffset; - var v0 = (frameY / textureHeight) + vOffset; - var u1 = (frameX + frameWidth) / textureWidth + uOffset; - var v1 = (frameY + frameHeight) / textureHeight + vOffset; - - var width = srcWidth; - var height = srcHeight; - - var x = -displayOriginX; - var y = -displayOriginY; - - if (gameObject.isCropped) - { - var crop = gameObject._crop; - - var cropWidth = crop.width; - var cropHeight = crop.height; - - width = cropWidth; - height = cropHeight; - - srcWidth = cropWidth; - srcHeight = cropHeight; - - frameX = crop.x; - frameY = crop.y; - - var ox = frameX; - var oy = frameY; - - if (flipX) - { - ox = (frameWidth - crop.x - cropWidth); - } - - if (flipY) - { - oy = (frameHeight - crop.y - cropHeight); - } - - u0 = (ox / textureWidth) + uOffset; - v0 = (oy / textureHeight) + vOffset; - u1 = (ox + cropWidth) / textureWidth + uOffset; - v1 = (oy + cropHeight) / textureHeight + vOffset; - - x = -displayOriginX + frameX; - y = -displayOriginY + frameY; - } - - // Invert the flipY if this is a RenderTexture - flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0); - - if (flipX) - { - width *= -1; - x += srcWidth; - } - - if (flipY) - { - height *= -1; - y += srcHeight; - } - - var xw = x + width; - var yh = y + height; - - spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); - - camMatrix.copyFrom(camera.matrix); - - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); - - // Undo the camera scroll - spriteMatrix.e = srcX; - spriteMatrix.f = srcY; - } - else - { - spriteMatrix.e -= camera.scrollX * scrollFactorX; - spriteMatrix.f -= camera.scrollY * scrollFactorY; - } - - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(spriteMatrix, calcMatrix); - - var roundPixels = camera.roundPixels; - - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); - - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); - - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); - - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); - - if (textureUnit === undefined) - { - textureUnit = this.renderer.setTexture2D(texture); - } - - if (gameObject) - { - this.manager.preBatch(gameObject); - } - - this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); - - if (gameObject) - { - this.manager.postBatch(gameObject); - } - }, - - /** - * Adds a Texture Frame into the batch for rendering. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTextureFrame - * @since 3.12.0 - * - * @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered. - * @param {number} x - The horizontal position to render the texture at. - * @param {number} y - The vertical position to render the texture at. - * @param {number} tint - The tint color. - * @param {number} alpha - The alpha value. - * @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix. - */ - batchTextureFrame: function ( - frame, - x, y, - tint, alpha, - transformMatrix, - parentTransformMatrix - ) - { - this.manager.set(this); - - var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); - var calcMatrix = this._tempMatrix2; - - var xw = x + frame.width; - var yh = y + frame.height; - - if (parentTransformMatrix) - { - spriteMatrix.multiply(parentTransformMatrix, calcMatrix); - } - else - { - calcMatrix = spriteMatrix; - } - - var tx0 = calcMatrix.getX(x, y); - var ty0 = calcMatrix.getY(x, y); - - var tx1 = calcMatrix.getX(x, yh); - var ty1 = calcMatrix.getY(x, yh); - - var tx2 = calcMatrix.getX(xw, yh); - var ty2 = calcMatrix.getY(xw, yh); - - var tx3 = calcMatrix.getX(xw, y); - var ty3 = calcMatrix.getY(xw, y); - - var unit = this.renderer.setTextureSource(frame.source); - - tint = Utils.getTintAppendFloatAlpha(tint, alpha); - - this.batchQuad(null, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit); - } - -}); - -module.exports = MultiPipeline; - - /***/ }), /* 124 */ /***/ (function(module, exports, __webpack_require__) { @@ -28676,9 +28676,9 @@ module.exports = HasValue; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); -var Circle = __webpack_require__(61); -var CircleContains = __webpack_require__(62); +var BlendModes = __webpack_require__(33); +var Circle = __webpack_require__(62); +var CircleContains = __webpack_require__(63); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); @@ -29091,12 +29091,12 @@ module.exports = { var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Rectangle = __webpack_require__(10); var TransformMatrix = __webpack_require__(25); -var ValueToColor = __webpack_require__(183); +var ValueToColor = __webpack_require__(184); var Vector2 = __webpack_require__(3); /** @@ -31888,6 +31888,363 @@ module.exports = Vector4; /***/ }), /* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(88); + +/** + * @classdesc + * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. + * + * Instances of this class are typically created by, and belong to WebGL Pipelines, however + * other Game Objects and classes can take advantage of Render Targets as well. + * + * @class RenderTarget + * @memberof Phaser.Renderer.WebGL + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGLRenderer. + * @param {number} width - The width of this Render Target. + * @param {number} height - The height of this Render Target. + * @param {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. + * @param {number} [minFilter=0] - The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`. + * @param {boolean} [autoClear=true] - Automatically clear this framebuffer when bound? + * @param {boolean} [autoResize=false] - Automatically resize this Render Target if the WebGL Renderer resizes? + */ +var RenderTarget = new Class({ + + initialize: + + function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize) + { + if (scale === undefined) { scale = 1; } + if (minFilter === undefined) { minFilter = 0; } + if (autoClear === undefined) { autoClear = true; } + if (autoResize === undefined) { autoResize = false; } + + /** + * A reference to the WebGLRenderer instance. + * + * @name Phaser.Renderer.WebGL.RenderTarget#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.50.0 + */ + this.renderer = renderer; + + /** + * The WebGLFramebuffer of this Render Target. + * + * This is created in the `RenderTarget.resize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#framebuffer + * @type {WebGLFramebuffer} + * @since 3.50.0 + */ + this.framebuffer = null; + + /** + * The WebGLTexture of this Render Target. + * + * This is created in the `RenderTarget.resize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#texture + * @type {WebGLTexture} + * @since 3.50.0 + */ + this.texture = null; + + /** + * The width of the texture. + * + * @name Phaser.Renderer.WebGL.RenderTarget#width + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.width = 0; + + /** + * The height of the texture. + * + * @name Phaser.Renderer.WebGL.RenderTarget#height + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.height = 0; + + /** + * A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. + * + * A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc. + * + * @name Phaser.Renderer.WebGL.RenderTarget#scale + * @type {number} + * @since 3.50.0 + */ + this.scale = scale; + + /** + * The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`. + * + * @name Phaser.Renderer.WebGL.RenderTarget#minFilter + * @type {number} + * @since 3.50.0 + */ + this.minFilter = minFilter; + + /** + * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) + * during the `RenderTarget.bind` method. + * + * If you need more control over how, or if, the target is cleared, you can disable + * this via the config on creation, or even toggle it directly at runtime. + * + * @name Phaser.Renderer.WebGL.RenderTarget#autoClear + * @type {boolean} + * @since 3.50.0 + */ + this.autoClear = autoClear; + + /** + * Does this Render Target automatically resize when the WebGL Renderer does? + * + * Modify this property via the `setAutoResize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#autoResize + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.autoResize = false; + + this.resize(width, height); + + if (autoResize) + { + this.setAutoResize(true); + } + }, + + /** + * Sets if this Render Target should automatically resize when the WebGL Renderer + * emits a resize event. + * + * @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize + * @since 3.50.0 + * + * @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes? + * + * @return {this} This RenderTarget instance. + */ + setAutoResize: function (autoResize) + { + if (autoResize && !this.autoResize) + { + this.renderer.on(Events.RESIZE, this.resize, this); + + this.autoResize = true; + } + else if (!autoResize && this.autoResize) + { + this.renderer.off(Events.RESIZE, this.resize, this); + + this.autoResize = false; + } + + return this; + }, + + /** + * Resizes this Render Target. + * + * Deletes both the frame buffer and texture, if they exist and then re-creates + * them using the new sizes. + * + * This method is called automatically by the pipeline during its resize handler. + * + * @method Phaser.Renderer.WebGL.RenderTarget#resize + * @since 3.50.0 + * + * @param {number} width - The new width of this Render Target. + * @param {number} height - The new height of this Render Target. + * + * @return {this} This RenderTarget instance. + */ + resize: function (width, height) + { + var scaledWidth = width * this.scale; + var scaledHeight = height * this.scale; + + if (scaledWidth !== this.width || scaledHeight !== this.height) + { + var renderer = this.renderer; + + renderer.deleteFramebuffer(this.framebuffer); + + renderer.deleteTexture(this.texture); + + width *= this.scale; + height *= this.scale; + + this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter); + this.framebuffer = renderer.createFramebuffer(width, height, this.texture, false); + + this.width = width; + this.height = height; + } + + return this; + }, + + /** + * Pushes this Render Target as the current frame buffer of the renderer. + * + * If `autoClear` is set, then clears the texture. + * + * If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport. + * + * @method Phaser.Renderer.WebGL.RenderTarget#bind + * @since 3.50.0 + * + * @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ? + * @param {number} [width] - Optional new width of this Render Target. + * @param {number} [height] - Optional new height of this Render Target. + */ + bind: function (adjustViewport, width, height) + { + if (adjustViewport === undefined) { adjustViewport = false; } + + if (adjustViewport) + { + this.renderer.flush(); + } + + if (width && height) + { + this.resize(width, height); + } + + this.renderer.pushFramebuffer(this.framebuffer, false, false, false); + + if (adjustViewport) + { + this.adjustViewport(); + } + + if (this.autoClear) + { + var gl = this.renderer.gl; + + gl.clearColor(0, 0, 0, 0); + + gl.clear(gl.COLOR_BUFFER_BIT); + } + }, + + /** + * Adjusts the GL viewport to match the width and height of this Render Target. + * + * Also disables `SCISSOR_TEST`. + * + * @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport + * @since 3.50.0 + */ + adjustViewport: function () + { + var gl = this.renderer.gl; + + gl.viewport(0, 0, this.width, this.height); + + gl.disable(gl.SCISSOR_TEST); + }, + + /** + * Clears this Render Target. + * + * @method Phaser.Renderer.WebGL.RenderTarget#clear + * @since 3.50.0 + */ + clear: function () + { + var renderer = this.renderer; + var gl = renderer.gl; + + renderer.pushFramebuffer(this.framebuffer); + + gl.disable(gl.SCISSOR_TEST); + + gl.clearColor(0, 0, 0, 0); + + gl.clear(gl.COLOR_BUFFER_BIT); + + renderer.popFramebuffer(); + + renderer.resetScissor(); + }, + + /** + * Unbinds this Render Target and optionally flushes the WebGL Renderer first. + * + * @name Phaser.Renderer.WebGL.RenderTarget#unbind + * @since 3.50.0 + * + * @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding? + * + * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. + */ + unbind: function (flush) + { + if (flush === undefined) { flush = false; } + + var renderer = this.renderer; + + if (flush) + { + renderer.flush(); + } + + return renderer.popFramebuffer(); + }, + + /** + * Removes all external references from this class and deletes the + * WebGL framebuffer and texture instances. + * + * Does not remove this Render Target from the parent pipeline. + * + * @name Phaser.Renderer.WebGL.RenderTarget#destroy + * @since 3.50.0 + */ + destroy: function () + { + var renderer = this.renderer; + + renderer.deleteFramebuffer(this.framebuffer); + renderer.deleteTexture(this.texture); + + renderer.off(Events.RESIZE, this.resize, this); + + this.renderer = null; + this.framebuffer = null; + this.texture = null; + } + +}); + +module.exports = RenderTarget; + + +/***/ }), +/* 140 */ /***/ (function(module, exports) { /** @@ -31945,7 +32302,7 @@ module.exports = AddToDOM; /***/ }), -/* 140 */ +/* 141 */ /***/ (function(module, exports) { /** @@ -32851,7 +33208,7 @@ module.exports = KeyCodes; /***/ }), -/* 141 */ +/* 142 */ /***/ (function(module, exports) { /** @@ -32974,7 +33331,7 @@ module.exports = CONST; /***/ }), -/* 142 */ +/* 143 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -33019,7 +33376,7 @@ module.exports = Merge; /***/ }), -/* 143 */ +/* 144 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -33032,11 +33389,11 @@ module.exports = Merge; var Class = __webpack_require__(0); var Clone = __webpack_require__(77); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(68); +var Events = __webpack_require__(69); var GameEvents = __webpack_require__(22); var NOOP = __webpack_require__(1); -var GetAll = __webpack_require__(202); -var GetFirst = __webpack_require__(406); +var GetAll = __webpack_require__(204); +var GetFirst = __webpack_require__(422); /** * @classdesc @@ -33733,7 +34090,7 @@ module.exports = BaseSoundManager; /***/ }), -/* 144 */ +/* 145 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -33745,8 +34102,8 @@ module.exports = BaseSoundManager; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(68); -var Extend = __webpack_require__(19); +var Events = __webpack_require__(69); +var Extend = __webpack_require__(17); var NOOP = __webpack_require__(1); /** @@ -34236,7 +34593,7 @@ module.exports = BaseSound; /***/ }), -/* 145 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -34245,8 +34602,8 @@ module.exports = BaseSound; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CheckMatrix = __webpack_require__(204); -var TransposeMatrix = __webpack_require__(413); +var CheckMatrix = __webpack_require__(206); +var TransposeMatrix = __webpack_require__(429); /** * Rotates the array matrix based on the given rotation value. @@ -34322,7 +34679,7 @@ module.exports = RotateMatrix; /***/ }), -/* 146 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -34332,12 +34689,12 @@ module.exports = RotateMatrix; */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var GetBitmapTextSize = __webpack_require__(1037); var ParseFromAtlas = __webpack_require__(1038); -var ParseXMLBitmapFont = __webpack_require__(207); +var ParseXMLBitmapFont = __webpack_require__(209); var Rectangle = __webpack_require__(10); var Render = __webpack_require__(1039); @@ -35411,7 +35768,7 @@ module.exports = BitmapText; /***/ }), -/* 147 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -35860,7 +36217,7 @@ module.exports = Set; /***/ }), -/* 148 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -35872,8 +36229,8 @@ module.exports = Set; var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var IntegerToColor = __webpack_require__(185); -var PIPELINES_CONST = __webpack_require__(72); +var IntegerToColor = __webpack_require__(186); +var PIPELINES_CONST = __webpack_require__(65); var Render = __webpack_require__(1176); /** @@ -36065,7 +36422,7 @@ module.exports = PointLight; /***/ }), -/* 149 */ +/* 150 */ /***/ (function(module, exports) { /** @@ -36119,7 +36476,7 @@ module.exports = CircleToRectangle; /***/ }), -/* 150 */ +/* 151 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36227,7 +36584,7 @@ module.exports = InputPluginCache; /***/ }), -/* 151 */ +/* 152 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36254,7 +36611,7 @@ module.exports = { /***/ }), -/* 152 */ +/* 153 */ /***/ (function(module, exports) { /** @@ -36295,7 +36652,7 @@ module.exports = GetURL; /***/ }), -/* 153 */ +/* 154 */ /***/ (function(module, exports) { /** @@ -36365,7 +36722,7 @@ module.exports = XHRSettings; /***/ }), -/* 154 */ +/* 155 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36375,7 +36732,7 @@ module.exports = XHRSettings; */ var Class = __webpack_require__(0); -var Components = __webpack_require__(238); +var Components = __webpack_require__(240); var Sprite = __webpack_require__(73); /** @@ -36468,7 +36825,7 @@ module.exports = ArcadeSprite; /***/ }), -/* 155 */ +/* 156 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36477,7 +36834,7 @@ module.exports = ArcadeSprite; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var IsInLayerBounds = __webpack_require__(116); +var IsInLayerBounds = __webpack_require__(118); /** * Gets a tile at the given tile coordinates from the given layer. @@ -36523,7 +36880,7 @@ module.exports = GetTileAt; /***/ }), -/* 156 */ +/* 157 */ /***/ (function(module, exports) { /** @@ -36649,7 +37006,7 @@ module.exports = RunCull; /***/ }), -/* 157 */ +/* 158 */ /***/ (function(module, exports) { /** @@ -36687,7 +37044,7 @@ module.exports = SetLayerCollisionIndex; /***/ }), -/* 158 */ +/* 159 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36748,7 +37105,7 @@ module.exports = CreateGroupLayer; /***/ }), -/* 159 */ +/* 160 */ /***/ (function(module, exports) { /** @@ -36812,7 +37169,7 @@ module.exports = GetNewValue; /***/ }), -/* 160 */ +/* 161 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36821,17 +37178,17 @@ module.exports = GetNewValue; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Defaults = __webpack_require__(259); +var Defaults = __webpack_require__(261); var GetAdvancedValue = __webpack_require__(13); var GetBoolean = __webpack_require__(96); var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetProps = __webpack_require__(563); -var GetTargets = __webpack_require__(257); +var GetNewValue = __webpack_require__(160); +var GetProps = __webpack_require__(579); +var GetTargets = __webpack_require__(259); var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(258); -var Tween = __webpack_require__(260); -var TweenData = __webpack_require__(262); +var GetValueOp = __webpack_require__(260); +var Tween = __webpack_require__(262); +var TweenData = __webpack_require__(264); /** * Creates a new Tween. @@ -36945,7 +37302,7 @@ module.exports = TweenBuilder; /***/ }), -/* 161 */ +/* 162 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36958,7 +37315,7 @@ var Class = __webpack_require__(0); var CustomMap = __webpack_require__(99); var GetFastValue = __webpack_require__(2); var Events = __webpack_require__(130); -var Animation = __webpack_require__(181); +var Animation = __webpack_require__(182); /** * @classdesc @@ -38822,8 +39179,9 @@ module.exports = AnimationState; /***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { +/* 163 */, +/* 164 */ +/***/ (function(module, exports) { /** * @author Richard Davey @@ -38831,356 +39189,52 @@ module.exports = AnimationState; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Events = __webpack_require__(94); - /** - * @classdesc - * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. - * - * Instances of this class are typically created by, and belong to WebGL Pipelines, however - * other Game Objects and classes can take advantage of Render Targets as well. - * - * @class RenderTarget - * @memberof Phaser.Renderer.WebGL - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGLRenderer. - * @param {number} width - The width of this Render Target. - * @param {number} height - The height of this Render Target. - * @param {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. - * @param {number} [minFilter=0] - The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`. - * @param {boolean} [autoClear=true] - Automatically clear this framebuffer when bound? - * @param {boolean} [autoResize=false] - Automatically resize this Render Target if the WebGL Renderer resizes? + * Phaser Scale Modes. + * + * @namespace Phaser.ScaleModes + * @since 3.0.0 */ -var RenderTarget = new Class({ - initialize: - - function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize) - { - if (scale === undefined) { scale = 1; } - if (minFilter === undefined) { minFilter = 0; } - if (autoClear === undefined) { autoClear = true; } - if (autoResize === undefined) { autoResize = false; } - - /** - * A reference to the WebGLRenderer instance. - * - * @name Phaser.Renderer.WebGL.RenderTarget#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} - * @since 3.50.0 - */ - this.renderer = renderer; - - /** - * The WebGLFramebuffer of this Render Target. - * - * This is created in the `RenderTarget.resize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#framebuffer - * @type {WebGLFramebuffer} - * @since 3.50.0 - */ - this.framebuffer = null; - - /** - * The WebGLTexture of this Render Target. - * - * This is created in the `RenderTarget.resize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#texture - * @type {WebGLTexture} - * @since 3.50.0 - */ - this.texture = null; - - /** - * The width of the texture. - * - * @name Phaser.Renderer.WebGL.RenderTarget#width - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.width = 0; - - /** - * The height of the texture. - * - * @name Phaser.Renderer.WebGL.RenderTarget#height - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.height = 0; - - /** - * A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. - * - * A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc. - * - * @name Phaser.Renderer.WebGL.RenderTarget#scale - * @type {number} - * @since 3.50.0 - */ - this.scale = scale; - - /** - * The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`. - * - * @name Phaser.Renderer.WebGL.RenderTarget#minFilter - * @type {number} - * @since 3.50.0 - */ - this.minFilter = minFilter; - - /** - * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) - * during the `RenderTarget.bind` method. - * - * If you need more control over how, or if, the target is cleared, you can disable - * this via the config on creation, or even toggle it directly at runtime. - * - * @name Phaser.Renderer.WebGL.RenderTarget#autoClear - * @type {boolean} - * @since 3.50.0 - */ - this.autoClear = autoClear; - - /** - * Does this Render Target automatically resize when the WebGL Renderer does? - * - * Modify this property via the `setAutoResize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#autoResize - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.autoResize = false; - - this.resize(width, height); - - if (autoResize) - { - this.setAutoResize(true); - } - }, +var ScaleModes = { /** - * Sets if this Render Target should automatically resize when the WebGL Renderer - * emits a resize event. - * - * @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize - * @since 3.50.0 - * - * @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes? - * - * @return {this} This RenderTarget instance. + * Default Scale Mode (Linear). + * + * @name Phaser.ScaleModes.DEFAULT + * @type {number} + * @readonly + * @since 3.0.0 */ - setAutoResize: function (autoResize) - { - if (autoResize && !this.autoResize) - { - this.renderer.on(Events.RESIZE, this.resize, this); - - this.autoResize = true; - } - else if (!autoResize && this.autoResize) - { - this.renderer.off(Events.RESIZE, this.resize, this); - - this.autoResize = false; - } - - return this; - }, + DEFAULT: 0, /** - * Resizes this Render Target. - * - * Deletes both the frame buffer and texture, if they exist and then re-creates - * them using the new sizes. - * - * This method is called automatically by the pipeline during its resize handler. - * - * @method Phaser.Renderer.WebGL.RenderTarget#resize - * @since 3.50.0 - * - * @param {number} width - The new width of this Render Target. - * @param {number} height - The new height of this Render Target. - * - * @return {this} This RenderTarget instance. + * Linear Scale Mode. + * + * @name Phaser.ScaleModes.LINEAR + * @type {number} + * @readonly + * @since 3.0.0 */ - resize: function (width, height) - { - var scaledWidth = width * this.scale; - var scaledHeight = height * this.scale; - - if (scaledWidth !== this.width || scaledHeight !== this.height) - { - var renderer = this.renderer; - - renderer.deleteFramebuffer(this.framebuffer); - - renderer.deleteTexture(this.texture); - - width *= this.scale; - height *= this.scale; - - this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter); - this.framebuffer = renderer.createFramebuffer(width, height, this.texture, false); - - this.width = width; - this.height = height; - } - - return this; - }, + LINEAR: 0, /** - * Pushes this Render Target as the current frame buffer of the renderer. - * - * If `autoClear` is set, then clears the texture. - * - * If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport. - * - * @method Phaser.Renderer.WebGL.RenderTarget#bind - * @since 3.50.0 - * - * @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ? - * @param {number} [width] - Optional new width of this Render Target. - * @param {number} [height] - Optional new height of this Render Target. + * Nearest Scale Mode. + * + * @name Phaser.ScaleModes.NEAREST + * @type {number} + * @readonly + * @since 3.0.0 */ - bind: function (adjustViewport, width, height) - { - if (adjustViewport === undefined) { adjustViewport = false; } + NEAREST: 1 - if (adjustViewport) - { - this.renderer.flush(); - } +}; - if (width && height) - { - this.resize(width, height); - } - - this.renderer.pushFramebuffer(this.framebuffer, false, false, false); - - if (adjustViewport) - { - this.adjustViewport(); - } - - if (this.autoClear) - { - var gl = this.renderer.gl; - - gl.clearColor(0, 0, 0, 0); - - gl.clear(gl.COLOR_BUFFER_BIT); - } - }, - - /** - * Adjusts the GL viewport to match the width and height of this Render Target. - * - * Also disables `SCISSOR_TEST`. - * - * @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport - * @since 3.50.0 - */ - adjustViewport: function () - { - var gl = this.renderer.gl; - - gl.viewport(0, 0, this.width, this.height); - - gl.disable(gl.SCISSOR_TEST); - }, - - /** - * Clears this Render Target. - * - * @method Phaser.Renderer.WebGL.RenderTarget#clear - * @since 3.50.0 - */ - clear: function () - { - var renderer = this.renderer; - var gl = renderer.gl; - - renderer.pushFramebuffer(this.framebuffer); - - gl.disable(gl.SCISSOR_TEST); - - gl.clearColor(0, 0, 0, 0); - - gl.clear(gl.COLOR_BUFFER_BIT); - - renderer.popFramebuffer(); - - renderer.resetScissor(); - }, - - /** - * Unbinds this Render Target and optionally flushes the WebGL Renderer first. - * - * @name Phaser.Renderer.WebGL.RenderTarget#unbind - * @since 3.50.0 - * - * @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding? - * - * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. - */ - unbind: function (flush) - { - if (flush === undefined) { flush = false; } - - var renderer = this.renderer; - - if (flush) - { - renderer.flush(); - } - - return renderer.popFramebuffer(); - }, - - /** - * Removes all external references from this class and deletes the - * WebGL framebuffer and texture instances. - * - * Does not remove this Render Target from the parent pipeline. - * - * @name Phaser.Renderer.WebGL.RenderTarget#destroy - * @since 3.50.0 - */ - destroy: function () - { - var renderer = this.renderer; - - renderer.deleteFramebuffer(this.framebuffer); - renderer.deleteTexture(this.texture); - - renderer.off(Events.RESIZE, this.resize, this); - - this.renderer = null; - this.framebuffer = null; - this.texture = null; - } - -}); - -module.exports = RenderTarget; +module.exports = ScaleModes; /***/ }), -/* 163 */, -/* 164 */ +/* 165 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39219,7 +39273,7 @@ module.exports = CircumferencePoint; /***/ }), -/* 165 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39263,7 +39317,7 @@ module.exports = Random; /***/ }), -/* 166 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39344,7 +39398,7 @@ module.exports = GetPoint; /***/ }), -/* 167 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39353,7 +39407,7 @@ module.exports = GetPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); var Point = __webpack_require__(4); /** @@ -39409,7 +39463,7 @@ module.exports = GetPoints; /***/ }), -/* 168 */ +/* 169 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39449,7 +39503,7 @@ module.exports = Random; /***/ }), -/* 169 */ +/* 170 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39487,7 +39541,7 @@ module.exports = Random; /***/ }), -/* 170 */ +/* 171 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39496,8 +39550,8 @@ module.exports = Random; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DeepCopy = __webpack_require__(171); -var PIPELINE_CONST = __webpack_require__(72); +var DeepCopy = __webpack_require__(172); +var PIPELINE_CONST = __webpack_require__(65); var SpliceOne = __webpack_require__(74); /** @@ -39888,7 +39942,7 @@ module.exports = Pipeline; /***/ }), -/* 171 */ +/* 172 */ /***/ (function(module, exports) { /** @@ -39937,7 +39991,7 @@ module.exports = DeepCopy; /***/ }), -/* 172 */ +/* 173 */ /***/ (function(module, exports) { /** @@ -39998,7 +40052,7 @@ module.exports = ToJSON; /***/ }), -/* 173 */ +/* 174 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -40053,7 +40107,7 @@ module.exports = TransformXY; /***/ }), -/* 174 */ +/* 175 */ /***/ (function(module, exports) { /** @@ -40093,7 +40147,7 @@ module.exports = RotateLeft; /***/ }), -/* 175 */ +/* 176 */ /***/ (function(module, exports) { /** @@ -40133,7 +40187,7 @@ module.exports = RotateRight; /***/ }), -/* 176 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -40174,7 +40228,7 @@ module.exports = Random; /***/ }), -/* 177 */ +/* 178 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -40230,7 +40284,7 @@ module.exports = Random; /***/ }), -/* 178 */ +/* 179 */ /***/ (function(module, exports) { /** @@ -40271,7 +40325,7 @@ module.exports = RotateAroundDistance; /***/ }), -/* 179 */ +/* 180 */ /***/ (function(module, exports) { /** @@ -40310,7 +40364,7 @@ module.exports = SmootherStep; /***/ }), -/* 180 */ +/* 181 */ /***/ (function(module, exports) { /** @@ -40357,7 +40411,7 @@ module.exports = SmoothStep; /***/ }), -/* 181 */ +/* 182 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -40366,7 +40420,7 @@ module.exports = SmoothStep; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Events = __webpack_require__(130); var FindClosestInSorted = __webpack_require__(312); @@ -41272,7 +41326,7 @@ module.exports = Animation; /***/ }), -/* 182 */ +/* 183 */ /***/ (function(module, exports) { /** @@ -41348,7 +41402,7 @@ module.exports = Pad; /***/ }), -/* 183 */ +/* 184 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -41358,7 +41412,7 @@ module.exports = Pad; */ var HexStringToColor = __webpack_require__(321); -var IntegerToColor = __webpack_require__(185); +var IntegerToColor = __webpack_require__(186); var ObjectToColor = __webpack_require__(325); var RGBStringToColor = __webpack_require__(326); @@ -41404,7 +41458,7 @@ module.exports = ValueToColor; /***/ }), -/* 184 */ +/* 185 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -41485,7 +41539,7 @@ module.exports = HSVToRGB; /***/ }), -/* 185 */ +/* 186 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -41494,7 +41548,7 @@ module.exports = HSVToRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var IntegerToRGB = __webpack_require__(324); /** @@ -41518,7 +41572,7 @@ module.exports = IntegerToColor; /***/ }), -/* 186 */ +/* 187 */ /***/ (function(module, exports) { /** @@ -41555,7 +41609,7 @@ module.exports = CenterOn; /***/ }), -/* 187 */ +/* 188 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -41747,7 +41801,7 @@ module.exports = init(); /***/ }), -/* 188 */ +/* 189 */ /***/ (function(module, exports) { /** @@ -41879,7 +41933,7 @@ module.exports = Smoothing(); /***/ }), -/* 189 */ +/* 190 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -41889,7 +41943,7 @@ module.exports = Smoothing(); */ var CONST = __webpack_require__(14); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Math @@ -41912,11 +41966,11 @@ var PhaserMath = { // Single functions Average: __webpack_require__(837), Bernstein: __webpack_require__(350), - Between: __webpack_require__(191), - CatmullRom: __webpack_require__(190), + Between: __webpack_require__(192), + CatmullRom: __webpack_require__(191), CeilTo: __webpack_require__(838), - Clamp: __webpack_require__(17), - DegToRad: __webpack_require__(33), + Clamp: __webpack_require__(18), + DegToRad: __webpack_require__(34), Difference: __webpack_require__(839), Euler: __webpack_require__(840), Factorial: __webpack_require__(351), @@ -41930,30 +41984,30 @@ var PhaserMath = { MaxAdd: __webpack_require__(845), MinSub: __webpack_require__(846), Percent: __webpack_require__(847), - RadToDeg: __webpack_require__(192), + RadToDeg: __webpack_require__(193), RandomXY: __webpack_require__(848), RandomXYZ: __webpack_require__(849), RandomXYZW: __webpack_require__(850), Rotate: __webpack_require__(356), RotateAround: __webpack_require__(302), - RotateAroundDistance: __webpack_require__(178), + RotateAroundDistance: __webpack_require__(179), RotateTo: __webpack_require__(851), RoundAwayFromZero: __webpack_require__(357), RoundTo: __webpack_require__(852), SinCosTableGenerator: __webpack_require__(853), - SmootherStep: __webpack_require__(179), - SmoothStep: __webpack_require__(180), + SmootherStep: __webpack_require__(180), + SmoothStep: __webpack_require__(181), ToXY: __webpack_require__(854), - TransformXY: __webpack_require__(173), + TransformXY: __webpack_require__(174), Within: __webpack_require__(855), - Wrap: __webpack_require__(64), + Wrap: __webpack_require__(66), // Vector classes Vector2: __webpack_require__(3), - Vector3: __webpack_require__(36), + Vector3: __webpack_require__(37), Vector4: __webpack_require__(138), Matrix3: __webpack_require__(358), - Matrix4: __webpack_require__(65), + Matrix4: __webpack_require__(67), Quaternion: __webpack_require__(359), RotateVec3: __webpack_require__(856) @@ -41969,7 +42023,7 @@ module.exports = PhaserMath; /***/ }), -/* 190 */ +/* 191 */ /***/ (function(module, exports) { /** @@ -42006,7 +42060,7 @@ module.exports = CatmullRom; /***/ }), -/* 191 */ +/* 192 */ /***/ (function(module, exports) { /** @@ -42035,7 +42089,7 @@ module.exports = Between; /***/ }), -/* 192 */ +/* 193 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42065,7 +42119,7 @@ module.exports = RadToDeg; /***/ }), -/* 193 */ +/* 194 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42167,7 +42221,657 @@ module.exports = DefaultPlugins; /***/ }), -/* 194 */ +/* 195 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * The ColorMatrix class creates a 5x4 matrix that can be used in shaders and graphics + * operations. It provides methods required to modify the color values, such as adjusting + * the brightness, setting a sepia tone, hue rotation and more. + * + * Use the method `getData` to return a Float32Array containing the current color values. + * + * @class ColorMatrix + * @memberof Phaser.Display + * @constructor + * @since 3.50.0 + */ +var ColorMatrix = new Class({ + + initialize: + + function ColorMatrix () + { + /** + * Internal ColorMatrix array. + * + * @name Phaser.Display.ColorMatrix#_matrix + * @type {number[]} + * @private + * @since 3.50.0 + */ + this._matrix = [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + + /** + * The value that determines how much of the original color is used + * when mixing the colors. A value between 0 (all original) and 1 (all final) + * + * @name Phaser.Display.ColorMatrix#alpha + * @type {number} + * @since 3.50.0 + */ + this.alpha = 1; + + /** + * Is the ColorMatrix array dirty? + * + * @name Phaser.Display.ColorMatrix#_dirty + * @type {boolean} + * @private + * @since 3.50.0 + */ + this._dirty = true; + + /** + * The matrix data as a Float32Array. + * + * Returned by the `getData` method. + * + * @name Phaser.Display.ColorMatrix#data + * @type {Float32Array} + * @private + * @since 3.50.0 + */ + this._data; + }, + + /** + * Sets this ColorMatrix from the given array of color values. + * + * @method Phaser.Display.ColorMatrix#set + * @since 3.50.0 + * + * @param {number[]} value - The ColorMatrix values to set. + * + * @return {this} This ColorMatrix instance. + */ + set: function (value) + { + this._matrix = value; + + this._dirty = true; + + return this; + }, + + /** + * Resets the ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#reset + * @since 3.50.0 + * + * @return {this} This ColorMatrix instance. + */ + reset: function () + { + // Long-winded, but saves on gc, which happens a lot in Post FX Shaders + // that reset the ColorMatrix every frame. + + var m = this._matrix; + + m[0] = 1; + m[1] = 0; + m[2] = 0; + m[3] = 0; + m[4] = 0; + + m[5] = 0; + m[6] = 1; + m[7] = 0; + m[8] = 0; + m[9] = 0; + + m[10] = 0; + m[11] = 0; + m[12] = 1; + m[13] = 0; + m[14] = 0; + + m[15] = 0; + m[16] = 0; + m[17] = 0; + m[18] = 1; + m[19] = 0; + + this._dirty = true; + + return this; + }, + + /** + * Gets the ColorMatrix as a Float32Array. + * + * Can be used directly as a 1fv shader uniform value. + * + * @method Phaser.Display.ColorMatrix#getData + * @since 3.50.0 + * + * @return {Float32Array} The ColorMatrix as a Float32Array. + */ + getData: function () + { + if (this._dirty) + { + var f32 = new Float32Array(this._matrix); + + f32[4] /= 255; + f32[9] /= 255; + f32[14] /= 255; + f32[19] /= 255; + + this._data = f32; + + this._dirty = false; + } + + return this._data; + }, + + /** + * Changes the brightness of this ColorMatrix by the given amount. + * + * @method Phaser.Display.ColorMatrix#brightness + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + brightness: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var b = value; + + return this.multiply([ + b, 0, 0, 0, 0, + 0, b, 0, 0, 0, + 0, 0, b, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Changes the saturation of this ColorMatrix by the given amount. + * + * @method Phaser.Display.ColorMatrix#saturate + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + saturate: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var x = (value * 2 / 3) + 1; + var y = ((x - 1) * -0.5); + + return this.multiply([ + x, y, y, 0, 0, + y, x, y, 0, 0, + y, y, x, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Desaturates this ColorMatrix (removes color from it). + * + * @method Phaser.Display.ColorMatrix#saturation + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + desaturate: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.saturate(-1, multiply); + }, + + /** + * Rotates the hues of this ColorMatrix by the value given. + * + * @method Phaser.Display.ColorMatrix#hue + * @since 3.50.0 + * + * @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + hue: function (rotation, multiply) + { + if (rotation === undefined) { rotation = 0; } + if (multiply === undefined) { multiply = false; } + + rotation = rotation / 180 * Math.PI; + + var cos = Math.cos(rotation); + var sin = Math.sin(rotation); + var lumR = 0.213; + var lumG = 0.715; + var lumB = 0.072; + + return this.multiply([ + lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0, + lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0, + lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Sets this ColorMatrix to be grayscale. + * + * @method Phaser.Display.ColorMatrix#grayscale + * @since 3.50.0 + * + * @param {number} [value=1] - The grayscale scale (0 is black). + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + grayscale: function (value, multiply) + { + if (value === undefined) { value = 1; } + if (multiply === undefined) { multiply = false; } + + return this.saturate(-value, multiply); + }, + + /** + * Sets this ColorMatrix to be black and white. + * + * @method Phaser.Display.ColorMatrix#blackWhite + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + blackWhite: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.3, 0.6, 0.1, 0, 0, + 0.3, 0.6, 0.1, 0, 0, + 0.3, 0.6, 0.1, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Change the contrast of this ColorMatrix by the amount given. + * + * @method Phaser.Display.ColorMatrix#contrast + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + contrast: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var v = value + 1; + var o = -0.5 * (v - 1); + + return this.multiply([ + v, 0, 0, 0, o, + 0, v, 0, 0, o, + 0, 0, v, 0, o, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Converts this ColorMatrix to have negative values. + * + * @method Phaser.Display.ColorMatrix#negative + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + negative: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + -1, 0, 0, 1, 0, + 0, -1, 0, 1, 0, + 0, 0, -1, 1, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Apply a desaturated luminance to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#desaturateLuminance + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + desaturateLuminance: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a sepia tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#sepia + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + sepia: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.393, 0.7689999, 0.18899999, 0, 0, + 0.349, 0.6859999, 0.16799999, 0, 0, + 0.272, 0.5339999, 0.13099999, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a night vision tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#night + * @since 3.50.0 + * + * @param {number} [intensity=0.1] - The intensity of this effect. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + night: function (intensity, multiply) + { + if (intensity === undefined) { intensity = 0.1; } + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + intensity * (-2.0), -intensity, 0, 0, 0, + -intensity, 0, intensity, 0, 0, + 0, intensity, intensity * 2.0, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a trippy color tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#lsd + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + lsd: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 2, -0.4, 0.5, 0, 0, + -0.5, 2, -0.4, 0, 0, + -0.4, -0.5, 3, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a brown tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#brown + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + brown: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, + -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, + 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a vintage pinhole color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#vintagePinhole + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + vintagePinhole: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, + 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, + 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a kodachrome color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#kodachrome + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + kodachrome: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, + -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, + -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a technicolor color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#technicolor + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + technicolor: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, + -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, + -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a polaroid color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#polaroid + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + polaroid: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.438, -0.062, -0.062, 0, 0, + -0.122, 1.378, -0.122, 0, 0, + -0.016, -0.016, 1.483, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Shifts the values of this ColorMatrix into BGR order. + * + * @method Phaser.Display.ColorMatrix#shiftToBGR + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + shiftToBGR: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Multiplies the two given matrices. + * + * @method Phaser.Display.ColorMatrix#multiply + * @since 3.50.0 + * + * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix. + * + * @return {this} This ColorMatrix instance. + */ + multiply: function (a, multiply) + { + // Duplicate _matrix into c + + if (!multiply) + { + this.reset(); + } + + var m = this._matrix; + var c = []; + + for (var i = 0; i < 20; i++) + { + c[i] = m[i]; + } + + // R + m[0] = (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]); + m[1] = (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]); + m[2] = (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]); + m[3] = (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]); + m[4] = (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4]; + + // G + m[5] = (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]); + m[6] = (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]); + m[7] = (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]); + m[8] = (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]); + m[9] = (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9]; + + // B + m[10] = (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]); + m[11] = (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]); + m[12] = (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]); + m[13] = (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]); + m[14] = (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14]; + + // A + m[15] = (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]); + m[16] = (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]); + m[17] = (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]); + m[18] = (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]); + m[19] = (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19]; + + this._dirty = true; + + return this; + } + +}); + +module.exports = ColorMatrix; + + +/***/ }), +/* 196 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42253,7 +42957,7 @@ module.exports = FromPoints; /***/ }), -/* 195 */ +/* 197 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42473,7 +43177,7 @@ module.exports = RGB; /***/ }), -/* 196 */ +/* 198 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42484,10 +43188,10 @@ module.exports = RGB; var CONST = { - CENTER: __webpack_require__(381), - ORIENTATION: __webpack_require__(382), - SCALE_MODE: __webpack_require__(383), - ZOOM: __webpack_require__(384) + CENTER: __webpack_require__(397), + ORIENTATION: __webpack_require__(398), + SCALE_MODE: __webpack_require__(399), + ZOOM: __webpack_require__(400) }; @@ -42495,7 +43199,7 @@ module.exports = CONST; /***/ }), -/* 197 */ +/* 199 */ /***/ (function(module, exports) { /** @@ -42524,7 +43228,7 @@ module.exports = RemoveFromDOM; /***/ }), -/* 198 */ +/* 200 */ /***/ (function(module, exports) { /** @@ -42622,7 +43326,7 @@ module.exports = INPUT_CONST; /***/ }), -/* 199 */ +/* 201 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -42632,13 +43336,13 @@ module.exports = INPUT_CONST; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(141); -var DefaultPlugins = __webpack_require__(193); +var CONST = __webpack_require__(142); +var DefaultPlugins = __webpack_require__(194); var Events = __webpack_require__(21); -var GetPhysicsPlugins = __webpack_require__(397); -var GetScenePlugins = __webpack_require__(398); +var GetPhysicsPlugins = __webpack_require__(413); +var GetScenePlugins = __webpack_require__(414); var NOOP = __webpack_require__(1); -var Settings = __webpack_require__(399); +var Settings = __webpack_require__(415); /** * @classdesc @@ -43417,7 +44121,7 @@ module.exports = Systems; /***/ }), -/* 200 */ +/* 202 */ /***/ (function(module, exports) { /** @@ -43454,7 +44158,7 @@ module.exports = UppercaseFirst; /***/ }), -/* 201 */ +/* 203 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43464,8 +44168,8 @@ module.exports = UppercaseFirst; */ var Class = __webpack_require__(0); -var Frame = __webpack_require__(104); -var TextureSource = __webpack_require__(402); +var Frame = __webpack_require__(106); +var TextureSource = __webpack_require__(418); var TEXTURE_MISSING_ERROR = 'Texture.frame missing: '; @@ -43974,7 +44678,7 @@ module.exports = Texture; /***/ }), -/* 202 */ +/* 204 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44036,7 +44740,7 @@ module.exports = GetAll; /***/ }), -/* 203 */ +/* 205 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44060,23 +44764,23 @@ module.exports = { Each: __webpack_require__(1021), EachInRange: __webpack_require__(1022), FindClosestInSorted: __webpack_require__(312), - GetAll: __webpack_require__(202), - GetFirst: __webpack_require__(406), - GetRandom: __webpack_require__(205), + GetAll: __webpack_require__(204), + GetFirst: __webpack_require__(422), + GetRandom: __webpack_require__(207), MoveDown: __webpack_require__(1023), MoveTo: __webpack_require__(1024), MoveUp: __webpack_require__(1025), NumberArray: __webpack_require__(316), NumberArrayStep: __webpack_require__(1026), - QuickSelect: __webpack_require__(414), - Range: __webpack_require__(415), - Remove: __webpack_require__(88), + QuickSelect: __webpack_require__(430), + Range: __webpack_require__(431), + Remove: __webpack_require__(89), RemoveAt: __webpack_require__(1027), RemoveBetween: __webpack_require__(1028), RemoveRandomElement: __webpack_require__(1029), Replace: __webpack_require__(1030), - RotateLeft: __webpack_require__(174), - RotateRight: __webpack_require__(175), + RotateLeft: __webpack_require__(175), + RotateRight: __webpack_require__(176), SafeRange: __webpack_require__(78), SendToBack: __webpack_require__(1031), SetAll: __webpack_require__(1032), @@ -44090,7 +44794,7 @@ module.exports = { /***/ }), -/* 204 */ +/* 206 */ /***/ (function(module, exports) { /** @@ -44152,7 +44856,7 @@ module.exports = CheckMatrix; /***/ }), -/* 205 */ +/* 207 */ /***/ (function(module, exports) { /** @@ -44187,7 +44891,7 @@ module.exports = GetRandom; /***/ }), -/* 206 */ +/* 208 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44198,7 +44902,7 @@ module.exports = GetRandom; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(416); +var Events = __webpack_require__(432); /** * @classdesc @@ -44490,7 +45194,7 @@ module.exports = ProcessQueue; /***/ }), -/* 207 */ +/* 209 */ /***/ (function(module, exports) { /** @@ -44651,7 +45355,7 @@ module.exports = ParseXMLBitmapFont; /***/ }), -/* 208 */ +/* 210 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44661,12 +45365,12 @@ module.exports = ParseXMLBitmapFont; */ var BlitterRender = __webpack_require__(1043); -var Bob = __webpack_require__(418); +var Bob = __webpack_require__(434); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var Frame = __webpack_require__(104); +var Frame = __webpack_require__(106); var GameObject = __webpack_require__(15); -var List = __webpack_require__(105); +var List = __webpack_require__(107); /** * @callback CreateCallback @@ -44950,7 +45654,7 @@ module.exports = Blitter; /***/ }), -/* 209 */ +/* 211 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44960,15 +45664,15 @@ module.exports = Blitter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(203); -var BlendModes = __webpack_require__(38); +var ArrayUtils = __webpack_require__(205); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var Events = __webpack_require__(75); var GameObject = __webpack_require__(15); var Rectangle = __webpack_require__(10); var Render = __webpack_require__(1046); -var Union = __webpack_require__(419); +var Union = __webpack_require__(435); var Vector2 = __webpack_require__(3); /** @@ -46325,7 +47029,7 @@ module.exports = Container; /***/ }), -/* 210 */ +/* 212 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46334,7 +47038,7 @@ module.exports = Container; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var Class = __webpack_require__(0); var Render = __webpack_require__(1051); @@ -46558,7 +47262,7 @@ module.exports = DynamicBitmapText; /***/ }), -/* 211 */ +/* 213 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46569,21 +47273,21 @@ module.exports = DynamicBitmapText; var BaseCamera = __webpack_require__(131); var Class = __webpack_require__(0); -var Commands = __webpack_require__(212); +var Commands = __webpack_require__(214); var ComponentsAlpha = __webpack_require__(297); var ComponentsBlendMode = __webpack_require__(298); var ComponentsDepth = __webpack_require__(299); var ComponentsMask = __webpack_require__(303); -var ComponentsPipeline = __webpack_require__(170); +var ComponentsPipeline = __webpack_require__(171); var ComponentsScrollFactor = __webpack_require__(306); var ComponentsTransform = __webpack_require__(307); var ComponentsVisible = __webpack_require__(308); -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var MATH_CONST = __webpack_require__(14); -var PIPELINES_CONST = __webpack_require__(72); +var PIPELINES_CONST = __webpack_require__(65); var Render = __webpack_require__(1057); /** @@ -48035,7 +48739,7 @@ module.exports = Graphics; /***/ }), -/* 212 */ +/* 214 */ /***/ (function(module, exports) { /** @@ -48070,7 +48774,7 @@ module.exports = { /***/ }), -/* 213 */ +/* 215 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48112,7 +48816,7 @@ module.exports = CircumferencePoint; /***/ }), -/* 214 */ +/* 216 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48121,14 +48825,14 @@ module.exports = CircumferencePoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var ComponentsToJSON = __webpack_require__(172); +var ComponentsToJSON = __webpack_require__(173); var DataManager = __webpack_require__(98); var EventEmitter = __webpack_require__(9); var GameObjectEvents = __webpack_require__(75); -var List = __webpack_require__(105); +var List = __webpack_require__(107); var Render = __webpack_require__(1065); var SceneEvents = __webpack_require__(21); var StableSort = __webpack_require__(79); @@ -48863,7 +49567,7 @@ module.exports = Layer; /***/ }), -/* 215 */ +/* 217 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48875,9 +49579,9 @@ module.exports = Layer; var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var GravityWell = __webpack_require__(428); -var List = __webpack_require__(105); -var ParticleEmitter = __webpack_require__(430); +var GravityWell = __webpack_require__(444); +var List = __webpack_require__(107); +var ParticleEmitter = __webpack_require__(446); var Render = __webpack_require__(1069); /** @@ -49364,7 +50068,7 @@ module.exports = ParticleEmitterManager; /***/ }), -/* 216 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -49373,20 +50077,20 @@ module.exports = ParticleEmitterManager; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Camera = __webpack_require__(131); var CanvasPool = __webpack_require__(31); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var CONST = __webpack_require__(39); -var Frame = __webpack_require__(104); +var Frame = __webpack_require__(106); var GameObject = __webpack_require__(15); var NOOP = __webpack_require__(1); -var PIPELINE_CONST = __webpack_require__(72); +var PIPELINE_CONST = __webpack_require__(65); var Render = __webpack_require__(1073); -var RenderTarget = __webpack_require__(162); +var RenderTarget = __webpack_require__(139); var Utils = __webpack_require__(12); -var UUID = __webpack_require__(217); +var UUID = __webpack_require__(219); /** * @classdesc @@ -50789,7 +51493,7 @@ module.exports = RenderTexture; /***/ }), -/* 217 */ +/* 219 */ /***/ (function(module, exports) { /** @@ -50824,7 +51528,7 @@ module.exports = UUID; /***/ }), -/* 218 */ +/* 220 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -50833,11 +51537,11 @@ module.exports = UUID; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(161); +var AnimationState = __webpack_require__(162); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var PIPELINE_CONST = __webpack_require__(72); +var PIPELINE_CONST = __webpack_require__(65); var RopeRender = __webpack_require__(1079); var Vector2 = __webpack_require__(3); @@ -51949,7 +52653,7 @@ module.exports = Rope; /***/ }), -/* 219 */ +/* 221 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -51958,17 +52662,17 @@ module.exports = Rope; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var CanvasPool = __webpack_require__(31); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameEvents = __webpack_require__(22); var GameObject = __webpack_require__(15); -var GetTextSize = __webpack_require__(436); +var GetTextSize = __webpack_require__(452); var GetValue = __webpack_require__(6); -var RemoveFromDOM = __webpack_require__(197); +var RemoveFromDOM = __webpack_require__(199); var TextRender = __webpack_require__(1082); -var TextStyle = __webpack_require__(437); +var TextStyle = __webpack_require__(453); /** * @classdesc @@ -53366,7 +54070,7 @@ module.exports = Text; /***/ }), -/* 220 */ +/* 222 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -53381,7 +54085,7 @@ var Components = __webpack_require__(11); var GameEvents = __webpack_require__(22); var GameObject = __webpack_require__(15); var GetPowerOfTwo = __webpack_require__(355); -var Smoothing = __webpack_require__(188); +var Smoothing = __webpack_require__(189); var TileSpriteRender = __webpack_require__(1085); var Vector2 = __webpack_require__(3); @@ -54018,7 +54722,7 @@ module.exports = TileSprite; /***/ }), -/* 221 */ +/* 223 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -54028,14 +54732,14 @@ module.exports = TileSprite; */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Components = __webpack_require__(11); var Events = __webpack_require__(75); var GameEvents = __webpack_require__(22); var InputEvents = __webpack_require__(49); var GameObject = __webpack_require__(15); -var SoundEvents = __webpack_require__(68); -var UUID = __webpack_require__(217); +var SoundEvents = __webpack_require__(69); +var UUID = __webpack_require__(219); var VideoRender = __webpack_require__(1088); var MATH_CONST = __webpack_require__(14); @@ -55864,7 +56568,7 @@ module.exports = Video; /***/ }), -/* 222 */ +/* 224 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -55874,8 +56578,8 @@ module.exports = Video; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(223); -var GetPoints = __webpack_require__(448); +var Contains = __webpack_require__(225); +var GetPoints = __webpack_require__(464); var GEOM_CONST = __webpack_require__(55); /** @@ -56098,7 +56802,7 @@ module.exports = Polygon; /***/ }), -/* 223 */ +/* 225 */ /***/ (function(module, exports) { /** @@ -56147,7 +56851,7 @@ module.exports = Contains; /***/ }), -/* 224 */ +/* 226 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -56160,8 +56864,8 @@ var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); -var Extend = __webpack_require__(19); -var SetValue = __webpack_require__(456); +var Extend = __webpack_require__(17); +var SetValue = __webpack_require__(472); var ShaderRender = __webpack_require__(1170); var TransformMatrix = __webpack_require__(25); @@ -57379,7 +58083,7 @@ module.exports = Shader; /***/ }), -/* 225 */ +/* 227 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -57390,17 +58094,17 @@ module.exports = Shader; var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(33); -var Face = __webpack_require__(111); +var DegToRad = __webpack_require__(34); +var Face = __webpack_require__(113); var GameObject = __webpack_require__(15); -var GenerateVerts = __webpack_require__(457); -var GenerateObjVerts = __webpack_require__(458); -var GetCalcMatrix = __webpack_require__(18); -var Matrix4 = __webpack_require__(65); +var GenerateVerts = __webpack_require__(473); +var GenerateObjVerts = __webpack_require__(474); +var GetCalcMatrix = __webpack_require__(19); +var Matrix4 = __webpack_require__(67); var MeshRender = __webpack_require__(1173); var StableSort = __webpack_require__(79); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); /** * @classdesc @@ -58434,7 +59138,7 @@ module.exports = Mesh; /***/ }), -/* 226 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58465,7 +59169,7 @@ module.exports = CircleToCircle; /***/ }), -/* 227 */ +/* 229 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58476,7 +59180,7 @@ module.exports = CircleToCircle; */ var Point = __webpack_require__(4); -var LineToCircle = __webpack_require__(228); +var LineToCircle = __webpack_require__(230); /** * Checks for intersection between the line segment and circle, @@ -58557,7 +59261,7 @@ module.exports = GetLineToCircle; /***/ }), -/* 228 */ +/* 230 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58566,7 +59270,7 @@ module.exports = GetLineToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); var Point = __webpack_require__(4); var tmp = new Point(); @@ -58641,7 +59345,7 @@ module.exports = LineToCircle; /***/ }), -/* 229 */ +/* 231 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58652,8 +59356,8 @@ module.exports = LineToCircle; */ var Point = __webpack_require__(4); -var LineToLine = __webpack_require__(91); -var LineToRectangle = __webpack_require__(466); +var LineToLine = __webpack_require__(92); +var LineToRectangle = __webpack_require__(482); /** * Checks for intersection between the Line and a Rectangle shape, @@ -58701,7 +59405,7 @@ module.exports = GetLineToRectangle; /***/ }), -/* 230 */ +/* 232 */ /***/ (function(module, exports) { /** @@ -58788,7 +59492,7 @@ module.exports = ContainsArray; /***/ }), -/* 231 */ +/* 233 */ /***/ (function(module, exports) { /** @@ -58836,7 +59540,7 @@ module.exports = RotateAroundXY; /***/ }), -/* 232 */ +/* 234 */ /***/ (function(module, exports) { /** @@ -58864,7 +59568,7 @@ module.exports = GetAspectRatio; /***/ }), -/* 233 */ +/* 235 */ /***/ (function(module, exports) { /** @@ -58918,7 +59622,7 @@ module.exports = RotateAroundXY; /***/ }), -/* 234 */ +/* 236 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58944,7 +59648,7 @@ module.exports = { /***/ }), -/* 235 */ +/* 237 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -58953,8 +59657,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var XHRSettings = __webpack_require__(153); +var Extend = __webpack_require__(17); +var XHRSettings = __webpack_require__(154); /** * Takes two XHRSettings Objects and creates a new XHRSettings object from them. @@ -58992,7 +59696,7 @@ module.exports = MergeXHRSettings; /***/ }), -/* 236 */ +/* 238 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59007,7 +59711,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var ParseXML = __webpack_require__(386); +var ParseXML = __webpack_require__(402); /** * @classdesc @@ -59177,7 +59881,7 @@ module.exports = XMLFile; /***/ }), -/* 237 */ +/* 239 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59356,7 +60060,7 @@ module.exports = TextFile; /***/ }), -/* 238 */ +/* 240 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59381,8 +60085,8 @@ module.exports = { Gravity: __webpack_require__(1369), Immovable: __webpack_require__(1370), Mass: __webpack_require__(1371), - OverlapCirc: __webpack_require__(501), - OverlapRect: __webpack_require__(239), + OverlapCirc: __webpack_require__(517), + OverlapRect: __webpack_require__(241), Pushable: __webpack_require__(1372), Size: __webpack_require__(1373), Velocity: __webpack_require__(1374) @@ -59391,7 +60095,7 @@ module.exports = { /***/ }), -/* 239 */ +/* 241 */ /***/ (function(module, exports) { /** @@ -59476,7 +60180,7 @@ module.exports = OverlapRect; /***/ }), -/* 240 */ +/* 242 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59504,7 +60208,7 @@ module.exports = { /***/ }), -/* 241 */ +/* 243 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59513,7 +60217,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); +var CONST = __webpack_require__(60); /** * Calculates and returns the horizontal overlap between two arcade physics bodies and sets their properties @@ -59612,7 +60316,7 @@ module.exports = GetOverlapX; /***/ }), -/* 242 */ +/* 244 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59621,7 +60325,7 @@ module.exports = GetOverlapX; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); +var CONST = __webpack_require__(60); /** * Calculates and returns the vertical overlap between two arcade physics bodies and sets their properties @@ -59720,7 +60424,7 @@ module.exports = GetOverlapY; /***/ }), -/* 243 */ +/* 245 */ /***/ (function(module, exports) { /** @@ -59756,8 +60460,8 @@ module.exports = TileIntersectsBody; /***/ }), -/* 244 */, -/* 245 */ +/* 246 */, +/* 247 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59772,81 +60476,81 @@ module.exports = TileIntersectsBody; module.exports = { - CalculateFacesAt: __webpack_require__(246), - CalculateFacesWithin: __webpack_require__(60), - CheckIsoBounds: __webpack_require__(521), - Copy: __webpack_require__(1407), - CreateFromTiles: __webpack_require__(1408), - CullBounds: __webpack_require__(523), - CullTiles: __webpack_require__(524), - Fill: __webpack_require__(1409), - FilterTiles: __webpack_require__(1410), - FindByIndex: __webpack_require__(1411), - FindTile: __webpack_require__(1412), - ForEachTile: __webpack_require__(1413), - GetCullTilesFunction: __webpack_require__(1414), - GetTileAt: __webpack_require__(155), - GetTileAtWorldXY: __webpack_require__(1415), + CalculateFacesAt: __webpack_require__(248), + CalculateFacesWithin: __webpack_require__(61), + CheckIsoBounds: __webpack_require__(537), + Copy: __webpack_require__(1414), + CreateFromTiles: __webpack_require__(1415), + CullBounds: __webpack_require__(539), + CullTiles: __webpack_require__(540), + Fill: __webpack_require__(1416), + FilterTiles: __webpack_require__(1417), + FindByIndex: __webpack_require__(1418), + FindTile: __webpack_require__(1419), + ForEachTile: __webpack_require__(1420), + GetCullTilesFunction: __webpack_require__(1421), + GetTileAt: __webpack_require__(156), + GetTileAtWorldXY: __webpack_require__(1422), GetTilesWithin: __webpack_require__(26), - GetTilesWithinShape: __webpack_require__(1416), - GetTilesWithinWorldXY: __webpack_require__(507), - GetTileToWorldXFunction: __webpack_require__(1417), - GetTileToWorldXYFunction: __webpack_require__(1418), - GetTileToWorldYFunction: __webpack_require__(1419), - GetWorldToTileXFunction: __webpack_require__(1420), - GetWorldToTileXYFunction: __webpack_require__(1421), - GetWorldToTileYFunction: __webpack_require__(1422), - HasTileAt: __webpack_require__(542), - HasTileAtWorldXY: __webpack_require__(1423), - HexagonalCullBounds: __webpack_require__(526), - HexagonalCullTiles: __webpack_require__(525), - HexagonalTileToWorldXY: __webpack_require__(530), - HexagonalTileToWorldY: __webpack_require__(534), - HexagonalWorldToTileXY: __webpack_require__(536), - HexagonalWorldToTileY: __webpack_require__(540), - IsInLayerBounds: __webpack_require__(116), - IsometricCullTiles: __webpack_require__(527), - IsometricTileToWorldXY: __webpack_require__(531), - IsometricWorldToTileXY: __webpack_require__(537), - PutTileAt: __webpack_require__(251), - PutTileAtWorldXY: __webpack_require__(1424), - PutTilesAt: __webpack_require__(1425), - Randomize: __webpack_require__(1426), - RemoveTileAt: __webpack_require__(543), - RemoveTileAtWorldXY: __webpack_require__(1427), - RenderDebug: __webpack_require__(1428), - ReplaceByIndex: __webpack_require__(522), - RunCull: __webpack_require__(156), - SetCollision: __webpack_require__(1429), - SetCollisionBetween: __webpack_require__(1430), - SetCollisionByExclusion: __webpack_require__(1431), - SetCollisionByProperty: __webpack_require__(1432), - SetCollisionFromCollisionGroup: __webpack_require__(1433), - SetLayerCollisionIndex: __webpack_require__(157), - SetTileCollision: __webpack_require__(71), - SetTileIndexCallback: __webpack_require__(1434), - SetTileLocationCallback: __webpack_require__(1435), - Shuffle: __webpack_require__(1436), - StaggeredCullBounds: __webpack_require__(529), - StaggeredCullTiles: __webpack_require__(528), - StaggeredTileToWorldXY: __webpack_require__(532), - StaggeredTileToWorldY: __webpack_require__(535), - StaggeredWorldToTileXY: __webpack_require__(538), - StaggeredWorldToTileY: __webpack_require__(541), - SwapByIndex: __webpack_require__(1437), - TileToWorldX: __webpack_require__(247), - TileToWorldXY: __webpack_require__(533), - TileToWorldY: __webpack_require__(248), - WeightedRandomize: __webpack_require__(1438), - WorldToTileX: __webpack_require__(249), - WorldToTileXY: __webpack_require__(539), - WorldToTileY: __webpack_require__(250) + GetTilesWithinShape: __webpack_require__(1423), + GetTilesWithinWorldXY: __webpack_require__(523), + GetTileToWorldXFunction: __webpack_require__(1424), + GetTileToWorldXYFunction: __webpack_require__(1425), + GetTileToWorldYFunction: __webpack_require__(1426), + GetWorldToTileXFunction: __webpack_require__(1427), + GetWorldToTileXYFunction: __webpack_require__(1428), + GetWorldToTileYFunction: __webpack_require__(1429), + HasTileAt: __webpack_require__(558), + HasTileAtWorldXY: __webpack_require__(1430), + HexagonalCullBounds: __webpack_require__(542), + HexagonalCullTiles: __webpack_require__(541), + HexagonalTileToWorldXY: __webpack_require__(546), + HexagonalTileToWorldY: __webpack_require__(550), + HexagonalWorldToTileXY: __webpack_require__(552), + HexagonalWorldToTileY: __webpack_require__(556), + IsInLayerBounds: __webpack_require__(118), + IsometricCullTiles: __webpack_require__(543), + IsometricTileToWorldXY: __webpack_require__(547), + IsometricWorldToTileXY: __webpack_require__(553), + PutTileAt: __webpack_require__(253), + PutTileAtWorldXY: __webpack_require__(1431), + PutTilesAt: __webpack_require__(1432), + Randomize: __webpack_require__(1433), + RemoveTileAt: __webpack_require__(559), + RemoveTileAtWorldXY: __webpack_require__(1434), + RenderDebug: __webpack_require__(1435), + ReplaceByIndex: __webpack_require__(538), + RunCull: __webpack_require__(157), + SetCollision: __webpack_require__(1436), + SetCollisionBetween: __webpack_require__(1437), + SetCollisionByExclusion: __webpack_require__(1438), + SetCollisionByProperty: __webpack_require__(1439), + SetCollisionFromCollisionGroup: __webpack_require__(1440), + SetLayerCollisionIndex: __webpack_require__(158), + SetTileCollision: __webpack_require__(72), + SetTileIndexCallback: __webpack_require__(1441), + SetTileLocationCallback: __webpack_require__(1442), + Shuffle: __webpack_require__(1443), + StaggeredCullBounds: __webpack_require__(545), + StaggeredCullTiles: __webpack_require__(544), + StaggeredTileToWorldXY: __webpack_require__(548), + StaggeredTileToWorldY: __webpack_require__(551), + StaggeredWorldToTileXY: __webpack_require__(554), + StaggeredWorldToTileY: __webpack_require__(557), + SwapByIndex: __webpack_require__(1444), + TileToWorldX: __webpack_require__(249), + TileToWorldXY: __webpack_require__(549), + TileToWorldY: __webpack_require__(250), + WeightedRandomize: __webpack_require__(1445), + WorldToTileX: __webpack_require__(251), + WorldToTileXY: __webpack_require__(555), + WorldToTileY: __webpack_require__(252) }; /***/ }), -/* 246 */ +/* 248 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59855,7 +60559,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTileAt = __webpack_require__(155); +var GetTileAt = __webpack_require__(156); /** * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting @@ -59940,7 +60644,7 @@ module.exports = CalculateFacesAt; /***/ }), -/* 247 */ +/* 249 */ /***/ (function(module, exports) { /** @@ -59984,7 +60688,7 @@ module.exports = TileToWorldX; /***/ }), -/* 248 */ +/* 250 */ /***/ (function(module, exports) { /** @@ -60028,7 +60732,7 @@ module.exports = TileToWorldY; /***/ }), -/* 249 */ +/* 251 */ /***/ (function(module, exports) { /** @@ -60076,7 +60780,7 @@ module.exports = WorldToTileX; /***/ }), -/* 250 */ +/* 252 */ /***/ (function(module, exports) { /** @@ -60124,7 +60828,7 @@ module.exports = WorldToTileY; /***/ }), -/* 251 */ +/* 253 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60134,9 +60838,9 @@ module.exports = WorldToTileY; */ var Tile = __webpack_require__(83); -var IsInLayerBounds = __webpack_require__(116); -var CalculateFacesAt = __webpack_require__(246); -var SetTileCollision = __webpack_require__(71); +var IsInLayerBounds = __webpack_require__(118); +var CalculateFacesAt = __webpack_require__(248); +var SetTileCollision = __webpack_require__(72); /** * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index @@ -60209,7 +60913,7 @@ module.exports = PutTileAt; /***/ }), -/* 252 */ +/* 254 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60256,7 +60960,7 @@ module.exports = FromOrientationString; /***/ }), -/* 253 */ +/* 255 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60265,9 +60969,9 @@ module.exports = FromOrientationString; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(37); -var LayerData = __webpack_require__(117); -var MapData = __webpack_require__(118); +var Formats = __webpack_require__(38); +var LayerData = __webpack_require__(119); +var MapData = __webpack_require__(120); var Tile = __webpack_require__(83); /** @@ -60348,7 +61052,7 @@ module.exports = Parse2DArray; /***/ }), -/* 254 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60357,8 +61061,8 @@ module.exports = Parse2DArray; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Pick = __webpack_require__(551); -var ParseGID = __webpack_require__(255); +var Pick = __webpack_require__(567); +var ParseGID = __webpack_require__(257); var copyPoints = function (p) { return { x: p.x, y: p.y }; }; @@ -60428,7 +61132,7 @@ module.exports = ParseObject; /***/ }), -/* 255 */ +/* 257 */ /***/ (function(module, exports) { /** @@ -60518,7 +61222,7 @@ module.exports = ParseGID; /***/ }), -/* 256 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60527,10 +61231,10 @@ module.exports = ParseGID; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(37); -var MapData = __webpack_require__(118); -var Parse = __webpack_require__(544); -var Tilemap = __webpack_require__(560); +var Formats = __webpack_require__(38); +var MapData = __webpack_require__(120); +var Parse = __webpack_require__(560); +var Tilemap = __webpack_require__(576); /** * Create a Tilemap from the given key or data. If neither is given, make a blank Tilemap. When @@ -60604,7 +61308,7 @@ module.exports = ParseToTilemap; /***/ }), -/* 257 */ +/* 259 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60653,7 +61357,7 @@ module.exports = GetTargets; /***/ }), -/* 258 */ +/* 260 */ /***/ (function(module, exports) { /** @@ -60921,7 +61625,7 @@ module.exports = GetValueOp; /***/ }), -/* 259 */ +/* 261 */ /***/ (function(module, exports) { /** @@ -60965,7 +61669,7 @@ module.exports = TWEEN_DEFAULTS; /***/ }), -/* 260 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -60976,7 +61680,7 @@ module.exports = TWEEN_DEFAULTS; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(261); +var Events = __webpack_require__(263); var GameObjectCreator = __webpack_require__(16); var GameObjectFactory = __webpack_require__(5); var TWEEN_CONST = __webpack_require__(97); @@ -62608,7 +63312,7 @@ module.exports = Tween; /***/ }), -/* 261 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62623,26 +63327,26 @@ module.exports = Tween; module.exports = { - TIMELINE_COMPLETE: __webpack_require__(1452), - TIMELINE_LOOP: __webpack_require__(1453), - TIMELINE_PAUSE: __webpack_require__(1454), - TIMELINE_RESUME: __webpack_require__(1455), - TIMELINE_START: __webpack_require__(1456), - TIMELINE_UPDATE: __webpack_require__(1457), - TWEEN_ACTIVE: __webpack_require__(1458), - TWEEN_COMPLETE: __webpack_require__(1459), - TWEEN_LOOP: __webpack_require__(1460), - TWEEN_REPEAT: __webpack_require__(1461), - TWEEN_START: __webpack_require__(1462), - TWEEN_STOP: __webpack_require__(1463), - TWEEN_UPDATE: __webpack_require__(1464), - TWEEN_YOYO: __webpack_require__(1465) + TIMELINE_COMPLETE: __webpack_require__(1459), + TIMELINE_LOOP: __webpack_require__(1460), + TIMELINE_PAUSE: __webpack_require__(1461), + TIMELINE_RESUME: __webpack_require__(1462), + TIMELINE_START: __webpack_require__(1463), + TIMELINE_UPDATE: __webpack_require__(1464), + TWEEN_ACTIVE: __webpack_require__(1465), + TWEEN_COMPLETE: __webpack_require__(1466), + TWEEN_LOOP: __webpack_require__(1467), + TWEEN_REPEAT: __webpack_require__(1468), + TWEEN_START: __webpack_require__(1469), + TWEEN_STOP: __webpack_require__(1470), + TWEEN_UPDATE: __webpack_require__(1471), + TWEEN_YOYO: __webpack_require__(1472) }; /***/ }), -/* 262 */ +/* 264 */ /***/ (function(module, exports) { /** @@ -62769,61 +63473,7 @@ module.exports = TweenData; /***/ }), -/* 263 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Modes. - * - * @namespace Phaser.ScaleModes - * @since 3.0.0 - */ - -var ScaleModes = { - - /** - * Default Scale Mode (Linear). - * - * @name Phaser.ScaleModes.DEFAULT - * @type {number} - * @readonly - * @since 3.0.0 - */ - DEFAULT: 0, - - /** - * Linear Scale Mode. - * - * @name Phaser.ScaleModes.LINEAR - * @type {number} - * @readonly - * @since 3.0.0 - */ - LINEAR: 0, - - /** - * Nearest Scale Mode. - * - * @name Phaser.ScaleModes.NEAREST - * @type {number} - * @readonly - * @since 3.0.0 - */ - NEAREST: 1 - -}; - -module.exports = ScaleModes; - - -/***/ }), -/* 264 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62832,7 +63482,7 @@ module.exports = ScaleModes; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathWrap = __webpack_require__(64); +var MathWrap = __webpack_require__(66); /** * Wrap an angle. @@ -62855,7 +63505,7 @@ module.exports = Wrap; /***/ }), -/* 265 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62864,7 +63514,7 @@ module.exports = Wrap; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Wrap = __webpack_require__(64); +var Wrap = __webpack_require__(66); /** * Wrap an angle in degrees. @@ -62886,656 +63536,6 @@ var WrapDegrees = function (angle) module.exports = WrapDegrees; -/***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * The ColorMatrix class creates a 5x4 matrix that can be used in shaders and graphics - * operations. It provides methods required to modify the color values, such as adjusting - * the brightness, setting a sepia tone, hue rotation and more. - * - * Use the method `getData` to return a Float32Array containing the current color values. - * - * @class ColorMatrix - * @memberof Phaser.Display - * @constructor - * @since 3.50.0 - */ -var ColorMatrix = new Class({ - - initialize: - - function ColorMatrix () - { - /** - * Internal ColorMatrix array. - * - * @name Phaser.Display.ColorMatrix#_matrix - * @type {number[]} - * @private - * @since 3.50.0 - */ - this._matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - - /** - * The value that determines how much of the original color is used - * when mixing the colors. A value between 0 (all original) and 1 (all final) - * - * @name Phaser.Display.ColorMatrix#alpha - * @type {number} - * @since 3.50.0 - */ - this.alpha = 1; - - /** - * Is the ColorMatrix array dirty? - * - * @name Phaser.Display.ColorMatrix#_dirty - * @type {boolean} - * @private - * @since 3.50.0 - */ - this._dirty = true; - - /** - * The matrix data as a Float32Array. - * - * Returned by the `getData` method. - * - * @name Phaser.Display.ColorMatrix#data - * @type {Float32Array} - * @private - * @since 3.50.0 - */ - this._data; - }, - - /** - * Sets this ColorMatrix from the given array of color values. - * - * @method Phaser.Display.ColorMatrix#set - * @since 3.50.0 - * - * @param {number[]} value - The ColorMatrix values to set. - * - * @return {this} This ColorMatrix instance. - */ - set: function (value) - { - this._matrix = value; - - this._dirty = true; - - return this; - }, - - /** - * Resets the ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#reset - * @since 3.50.0 - * - * @return {this} This ColorMatrix instance. - */ - reset: function () - { - // Long-winded, but saves on gc, which happens a lot in Post FX Shaders - // that reset the ColorMatrix every frame. - - var m = this._matrix; - - m[0] = 1; - m[1] = 0; - m[2] = 0; - m[3] = 0; - m[4] = 0; - - m[5] = 0; - m[6] = 1; - m[7] = 0; - m[8] = 0; - m[9] = 0; - - m[10] = 0; - m[11] = 0; - m[12] = 1; - m[13] = 0; - m[14] = 0; - - m[15] = 0; - m[16] = 0; - m[17] = 0; - m[18] = 1; - m[19] = 0; - - this._dirty = true; - - return this; - }, - - /** - * Gets the ColorMatrix as a Float32Array. - * - * Can be used directly as a 1fv shader uniform value. - * - * @method Phaser.Display.ColorMatrix#getData - * @since 3.50.0 - * - * @return {Float32Array} The ColorMatrix as a Float32Array. - */ - getData: function () - { - if (this._dirty) - { - var f32 = new Float32Array(this._matrix); - - f32[4] /= 255; - f32[9] /= 255; - f32[14] /= 255; - f32[19] /= 255; - - this._data = f32; - - this._dirty = false; - } - - return this._data; - }, - - /** - * Changes the brightness of this ColorMatrix by the given amount. - * - * @method Phaser.Display.ColorMatrix#brightness - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - brightness: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var b = value; - - return this.multiply([ - b, 0, 0, 0, 0, - 0, b, 0, 0, 0, - 0, 0, b, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Changes the saturation of this ColorMatrix by the given amount. - * - * @method Phaser.Display.ColorMatrix#saturate - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - saturate: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var x = (value * 2 / 3) + 1; - var y = ((x - 1) * -0.5); - - return this.multiply([ - x, y, y, 0, 0, - y, x, y, 0, 0, - y, y, x, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Desaturates this ColorMatrix (removes color from it). - * - * @method Phaser.Display.ColorMatrix#saturation - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - desaturate: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.saturate(-1, multiply); - }, - - /** - * Rotates the hues of this ColorMatrix by the value given. - * - * @method Phaser.Display.ColorMatrix#hue - * @since 3.50.0 - * - * @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - hue: function (rotation, multiply) - { - if (rotation === undefined) { rotation = 0; } - if (multiply === undefined) { multiply = false; } - - rotation = rotation / 180 * Math.PI; - - var cos = Math.cos(rotation); - var sin = Math.sin(rotation); - var lumR = 0.213; - var lumG = 0.715; - var lumB = 0.072; - - return this.multiply([ - lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0, - lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0, - lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Sets this ColorMatrix to be grayscale. - * - * @method Phaser.Display.ColorMatrix#grayscale - * @since 3.50.0 - * - * @param {number} [value=1] - The grayscale scale (0 is black). - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - grayscale: function (value, multiply) - { - if (value === undefined) { value = 1; } - if (multiply === undefined) { multiply = false; } - - return this.saturate(-value, multiply); - }, - - /** - * Sets this ColorMatrix to be black and white. - * - * @method Phaser.Display.ColorMatrix#blackWhite - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - blackWhite: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.3, 0.6, 0.1, 0, 0, - 0.3, 0.6, 0.1, 0, 0, - 0.3, 0.6, 0.1, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Change the contrast of this ColorMatrix by the amount given. - * - * @method Phaser.Display.ColorMatrix#contrast - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - contrast: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var v = value + 1; - var o = -0.5 * (v - 1); - - return this.multiply([ - v, 0, 0, 0, o, - 0, v, 0, 0, o, - 0, 0, v, 0, o, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Converts this ColorMatrix to have negative values. - * - * @method Phaser.Display.ColorMatrix#negative - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - negative: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - -1, 0, 0, 1, 0, - 0, -1, 0, 1, 0, - 0, 0, -1, 1, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Apply a desaturated luminance to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#desaturateLuminance - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - desaturateLuminance: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a sepia tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#sepia - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - sepia: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.393, 0.7689999, 0.18899999, 0, 0, - 0.349, 0.6859999, 0.16799999, 0, 0, - 0.272, 0.5339999, 0.13099999, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a night vision tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#night - * @since 3.50.0 - * - * @param {number} [intensity=0.1] - The intensity of this effect. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - night: function (intensity, multiply) - { - if (intensity === undefined) { intensity = 0.1; } - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - intensity * (-2.0), -intensity, 0, 0, 0, - -intensity, 0, intensity, 0, 0, - 0, intensity, intensity * 2.0, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a trippy color tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#lsd - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - lsd: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 2, -0.4, 0.5, 0, 0, - -0.5, 2, -0.4, 0, 0, - -0.4, -0.5, 3, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a brown tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#brown - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - brown: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, - -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, - 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a vintage pinhole color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#vintagePinhole - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - vintagePinhole: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, - 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, - 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a kodachrome color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#kodachrome - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - kodachrome: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, - -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, - -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a technicolor color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#technicolor - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - technicolor: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, - -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, - -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a polaroid color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#polaroid - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - polaroid: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.438, -0.062, -0.062, 0, 0, - -0.122, 1.378, -0.122, 0, 0, - -0.016, -0.016, 1.483, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Shifts the values of this ColorMatrix into BGR order. - * - * @method Phaser.Display.ColorMatrix#shiftToBGR - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - shiftToBGR: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Multiplies the two given matrices. - * - * @method Phaser.Display.ColorMatrix#multiply - * @since 3.50.0 - * - * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix. - * - * @return {this} This ColorMatrix instance. - */ - multiply: function (a, multiply) - { - // Duplicate _matrix into c - - if (!multiply) - { - this.reset(); - } - - var m = this._matrix; - var c = []; - - for (var i = 0; i < 20; i++) - { - c[i] = m[i]; - } - - // R - m[0] = (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]); - m[1] = (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]); - m[2] = (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]); - m[3] = (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]); - m[4] = (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4]; - - // G - m[5] = (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]); - m[6] = (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]); - m[7] = (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]); - m[8] = (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]); - m[9] = (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9]; - - // B - m[10] = (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]); - m[11] = (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]); - m[12] = (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]); - m[13] = (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]); - m[14] = (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14]; - - // A - m[15] = (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]); - m[16] = (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]); - m[17] = (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]); - m[18] = (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]); - m[19] = (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19]; - - this._dirty = true; - - return this; - } - -}); - -module.exports = ColorMatrix; - - /***/ }), /* 267 */, /* 268 */, @@ -63621,7 +63621,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = __webpack_require__(120); +var ALIGN_CONST = __webpack_require__(122); var AlignToMap = []; @@ -64201,7 +64201,7 @@ module.exports = TopRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = __webpack_require__(120); +var ALIGN_CONST = __webpack_require__(122); var AlignInMap = []; @@ -64685,7 +64685,7 @@ module.exports = TopRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CircumferencePoint = __webpack_require__(164); +var CircumferencePoint = __webpack_require__(165); var FromPercent = __webpack_require__(95); var MATH_CONST = __webpack_require__(14); var Point = __webpack_require__(4); @@ -64729,7 +64729,7 @@ module.exports = GetPoint; */ var Circumference = __webpack_require__(296); -var CircumferencePoint = __webpack_require__(164); +var CircumferencePoint = __webpack_require__(165); var FromPercent = __webpack_require__(95); var MATH_CONST = __webpack_require__(14); @@ -64808,7 +64808,7 @@ module.exports = Circumference; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); // bitmask flag for GameObject.renderMask var _FLAG = 2; // 0010 @@ -64918,7 +64918,7 @@ module.exports = AlphaSingle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); /** * Provides methods used for setting the blend mode of a Game Object. @@ -65137,7 +65137,7 @@ module.exports = Depth; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetPoint = __webpack_require__(166); +var GetPoint = __webpack_require__(167); var Perimeter = __webpack_require__(128); // Return an array of points from the perimeter of the rectangle @@ -65425,7 +65425,7 @@ module.exports = Mask; var Class = __webpack_require__(0); var GameEvents = __webpack_require__(22); -var RenderEvents = __webpack_require__(94); +var RenderEvents = __webpack_require__(88); /** * @classdesc @@ -66169,9 +66169,9 @@ module.exports = ScrollFactor; var MATH_CONST = __webpack_require__(14); var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(173); -var WrapAngle = __webpack_require__(264); -var WrapAngleDegrees = __webpack_require__(265); +var TransformXY = __webpack_require__(174); +var WrapAngle = __webpack_require__(265); +var WrapAngleDegrees = __webpack_require__(266); var Vector2 = __webpack_require__(3); // global bitmask flag for GameObject.renderMask (used by Scale) @@ -67394,7 +67394,7 @@ module.exports = SortByDigits; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Animation = __webpack_require__(181); +var Animation = __webpack_require__(182); var Class = __webpack_require__(0); var CustomMap = __webpack_require__(99); var EventEmitter = __webpack_require__(9); @@ -67402,7 +67402,7 @@ var Events = __webpack_require__(130); var GameEvents = __webpack_require__(22); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); -var Pad = __webpack_require__(182); +var Pad = __webpack_require__(183); var NumberArray = __webpack_require__(316); /** @@ -68939,12 +68939,12 @@ module.exports = CacheManager; */ var BaseCamera = __webpack_require__(131); -var CenterOn = __webpack_require__(186); -var Clamp = __webpack_require__(17); +var CenterOn = __webpack_require__(187); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var Effects = __webpack_require__(327); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Linear = __webpack_require__(133); var Rectangle = __webpack_require__(10); var Vector2 = __webpack_require__(3); @@ -69747,7 +69747,7 @@ module.exports = Camera; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts a hex string into a Phaser Color object. @@ -69959,7 +69959,7 @@ module.exports = IntegerToRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts an object containing `r`, `g`, `b` and `a` properties into a Color class instance. @@ -69989,7 +69989,7 @@ module.exports = ObjectToColor; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts a CSS 'web' string into a Phaser Color object. @@ -70327,10 +70327,10 @@ var Device = __webpack_require__(341); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var IsPlainObject = __webpack_require__(7); -var PhaserMath = __webpack_require__(189); +var PhaserMath = __webpack_require__(190); var NOOP = __webpack_require__(1); -var DefaultPlugins = __webpack_require__(193); -var ValueToColor = __webpack_require__(183); +var DefaultPlugins = __webpack_require__(194); +var ValueToColor = __webpack_require__(184); /** * @classdesc @@ -70957,7 +70957,7 @@ module.exports = { os: __webpack_require__(102), browser: __webpack_require__(134), - features: __webpack_require__(187), + features: __webpack_require__(188), input: __webpack_require__(805), audio: __webpack_require__(806), video: __webpack_require__(807), @@ -71524,7 +71524,7 @@ module.exports = QuadraticBezierInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SmoothStep = __webpack_require__(180); +var SmoothStep = __webpack_require__(181); /** * A Smooth Step interpolation method. @@ -72250,7 +72250,7 @@ module.exports = Matrix3; var Class = __webpack_require__(0); var Matrix3 = __webpack_require__(358); var NOOP = __webpack_require__(1); -var Vector3 = __webpack_require__(36); +var Vector3 = __webpack_require__(37); var EPSILON = 0.000001; @@ -73296,7 +73296,7 @@ module.exports = Quaternion; var CanvasInterpolation = __webpack_require__(361); var CanvasPool = __webpack_require__(31); var CONST = __webpack_require__(39); -var Features = __webpack_require__(187); +var Features = __webpack_require__(188); /** * Called automatically by Phaser.Game and responsible for creating the renderer it will use. @@ -73386,8 +73386,8 @@ var CreateRenderer = function (game) if (true) { - CanvasRenderer = __webpack_require__(569); - WebGLRenderer = __webpack_require__(572); + CanvasRenderer = __webpack_require__(362); + WebGLRenderer = __webpack_require__(365); // Let the config pick the renderer type, as both are included if (config.renderType === CONST.WEBGL) @@ -73478,52044 +73478,6 @@ module.exports = CanvasInterpolation; /* 362 */ /***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(39); - -/** - * Called automatically by Phaser.Game and responsible for creating the console.log debug header. - * - * You can customize or disable the header via the Game Config object. - * - * @function Phaser.Core.DebugHeader - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance which will output this debug header. - */ -var DebugHeader = function (game) -{ - var config = game.config; - - if (config.hideBanner) - { - return; - } - - var renderType = 'WebGL'; - - if (config.renderType === CONST.CANVAS) - { - renderType = 'Canvas'; - } - else if (config.renderType === CONST.HEADLESS) - { - renderType = 'Headless'; - } - - var audioConfig = config.audio; - var deviceAudio = game.device.audio; - - var audioType; - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - audioType = 'Web Audio'; - } - else if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - audioType = 'No Audio'; - } - else - { - audioType = 'HTML5 Audio'; - } - - if (!game.device.browser.ie) - { - var c = ''; - var args = [ c ]; - - if (Array.isArray(config.bannerBackgroundColor)) - { - var lastColor; - - config.bannerBackgroundColor.forEach(function (color) - { - c = c.concat('%c '); - - args.push('background: ' + color); - - lastColor = color; - - }); - - // inject the text color - args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; - } - else - { - c = c.concat('%c '); - - args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); - } - - // URL link background color (always white) - args.push('background: #fff'); - - if (config.gameTitle) - { - c = c.concat(config.gameTitle); - - if (config.gameVersion) - { - c = c.concat(' v' + config.gameVersion); - } - - if (!config.hidePhaser) - { - c = c.concat(' / '); - } - } - - var fb = ( false) ? undefined : ''; - - if (!config.hidePhaser) - { - c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); - } - - c = c.concat(' %c ' + config.gameURL); - - // Inject the new string back into the args array - args[0] = c; - - console.log.apply(console, args); - } - else if (window['console']) - { - console.log('Phaser v' + CONST.VERSION + ' / https://phaser.io'); - } -}; - -module.exports = DebugHeader; - - -/***/ }), -/* 363 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetValue = __webpack_require__(6); -var NOOP = __webpack_require__(1); -var RequestAnimationFrame = __webpack_require__(364); - -// http://www.testufo.com/#test=animation-time-graph - -/** - * @classdesc - * The core runner class that Phaser uses to handle the game loop. It can use either Request Animation Frame, - * or SetTimeout, based on browser support and config settings, to create a continuous loop within the browser. - * - * Each time the loop fires, `TimeStep.step` is called and this is then passed onto the core Game update loop, - * it is the core heartbeat of your game. It will fire as often as Request Animation Frame is capable of handling - * on the target device. - * - * Note that there are lots of situations where a browser will stop updating your game. Such as if the player - * switches tabs, or covers up the browser window with another application. In these cases, the 'heartbeat' - * of your game will pause, and only resume when focus is returned to it by the player. There is no way to avoid - * this situation, all you can do is use the visibility events the browser, and Phaser, provide to detect when - * it has happened and then gracefully recover. - * - * @class TimeStep - * @memberof Phaser.Core - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step. - * @param {Phaser.Types.Core.FPSConfig} config - */ -var TimeStep = new Class({ - - initialize: - - function TimeStep (game, config) - { - /** - * A reference to the Phaser.Game instance. - * - * @name Phaser.Core.TimeStep#game - * @type {Phaser.Game} - * @readonly - * @since 3.0.0 - */ - this.game = game; - - /** - * The Request Animation Frame DOM Event handler. - * - * @name Phaser.Core.TimeStep#raf - * @type {Phaser.DOM.RequestAnimationFrame} - * @readonly - * @since 3.0.0 - */ - this.raf = new RequestAnimationFrame(); - - /** - * A flag that is set once the TimeStep has started running and toggled when it stops. - * - * @name Phaser.Core.TimeStep#started - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.started = false; - - /** - * A flag that is set once the TimeStep has started running and toggled when it stops. - * The difference between this value and `started` is that `running` is toggled when - * the TimeStep is sent to sleep, where-as `started` remains `true`, only changing if - * the TimeStep is actually stopped, not just paused. - * - * @name Phaser.Core.TimeStep#running - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.running = false; - - /** - * The minimum fps rate you want the Time Step to run at. - * - * @name Phaser.Core.TimeStep#minFps - * @type {number} - * @default 5 - * @since 3.0.0 - */ - this.minFps = GetValue(config, 'min', 5); - - /** - * The target fps rate for the Time Step to run at. - * - * Setting this value will not actually change the speed at which the browser runs, that is beyond - * the control of Phaser. Instead, it allows you to determine performance issues and if the Time Step - * is spiraling out of control. - * - * @name Phaser.Core.TimeStep#targetFps - * @type {number} - * @default 60 - * @since 3.0.0 - */ - this.targetFps = GetValue(config, 'target', 60); - - /** - * The minFps value in ms. - * Defaults to 200ms between frames (i.e. super slow!) - * - * @name Phaser.Core.TimeStep#_min - * @type {number} - * @private - * @since 3.0.0 - */ - this._min = 1000 / this.minFps; - - /** - * The targetFps value in ms. - * Defaults to 16.66ms between frames (i.e. normal) - * - * @name Phaser.Core.TimeStep#_target - * @type {number} - * @private - * @since 3.0.0 - */ - this._target = 1000 / this.targetFps; - - /** - * An exponential moving average of the frames per second. - * - * @name Phaser.Core.TimeStep#actualFps - * @type {number} - * @readonly - * @default 60 - * @since 3.0.0 - */ - this.actualFps = this.targetFps; - - /** - * The time at which the next fps rate update will take place. - * When an fps update happens, the `framesThisSecond` value is reset. - * - * @name Phaser.Core.TimeStep#nextFpsUpdate - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.nextFpsUpdate = 0; - - /** - * The number of frames processed this second. - * - * @name Phaser.Core.TimeStep#framesThisSecond - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.framesThisSecond = 0; - - /** - * A callback to be invoked each time the Time Step steps. - * - * @name Phaser.Core.TimeStep#callback - * @type {Phaser.Types.Core.TimeStepCallback} - * @default NOOP - * @since 3.0.0 - */ - this.callback = NOOP; - - /** - * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting - * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time. - * - * @name Phaser.Core.TimeStep#forceSetTimeOut - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.forceSetTimeOut = GetValue(config, 'forceSetTimeOut', false); - - /** - * The time, calculated at the start of the current step, as smoothed by the delta value. - * - * @name Phaser.Core.TimeStep#time - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.time = 0; - - /** - * The time at which the game started running. This value is adjusted if the game is then - * paused and resumes. - * - * @name Phaser.Core.TimeStep#startTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * The time, as returned by `performance.now` of the previous step. - * - * @name Phaser.Core.TimeStep#lastTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lastTime = 0; - - /** - * The current frame the game is on. This counter is incremented once every game step, regardless of how much - * time has passed and is unaffected by delta smoothing. - * - * @name Phaser.Core.TimeStep#frame - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.frame = 0; - - /** - * Is the browser currently considered in focus by the Page Visibility API? - * This value is set in the `blur` method, which is called automatically by the Game instance. - * - * @name Phaser.Core.TimeStep#inFocus - * @type {boolean} - * @readonly - * @default true - * @since 3.0.0 - */ - this.inFocus = true; - - /** - * The timestamp at which the game became paused, as determined by the Page Visibility API. - * - * @name Phaser.Core.TimeStep#_pauseTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._pauseTime = 0; - - /** - * An internal counter to allow for the browser 'cooling down' after coming back into focus. - * - * @name Phaser.Core.TimeStep#_coolDown - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._coolDown = 0; - - /** - * The delta time, in ms, since the last game step. This is a clamped and smoothed average value. - * - * @name Phaser.Core.TimeStep#delta - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.delta = 0; - - /** - * Internal index of the delta history position. - * - * @name Phaser.Core.TimeStep#deltaIndex - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.deltaIndex = 0; - - /** - * Internal array holding the previous delta values, used for delta smoothing. - * - * @name Phaser.Core.TimeStep#deltaHistory - * @type {number[]} - * @since 3.0.0 - */ - this.deltaHistory = []; - - /** - * The maximum number of delta values that are retained in order to calculate a smoothed moving average. - * - * This can be changed in the Game Config via the `fps.deltaHistory` property. The default is 10. - * - * @name Phaser.Core.TimeStep#deltaSmoothingMax - * @type {number} - * @default 10 - * @since 3.0.0 - */ - this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10); - - /** - * The number of frames that the cooldown is set to after the browser panics over the FPS rate, usually - * as a result of switching tabs and regaining focus. - * - * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120. - * - * @name Phaser.Core.TimeStep#panicMax - * @type {number} - * @default 120 - * @since 3.0.0 - */ - this.panicMax = GetValue(config, 'panicMax', 120); - - /** - * The actual elapsed time in ms between one update and the next. - * - * Unlike with `delta`, no smoothing, capping, or averaging is applied to this value. - * So please be careful when using this value in math calculations. - * - * @name Phaser.Core.TimeStep#rawDelta - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.rawDelta = 0; - - /** - * The time, as returned by `performance.now` at the very start of the current step. - * This can differ from the `time` value in that it isn't calculated based on the delta value. - * - * @name Phaser.Core.TimeStep#now - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.now = 0; - - /** - * Apply smoothing to the delta value used within Phasers internal calculations? - * - * This can be changed in the Game Config via the `fps.smoothStep` property. The default is `true`. - * - * Smoothing helps settle down the delta values after browser tab switches, or other situations - * which could cause significant delta spikes or dips. By default it has been enabled in Phaser 3 - * since the first version, but is now exposed under this property (and the corresponding game config - * `smoothStep` value), to allow you to easily disable it, should you require. - * - * @name Phaser.Core.TimeStep#smoothStep - * @type {boolean} - * @since 3.22.0 - */ - this.smoothStep = GetValue(config, 'smoothStep', true); - }, - - /** - * Called by the Game instance when the DOM window.onBlur event triggers. - * - * @method Phaser.Core.TimeStep#blur - * @since 3.0.0 - */ - blur: function () - { - this.inFocus = false; - }, - - /** - * Called by the Game instance when the DOM window.onFocus event triggers. - * - * @method Phaser.Core.TimeStep#focus - * @since 3.0.0 - */ - focus: function () - { - this.inFocus = true; - - this.resetDelta(); - }, - - /** - * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc) - * - * @method Phaser.Core.TimeStep#pause - * @since 3.0.0 - */ - pause: function () - { - this._pauseTime = window.performance.now(); - }, - - /** - * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc) - * - * @method Phaser.Core.TimeStep#resume - * @since 3.0.0 - */ - resume: function () - { - this.resetDelta(); - - this.startTime += this.time - this._pauseTime; - }, - - /** - * Resets the time, lastTime, fps averages and delta history. - * Called automatically when a browser sleeps them resumes. - * - * @method Phaser.Core.TimeStep#resetDelta - * @since 3.0.0 - */ - resetDelta: function () - { - var now = window.performance.now(); - - this.time = now; - this.lastTime = now; - this.nextFpsUpdate = now + 1000; - this.framesThisSecond = 0; - - // Pre-populate smoothing array - - for (var i = 0; i < this.deltaSmoothingMax; i++) - { - this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]); - } - - this.delta = 0; - this.deltaIndex = 0; - - this._coolDown = this.panicMax; - }, - - /** - * Starts the Time Step running, if it is not already doing so. - * Called automatically by the Game Boot process. - * - * @method Phaser.Core.TimeStep#start - * @since 3.0.0 - * - * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps. - */ - start: function (callback) - { - if (this.started) - { - return this; - } - - this.started = true; - this.running = true; - - for (var i = 0; i < this.deltaSmoothingMax; i++) - { - this.deltaHistory[i] = this._target; - } - - this.resetDelta(); - - this.startTime = window.performance.now(); - - this.callback = callback; - - this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target); - }, - - /** - * The main step method. This is called each time the browser updates, either by Request Animation Frame, - * or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more. - * You generally should never call this method directly. - * - * @method Phaser.Core.TimeStep#step - * @since 3.0.0 - */ - step: function () - { - // Because the timestamp passed in from raf represents the beginning of the main thread frame that we’re currently in, - // not the actual time now, and as we want to compare this time value against Event timeStamps and the like, we need a - // more accurate one: - - var time = window.performance.now(); - - this.now = time; - - var before = time - this.lastTime; - - if (before < 0) - { - // Because, Chrome. - before = 0; - } - - this.rawDelta = before; - - var idx = this.deltaIndex; - var history = this.deltaHistory; - var max = this.deltaSmoothingMax; - - // delta time (time is in ms) - var dt = before; - - // Delta Average - var avg = before; - - // When a browser switches tab, then comes back again, it takes around 10 frames before - // the delta time settles down so we employ a 'cooling down' period before we start - // trusting the delta values again, to avoid spikes flooding through our delta average - - if (this.smoothStep) - { - if (this._coolDown > 0 || !this.inFocus) - { - this._coolDown--; - - dt = Math.min(dt, this._target); - } - - if (dt > this._min) - { - // Probably super bad start time or browser tab context loss, - // so use the last 'sane' dt value - - dt = history[idx]; - - // Clamp delta to min (in case history has become corrupted somehow) - dt = Math.min(dt, this._min); - } - - // Smooth out the delta over the previous X frames - - // add the delta to the smoothing array - history[idx] = dt; - - // adjusts the delta history array index based on the smoothing count - // this stops the array growing beyond the size of deltaSmoothingMax - this.deltaIndex++; - - if (this.deltaIndex > max) - { - this.deltaIndex = 0; - } - - // Loop the history array, adding the delta values together - avg = 0; - - for (var i = 0; i < max; i++) - { - avg += history[i]; - } - - // Then divide by the array length to get the average delta - avg /= max; - } - - // Set as the world delta value - this.delta = avg; - - // Real-world timer advance - this.time += this.rawDelta; - - // Update the estimate of the frame rate, `fps`. Every second, the number - // of frames that occurred in that second are included in an exponential - // moving average of all frames per second, with an alpha of 0.25. This - // means that more recent seconds affect the estimated frame rate more than - // older seconds. - // - // When a browser window is NOT minimized, but is covered up (i.e. you're using - // another app which has spawned a window over the top of the browser), then it - // will start to throttle the raf callback time. It waits for a while, and then - // starts to drop the frame rate at 1 frame per second until it's down to just over 1fps. - // So if the game was running at 60fps, and the player opens a new window, then - // after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz. - // - // When they make the game visible again, the frame rate is increased at a rate of - // approx. 8fps, back up to 60fps (or the max it can obtain) - // - // There is no easy way to determine if this drop in frame rate is because the - // browser is throttling raf, or because the game is struggling with performance - // because you're asking it to do too much on the device. - - if (time > this.nextFpsUpdate) - { - // Compute the new exponential moving average with an alpha of 0.25. - this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps; - this.nextFpsUpdate = time + 1000; - this.framesThisSecond = 0; - } - - this.framesThisSecond++; - - // Interpolation - how far between what is expected and where we are? - var interpolation = avg / this._target; - - this.callback(time, avg, interpolation); - - // Shift time value over - this.lastTime = time; - - this.frame++; - }, - - /** - * Manually calls `TimeStep.step`. - * - * @method Phaser.Core.TimeStep#tick - * @since 3.0.0 - */ - tick: function () - { - this.step(); - }, - - /** - * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false. - * - * @method Phaser.Core.TimeStep#sleep - * @since 3.0.0 - */ - sleep: function () - { - if (this.running) - { - this.raf.stop(); - - this.running = false; - } - }, - - /** - * Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true. - * The `seamless` argument controls if the wake-up should adjust the start time or not. - * - * @method Phaser.Core.TimeStep#wake - * @since 3.0.0 - * - * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values. - */ - wake: function (seamless) - { - if (this.running) - { - return; - } - else if (seamless) - { - this.startTime += -this.lastTime + (this.lastTime + window.performance.now()); - } - - this.raf.start(this.step.bind(this), this.useRAF); - - this.running = true; - - this.step(); - }, - - /** - * Gets the duration which the game has been running, in seconds. - * - * @method Phaser.Core.TimeStep#getDuration - * @since 3.17.0 - * - * @return {number} The duration in seconds. - */ - getDuration: function () - { - return Math.round(this.lastTime - this.startTime) / 1000; - }, - - /** - * Gets the duration which the game has been running, in ms. - * - * @method Phaser.Core.TimeStep#getDurationMS - * @since 3.17.0 - * - * @return {number} The duration in ms. - */ - getDurationMS: function () - { - return Math.round(this.lastTime - this.startTime); - }, - - /** - * Stops the TimeStep running. - * - * @method Phaser.Core.TimeStep#stop - * @since 3.0.0 - * - * @return {this} The TimeStep object. - */ - stop: function () - { - this.running = false; - this.started = false; - - this.raf.stop(); - - return this; - }, - - /** - * Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null - * any objects. - * - * @method Phaser.Core.TimeStep#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stop(); - - this.callback = NOOP; - - this.raf = null; - this.game = null; - } - -}); - -module.exports = TimeStep; - - -/***/ }), -/* 364 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * Abstracts away the use of RAF or setTimeOut for the core game update loop. - * This is invoked automatically by the Phaser.Game instance. - * - * @class RequestAnimationFrame - * @memberof Phaser.DOM - * @constructor - * @since 3.0.0 - */ -var RequestAnimationFrame = new Class({ - - initialize: - - function RequestAnimationFrame () - { - /** - * True if RequestAnimationFrame is running, otherwise false. - * - * @name Phaser.DOM.RequestAnimationFrame#isRunning - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isRunning = false; - - /** - * The callback to be invoked each step. - * - * @name Phaser.DOM.RequestAnimationFrame#callback - * @type {FrameRequestCallback} - * @since 3.0.0 - */ - this.callback = NOOP; - - /** - * The most recent timestamp. Either a DOMHighResTimeStamp under RAF or `Date.now` under SetTimeout. - * - * @name Phaser.DOM.RequestAnimationFrame#tick - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.tick = 0; - - /** - * True if the step is using setTimeout instead of RAF. - * - * @name Phaser.DOM.RequestAnimationFrame#isSetTimeOut - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isSetTimeOut = false; - - /** - * The setTimeout or RAF callback ID used when canceling them. - * - * @name Phaser.DOM.RequestAnimationFrame#timeOutID - * @type {?number} - * @default null - * @since 3.0.0 - */ - this.timeOutID = null; - - /** - * The previous time the step was called. - * - * @name Phaser.DOM.RequestAnimationFrame#lastTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lastTime = 0; - - /** - * The target FPS rate in ms. - * Only used when setTimeout is used instead of RAF. - * - * @name Phaser.DOM.RequestAnimationFrame#target - * @type {number} - * @default 0 - * @since 3.21.0 - */ - this.target = 0; - - var _this = this; - - /** - * The RAF step function. - * Updates the local tick value, invokes the callback and schedules another call to requestAnimationFrame. - * - * @name Phaser.DOM.RequestAnimationFrame#step - * @type {FrameRequestCallback} - * @since 3.0.0 - */ - this.step = function step () - { - // Because we cannot trust the time passed to this callback from the browser and need it kept in sync with event times - var timestamp = window.performance.now(); - - // DOMHighResTimeStamp - _this.lastTime = _this.tick; - - _this.tick = timestamp; - - _this.callback(timestamp); - - _this.timeOutID = window.requestAnimationFrame(step); - }; - - /** - * The SetTimeout step function. - * Updates the local tick value, invokes the callback and schedules another call to setTimeout. - * - * @name Phaser.DOM.RequestAnimationFrame#stepTimeout - * @type {function} - * @since 3.0.0 - */ - this.stepTimeout = function stepTimeout () - { - var d = Date.now(); - - var delay = Math.min(Math.max(_this.target * 2 + _this.tick - d, 0), _this.target); - - _this.lastTime = _this.tick; - - _this.tick = d; - - _this.callback(d); - - _this.timeOutID = window.setTimeout(stepTimeout, delay); - }; - }, - - /** - * Starts the requestAnimationFrame or setTimeout process running. - * - * @method Phaser.DOM.RequestAnimationFrame#start - * @since 3.0.0 - * - * @param {FrameRequestCallback} callback - The callback to invoke each step. - * @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available? - * @param {number} targetFPS - The target fps rate (in ms). Only used when setTimeout is used. - */ - start: function (callback, forceSetTimeOut, targetFPS) - { - if (this.isRunning) - { - return; - } - - this.callback = callback; - - this.isSetTimeOut = forceSetTimeOut; - - this.target = targetFPS; - - this.isRunning = true; - - this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); - }, - - /** - * Stops the requestAnimationFrame or setTimeout from running. - * - * @method Phaser.DOM.RequestAnimationFrame#stop - * @since 3.0.0 - */ - stop: function () - { - this.isRunning = false; - - if (this.isSetTimeOut) - { - clearTimeout(this.timeOutID); - } - else - { - window.cancelAnimationFrame(this.timeOutID); - } - }, - - /** - * Stops the step from running and clears the callback reference. - * - * @method Phaser.DOM.RequestAnimationFrame#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stop(); - - this.callback = NOOP; - } - -}); - -module.exports = RequestAnimationFrame; - - -/***/ }), -/* 365 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Events = __webpack_require__(22); - -/** - * The Visibility Handler is responsible for listening out for document level visibility change events. - * This includes `visibilitychange` if the browser supports it, and blur and focus events. It then uses - * the provided Event Emitter and fires the related events. - * - * @function Phaser.Core.VisibilityHandler - * @fires Phaser.Core.Events#BLUR - * @fires Phaser.Core.Events#FOCUS - * @fires Phaser.Core.Events#HIDDEN - * @fires Phaser.Core.Events#VISIBLE - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. - */ -var VisibilityHandler = function (game) -{ - var hiddenVar; - var eventEmitter = game.events; - - if (document.hidden !== undefined) - { - hiddenVar = 'visibilitychange'; - } - else - { - var vendors = [ 'webkit', 'moz', 'ms' ]; - - vendors.forEach(function (prefix) - { - if (document[prefix + 'Hidden'] !== undefined) - { - document.hidden = function () - { - return document[prefix + 'Hidden']; - }; - - hiddenVar = prefix + 'visibilitychange'; - } - - }); - } - - var onChange = function (event) - { - if (document.hidden || event.type === 'pause') - { - eventEmitter.emit(Events.HIDDEN); - } - else - { - eventEmitter.emit(Events.VISIBLE); - } - }; - - if (hiddenVar) - { - document.addEventListener(hiddenVar, onChange, false); - } - - window.onblur = function () - { - eventEmitter.emit(Events.BLUR); - }; - - window.onfocus = function () - { - eventEmitter.emit(Events.FOCUS); - }; - - // Automatically give the window focus unless config says otherwise - if (window.focus && game.config.autoFocus) - { - window.focus(); - } -}; - -module.exports = VisibilityHandler; - - -/***/ }), -/* 366 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Arne16 = __webpack_require__(367); -var CanvasPool = __webpack_require__(31); -var GetValue = __webpack_require__(6); - -/** - * Generates a texture based on the given Create configuration object. - * - * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the - * data cells map to a single color. For example, if the texture config looked like this: - * - * ```javascript - * var star = [ - * '.....828.....', - * '....72227....', - * '....82228....', - * '...7222227...', - * '2222222222222', - * '8222222222228', - * '.72222222227.', - * '..787777787..', - * '..877777778..', - * '.78778887787.', - * '.27887.78872.', - * '.787.....787.' - * ]; - * - * this.textures.generate('star', { data: star, pixelWidth: 4 }); - * ``` - * - * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array - * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color - * number 8 in the palette. If a cell contains a period character `.` then it is transparent. - * - * The default palette is Arne16, but you can specify your own using the `palette` property. - * - * @function Phaser.Create.GenerateTexture - * @since 3.0.0 - * - * @param {Phaser.Types.Create.GenerateTextureConfig} config - The Generate Texture Configuration object. - * - * @return {HTMLCanvasElement} An HTMLCanvasElement which contains the generated texture drawn to it. - */ -var GenerateTexture = function (config) -{ - var data = GetValue(config, 'data', []); - var canvas = GetValue(config, 'canvas', null); - var palette = GetValue(config, 'palette', Arne16); - var pixelWidth = GetValue(config, 'pixelWidth', 1); - var pixelHeight = GetValue(config, 'pixelHeight', pixelWidth); - var resizeCanvas = GetValue(config, 'resizeCanvas', true); - var clearCanvas = GetValue(config, 'clearCanvas', true); - var preRender = GetValue(config, 'preRender', null); - var postRender = GetValue(config, 'postRender', null); - - var width = Math.floor(Math.abs(data[0].length * pixelWidth)); - var height = Math.floor(Math.abs(data.length * pixelHeight)); - - if (!canvas) - { - canvas = CanvasPool.create2D(this, width, height); - resizeCanvas = false; - clearCanvas = false; - } - - if (resizeCanvas) - { - canvas.width = width; - canvas.height = height; - } - - var ctx = canvas.getContext('2d'); - - if (clearCanvas) - { - ctx.clearRect(0, 0, width, height); - } - - // preRender Callback? - if (preRender) - { - preRender(canvas, ctx); - } - - // Draw it - for (var y = 0; y < data.length; y++) - { - var row = data[y]; - - for (var x = 0; x < row.length; x++) - { - var d = row[x]; - - if (d !== '.' && d !== ' ') - { - ctx.fillStyle = palette[d]; - ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight); - } - } - } - - // postRender Callback? - if (postRender) - { - postRender(canvas, ctx); - } - - return canvas; -}; - -module.exports = GenerateTexture; - - -/***/ }), -/* 367 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * A 16 color palette by [Arne](http://androidarts.com/palette/16pal.htm) - * - * @name Phaser.Create.Palettes.ARNE16 - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.exports = { - 0: '#000', - 1: '#9D9D9D', - 2: '#FFF', - 3: '#BE2633', - 4: '#E06F8B', - 5: '#493C2B', - 6: '#A46422', - 7: '#EB8931', - 8: '#F7E26B', - 9: '#2F484E', - A: '#44891A', - B: '#A3CE27', - C: '#1B2632', - D: '#005784', - E: '#31A2F2', - F: '#B2DCEF' -}; - - -/***/ }), -/* 368 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var CubicBezier = __webpack_require__(352); -var Curve = __webpack_require__(89); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A higher-order Bézier curve constructed of four points. - * - * @class CubicBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector2[])} p0 - Start point, or an array of point pairs. - * @param {Phaser.Math.Vector2} p1 - Control Point 1. - * @param {Phaser.Math.Vector2} p2 - Control Point 2. - * @param {Phaser.Math.Vector2} p3 - End Point. - */ -var CubicBezierCurve = new Class({ - - Extends: Curve, - - initialize: - - function CubicBezierCurve (p0, p1, p2, p3) - { - Curve.call(this, 'CubicBezierCurve'); - - if (Array.isArray(p0)) - { - p3 = new Vector2(p0[6], p0[7]); - p2 = new Vector2(p0[4], p0[5]); - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The start point of this curve. - * - * @name Phaser.Curves.CubicBezier#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = p0; - - /** - * The first control point of this curve. - * - * @name Phaser.Curves.CubicBezier#p1 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p1 = p1; - - /** - * The second control point of this curve. - * - * @name Phaser.Curves.CubicBezier#p2 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p2 = p2; - - /** - * The end point of this curve. - * - * @name Phaser.Curves.CubicBezier#p3 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p3 = p3; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.CubicBezier#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Returns the resolution of this curve. - * - * @method Phaser.Curves.CubicBezier#getResolution - * @since 3.0.0 - * - * @param {number} divisions - The amount of divisions used by this curve. - * - * @return {number} The resolution of the curve. - */ - getResolution: function (divisions) - { - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.CubicBezier#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var p0 = this.p0; - var p1 = this.p1; - var p2 = this.p2; - var p3 = this.p3; - - return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y)); - }, - - /** - * Draws this curve to the specified graphics object. - * - * @method Phaser.Curves.CubicBezier#draw - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - The graphics object this curve should be drawn to. - * @param {number} [pointsTotal=32] - The number of intermediary points that make up this curve. A higher number of points will result in a smoother curve. - * - * @return {Phaser.GameObjects.Graphics} The graphics object this curve was drawn to. Useful for method chaining. - */ - draw: function (graphics, pointsTotal) - { - if (pointsTotal === undefined) { pointsTotal = 32; } - - var points = this.getPoints(pointsTotal); - - graphics.beginPath(); - graphics.moveTo(this.p0.x, this.p0.y); - - for (var i = 1; i < points.length; i++) - { - graphics.lineTo(points[i].x, points[i].y); - } - - graphics.strokePath(); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Returns a JSON object that describes this curve. - * - * @method Phaser.Curves.CubicBezier#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y, - this.p2.x, this.p2.y, - this.p3.x, this.p3.y - ] - }; - } - -}); - -/** - * Generates a curve from a JSON object. - * - * @function Phaser.Curves.CubicBezier.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.CubicBezier} The curve generated from the JSON object. - */ -CubicBezierCurve.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - var p2 = new Vector2(points[4], points[5]); - var p3 = new Vector2(points[6], points[7]); - - return new CubicBezierCurve(p0, p1, p2, p3); -}; - -module.exports = CubicBezierCurve; - - -/***/ }), -/* 369 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var DegToRad = __webpack_require__(33); -var GetValue = __webpack_require__(6); -var RadToDeg = __webpack_require__(192); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * An Elliptical Curve derived from the Base Curve class. - * - * See https://en.wikipedia.org/wiki/Elliptic_curve for more details. - * - * @class Ellipse - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(number|Phaser.Types.Curves.EllipseCurveConfig)} [x=0] - The x coordinate of the ellipse, or an Ellipse Curve configuration object. - * @param {number} [y=0] - The y coordinate of the ellipse. - * @param {number} [xRadius=0] - The horizontal radius of ellipse. - * @param {number} [yRadius=0] - The vertical radius of ellipse. - * @param {number} [startAngle=0] - The start angle of the ellipse, in degrees. - * @param {number} [endAngle=360] - The end angle of the ellipse, in degrees. - * @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`). - * @param {number} [rotation=0] - The rotation of the ellipse, in degrees. - */ -var EllipseCurve = new Class({ - - Extends: Curve, - - initialize: - - function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) - { - if (typeof x === 'object') - { - var config = x; - - x = GetValue(config, 'x', 0); - y = GetValue(config, 'y', 0); - xRadius = GetValue(config, 'xRadius', 0); - yRadius = GetValue(config, 'yRadius', xRadius); - startAngle = GetValue(config, 'startAngle', 0); - endAngle = GetValue(config, 'endAngle', 360); - clockwise = GetValue(config, 'clockwise', false); - rotation = GetValue(config, 'rotation', 0); - } - else - { - if (yRadius === undefined) { yRadius = xRadius; } - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 360; } - if (clockwise === undefined) { clockwise = false; } - if (rotation === undefined) { rotation = 0; } - } - - Curve.call(this, 'EllipseCurve'); - - // Center point - - /** - * The center point of the ellipse. Used for calculating rotation. - * - * @name Phaser.Curves.Ellipse#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = new Vector2(x, y); - - /** - * The horizontal radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#_xRadius - * @type {number} - * @private - * @since 3.0.0 - */ - this._xRadius = xRadius; - - /** - * The vertical radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#_yRadius - * @type {number} - * @private - * @since 3.0.0 - */ - this._yRadius = yRadius; - - // Radians - - /** - * The starting angle of the ellipse in radians. - * - * @name Phaser.Curves.Ellipse#_startAngle - * @type {number} - * @private - * @since 3.0.0 - */ - this._startAngle = DegToRad(startAngle); - - /** - * The end angle of the ellipse in radians. - * - * @name Phaser.Curves.Ellipse#_endAngle - * @type {number} - * @private - * @since 3.0.0 - */ - this._endAngle = DegToRad(endAngle); - - /** - * Anti-clockwise direction. - * - * @name Phaser.Curves.Ellipse#_clockwise - * @type {boolean} - * @private - * @since 3.0.0 - */ - this._clockwise = clockwise; - - /** - * The rotation of the arc. - * - * @name Phaser.Curves.Ellipse#_rotation - * @type {number} - * @private - * @since 3.0.0 - */ - this._rotation = DegToRad(rotation); - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Ellipse#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return this.getPoint(0, out); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.Ellipse#getResolution - * @since 3.0.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions * 2; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Ellipse#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var twoPi = Math.PI * 2; - var deltaAngle = this._endAngle - this._startAngle; - var samePoints = Math.abs(deltaAngle) < Number.EPSILON; - - // ensures that deltaAngle is 0 .. 2 PI - while (deltaAngle < 0) - { - deltaAngle += twoPi; - } - - while (deltaAngle > twoPi) - { - deltaAngle -= twoPi; - } - - if (deltaAngle < Number.EPSILON) - { - if (samePoints) - { - deltaAngle = 0; - } - else - { - deltaAngle = twoPi; - } - } - - if (this._clockwise && !samePoints) - { - if (deltaAngle === twoPi) - { - deltaAngle = - twoPi; - } - else - { - deltaAngle = deltaAngle - twoPi; - } - } - - var angle = this._startAngle + t * deltaAngle; - var x = this.p0.x + this._xRadius * Math.cos(angle); - var y = this.p0.y + this._yRadius * Math.sin(angle); - - if (this._rotation !== 0) - { - var cos = Math.cos(this._rotation); - var sin = Math.sin(this._rotation); - - var tx = x - this.p0.x; - var ty = y - this.p0.y; - - // Rotate the point about the center of the ellipse. - x = tx * cos - ty * sin + this.p0.x; - y = tx * sin + ty * cos + this.p0.y; - } - - return out.set(x, y); - }, - - /** - * Sets the horizontal radius of this curve. - * - * @method Phaser.Curves.Ellipse#setXRadius - * @since 3.0.0 - * - * @param {number} value - The horizontal radius of this curve. - * - * @return {this} This curve object. - */ - setXRadius: function (value) - { - this.xRadius = value; - - return this; - }, - - /** - * Sets the vertical radius of this curve. - * - * @method Phaser.Curves.Ellipse#setYRadius - * @since 3.0.0 - * - * @param {number} value - The vertical radius of this curve. - * - * @return {this} This curve object. - */ - setYRadius: function (value) - { - this.yRadius = value; - - return this; - }, - - /** - * Sets the width of this curve. - * - * @method Phaser.Curves.Ellipse#setWidth - * @since 3.0.0 - * - * @param {number} value - The width of this curve. - * - * @return {this} This curve object. - */ - setWidth: function (value) - { - this.xRadius = value / 2; - - return this; - }, - - /** - * Sets the height of this curve. - * - * @method Phaser.Curves.Ellipse#setHeight - * @since 3.0.0 - * - * @param {number} value - The height of this curve. - * - * @return {this} This curve object. - */ - setHeight: function (value) - { - this.yRadius = value / 2; - - return this; - }, - - /** - * Sets the start angle of this curve. - * - * @method Phaser.Curves.Ellipse#setStartAngle - * @since 3.0.0 - * - * @param {number} value - The start angle of this curve, in radians. - * - * @return {this} This curve object. - */ - setStartAngle: function (value) - { - this.startAngle = value; - - return this; - }, - - /** - * Sets the end angle of this curve. - * - * @method Phaser.Curves.Ellipse#setEndAngle - * @since 3.0.0 - * - * @param {number} value - The end angle of this curve, in radians. - * - * @return {this} This curve object. - */ - setEndAngle: function (value) - { - this.endAngle = value; - - return this; - }, - - /** - * Sets if this curve extends clockwise or anti-clockwise. - * - * @method Phaser.Curves.Ellipse#setClockwise - * @since 3.0.0 - * - * @param {boolean} value - The clockwise state of this curve. - * - * @return {this} This curve object. - */ - setClockwise: function (value) - { - this.clockwise = value; - - return this; - }, - - /** - * Sets the rotation of this curve. - * - * @method Phaser.Curves.Ellipse#setRotation - * @since 3.0.0 - * - * @param {number} value - The rotation of this curve, in radians. - * - * @return {this} This curve object. - */ - setRotation: function (value) - { - this.rotation = value; - - return this; - }, - - /** - * The x coordinate of the center of the ellipse. - * - * @name Phaser.Curves.Ellipse#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.p0.x; - }, - - set: function (value) - { - this.p0.x = value; - } - - }, - - /** - * The y coordinate of the center of the ellipse. - * - * @name Phaser.Curves.Ellipse#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.p0.y; - }, - - set: function (value) - { - this.p0.y = value; - } - - }, - - /** - * The horizontal radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#xRadius - * @type {number} - * @since 3.0.0 - */ - xRadius: { - - get: function () - { - return this._xRadius; - }, - - set: function (value) - { - this._xRadius = value; - } - - }, - - /** - * The vertical radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#yRadius - * @type {number} - * @since 3.0.0 - */ - yRadius: { - - get: function () - { - return this._yRadius; - }, - - set: function (value) - { - this._yRadius = value; - } - - }, - - /** - * The start angle of the ellipse in degrees. - * - * @name Phaser.Curves.Ellipse#startAngle - * @type {number} - * @since 3.0.0 - */ - startAngle: { - - get: function () - { - return RadToDeg(this._startAngle); - }, - - set: function (value) - { - this._startAngle = DegToRad(value); - } - - }, - - /** - * The end angle of the ellipse in degrees. - * - * @name Phaser.Curves.Ellipse#endAngle - * @type {number} - * @since 3.0.0 - */ - endAngle: { - - get: function () - { - return RadToDeg(this._endAngle); - }, - - set: function (value) - { - this._endAngle = DegToRad(value); - } - - }, - - /** - * `true` if the ellipse rotation is clockwise or `false` if anti-clockwise. - * - * @name Phaser.Curves.Ellipse#clockwise - * @type {boolean} - * @since 3.0.0 - */ - clockwise: { - - get: function () - { - return this._clockwise; - }, - - set: function (value) - { - this._clockwise = value; - } - - }, - - /** - * The rotation of the ellipse, relative to the center, in degrees. - * - * @name Phaser.Curves.Ellipse#angle - * @type {number} - * @since 3.14.0 - */ - angle: { - - get: function () - { - return RadToDeg(this._rotation); - }, - - set: function (value) - { - this._rotation = DegToRad(value); - } - - }, - - /** - * The rotation of the ellipse, relative to the center, in radians. - * - * @name Phaser.Curves.Ellipse#rotation - * @type {number} - * @since 3.0.0 - */ - rotation: { - - get: function () - { - return this._rotation; - }, - - set: function (value) - { - this._rotation = value; - } - - }, - - /** - * JSON serialization of the curve. - * - * @method Phaser.Curves.Ellipse#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONEllipseCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - x: this.p0.x, - y: this.p0.y, - xRadius: this._xRadius, - yRadius: this._yRadius, - startAngle: RadToDeg(this._startAngle), - endAngle: RadToDeg(this._endAngle), - clockwise: this._clockwise, - rotation: RadToDeg(this._rotation) - }; - } - -}); - -/** - * Creates a curve from the provided Ellipse Curve Configuration object. - * - * @function Phaser.Curves.Ellipse.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. - */ -EllipseCurve.fromJSON = function (data) -{ - return new EllipseCurve(data); -}; - -module.exports = EllipseCurve; - - -/***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var FromPoints = __webpack_require__(194); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); - -var tmpVec2 = new Vector2(); - -/** - * @classdesc - * A LineCurve is a "curve" comprising exactly two points (a line segment). - * - * @class Line - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. - * @param {Phaser.Math.Vector2} [p1] - The second endpoint. - */ -var LineCurve = new Class({ - - Extends: Curve, - - initialize: - - // vec2s or array - function LineCurve (p0, p1) - { - Curve.call(this, 'LineCurve'); - - if (Array.isArray(p0)) - { - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The first endpoint. - * - * @name Phaser.Curves.Line#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = p0; - - /** - * The second endpoint. - * - * @name Phaser.Curves.Line#p1 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p1 = p1; - - // Override default Curve.arcLengthDivisions - - /** - * The quantity of arc length divisions within the curve. - * - * @name Phaser.Curves.Line#arcLengthDivisions - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.arcLengthDivisions = 1; - }, - - /** - * Returns a Rectangle where the position and dimensions match the bounds of this Curve. - * - * @method Phaser.Curves.Line#getBounds - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the bounds in. If not given a new Rectangle will be created. - * - * @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object. - */ - getBounds: function (out) - { - if (out === undefined) { out = new Rectangle(); } - - return FromPoints([ this.p0, this.p1 ], out); - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Line#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Gets the resolution of the line. - * - * @method Phaser.Curves.Line#getResolution - * @since 3.0.0 - * - * @param {number} [divisions=1] - The number of divisions to consider. - * - * @return {number} The resolution. Equal to the number of divisions. - */ - getResolution: function (divisions) - { - if (divisions === undefined) { divisions = 1; } - - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Line#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - if (t === 1) - { - return out.copy(this.p1); - } - - out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); - - return out; - }, - - // Line curve is linear, so we can overwrite default getPointAt - - /** - * Gets a point at a given position on the line. - * - * @method Phaser.Curves.Line#getPointAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPointAt: function (u, out) - { - return this.getPoint(u, out); - }, - - /** - * Gets the slope of the line as a unit vector. - * - * @method Phaser.Curves.Line#getTangent - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @return {Phaser.Math.Vector2} The tangent vector. - */ - getTangent: function () - { - var tangent = tmpVec2.copy(this.p1).subtract(this.p0); - - return tangent.normalize(); - }, - - /** - * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. - * - * @method Phaser.Curves.Line#getUtoTmapping - * @since 3.0.0 - * - * @param {number} u - A float between 0 and 1. - * @param {number} distance - The distance, in pixels. - * @param {number} [divisions] - Optional amount of divisions. - * - * @return {number} The equidistant value. - */ - getUtoTmapping: function (u, distance, divisions) - { - var t; - - if (distance) - { - var arcLengths = this.getLengths(divisions); - var lineLength = arcLengths[arcLengths.length - 1]; - - // Cannot overshoot the curve - var targetLineLength = Math.min(distance, lineLength); - - t = targetLineLength / lineLength; - } - else - { - t = u; - } - - return t; - }, - - // Override default Curve.draw because this is better than calling getPoints on a line! - - /** - * Draws this curve on the given Graphics object. - * - * The curve is drawn using `Graphics.lineBetween` so will be drawn at whatever the present Graphics line color is. - * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. - * - * @method Phaser.Curves.Line#draw - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn. - * - * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. - */ - draw: function (graphics) - { - graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Gets a JSON representation of the line. - * - * @method Phaser.Curves.Line#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y - ] - }; - } - -}); - -/** - * Configures this line from a JSON representation. - * - * @function Phaser.Curves.Line.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Line} A new LineCurve object. - */ -LineCurve.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - - return new LineCurve(p0, p1); -}; - -module.exports = LineCurve; - - -/***/ }), -/* 371 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A MoveTo Curve is a very simple curve consisting of only a single point. - * Its intended use is to move the ending point in a Path. - * - * @class MoveTo - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {number} [x=0] - `x` pixel coordinate. - * @param {number} [y=0] - `y` pixel coordinate. - */ -var MoveTo = new Class({ - - initialize: - - function MoveTo (x, y) - { - /** - * Denotes that this Curve does not influence the bounds, points, and drawing of its parent Path. Must be `false` or some methods in the parent Path will throw errors. - * - * @name Phaser.Curves.MoveTo#active - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.active = false; - - /** - * The lone point which this curve consists of. - * - * @name Phaser.Curves.MoveTo#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = new Vector2(x, y); - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.MoveTo#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Retrieves the point at given position in the curve. This will always return this curve's only point. - * - * @method Phaser.Curves.MoveTo#getPointAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The position in the path to retrieve, between 0 and 1. Not used. - * @param {Phaser.Math.Vector2} [out] - An optional vector in which to store the point. - * - * @return {Phaser.Math.Vector2} The modified `out` vector, or a new `Vector2` if none was provided. - */ - getPointAt: function (u, out) - { - return this.getPoint(u, out); - }, - - /** - * Gets the resolution of this curve. - * - * @method Phaser.Curves.MoveTo#getResolution - * @since 3.0.0 - * - * @return {number} The resolution of this curve. For a MoveTo the value is always 1. - */ - getResolution: function () - { - return 1; - }, - - /** - * Gets the length of this curve. - * - * @method Phaser.Curves.MoveTo#getLength - * @since 3.0.0 - * - * @return {number} The length of this curve. For a MoveTo the value is always 0. - */ - getLength: function () - { - return 0; - }, - - /** - * Converts this curve into a JSON-serializable object. - * - * @method Phaser.Curves.MoveTo#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} A primitive object with the curve's type and only point. - */ - toJSON: function () - { - return { - type: 'MoveTo', - points: [ - this.p0.x, this.p0.y - ] - }; - } - -}); - -module.exports = MoveTo; - - -/***/ }), -/* 372 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var QuadraticBezierInterpolation = __webpack_require__(353); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A quadratic Bézier curve constructed from two control points. - * - * @class QuadraticBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.2.0 - * - * @param {(Phaser.Math.Vector2|number[])} p0 - Start point, or an array of point pairs. - * @param {Phaser.Math.Vector2} p1 - Control Point 1. - * @param {Phaser.Math.Vector2} p2 - Control Point 2. - */ -var QuadraticBezier = new Class({ - - Extends: Curve, - - initialize: - - function QuadraticBezier (p0, p1, p2) - { - Curve.call(this, 'QuadraticBezier'); - - if (Array.isArray(p0)) - { - p2 = new Vector2(p0[4], p0[5]); - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The start point. - * - * @name Phaser.Curves.QuadraticBezier#p0 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p0 = p0; - - /** - * The first control point. - * - * @name Phaser.Curves.QuadraticBezier#p1 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p1 = p1; - - /** - * The second control point. - * - * @name Phaser.Curves.QuadraticBezier#p2 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p2 = p2; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.QuadraticBezier#getStartPoint - * @since 3.2.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.QuadraticBezier#getResolution - * @since 3.2.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.QuadraticBezier#getPoint - * @since 3.2.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var p0 = this.p0; - var p1 = this.p1; - var p2 = this.p2; - - return out.set( - QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x), - QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y) - ); - }, - - /** - * Draws this curve on the given Graphics object. - * - * The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is. - * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. - * - * @method Phaser.Curves.QuadraticBezier#draw - * @since 3.2.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - `Graphics` object to draw onto. - * @param {number} [pointsTotal=32] - Number of points to be used for drawing the curve. Higher numbers result in smoother curve but require more processing. - * - * @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to. - */ - draw: function (graphics, pointsTotal) - { - if (pointsTotal === undefined) { pointsTotal = 32; } - - var points = this.getPoints(pointsTotal); - - graphics.beginPath(); - graphics.moveTo(this.p0.x, this.p0.y); - - for (var i = 1; i < points.length; i++) - { - graphics.lineTo(points[i].x, points[i].y); - } - - graphics.strokePath(); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Converts the curve into a JSON compatible object. - * - * @method Phaser.Curves.QuadraticBezier#toJSON - * @since 3.2.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y, - this.p2.x, this.p2.y - ] - }; - } - -}); - -/** - * Creates a curve from a JSON object, e. g. created by `toJSON`. - * - * @function Phaser.Curves.QuadraticBezier.fromJSON - * @since 3.2.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.QuadraticBezier} The created curve instance. - */ -QuadraticBezier.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - var p2 = new Vector2(points[4], points[5]); - - return new QuadraticBezier(p0, p1, p2); -}; - -module.exports = QuadraticBezier; - - -/***/ }), -/* 373 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var CatmullRom = __webpack_require__(190); -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * Create a smooth 2d spline curve from a series of points. - * - * @class Spline - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2[]|number[]|number[][])} [points] - The points that configure the curve. - */ -var SplineCurve = new Class({ - - Extends: Curve, - - initialize: - - function SplineCurve (points) - { - if (points === undefined) { points = []; } - - Curve.call(this, 'SplineCurve'); - - /** - * The Vector2 points that configure the curve. - * - * @name Phaser.Curves.Spline#points - * @type {Phaser.Math.Vector2[]} - * @default [] - * @since 3.0.0 - */ - this.points = []; - - this.addPoints(points); - }, - - /** - * Add a list of points to the current list of Vector2 points of the curve. - * - * @method Phaser.Curves.Spline#addPoints - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve. - * - * @return {this} This curve object. - */ - addPoints: function (points) - { - for (var i = 0; i < points.length; i++) - { - var p = new Vector2(); - - if (typeof points[i] === 'number') - { - p.x = points[i]; - p.y = points[i + 1]; - i++; - } - else if (Array.isArray(points[i])) - { - // An array of arrays? - p.x = points[i][0]; - p.y = points[i][1]; - } - else - { - p.x = points[i].x; - p.y = points[i].y; - } - - this.points.push(p); - } - - return this; - }, - - /** - * Add a point to the current list of Vector2 points of the curve. - * - * @method Phaser.Curves.Spline#addPoint - * @since 3.0.0 - * - * @param {number} x - The x coordinate of this curve - * @param {number} y - The y coordinate of this curve - * - * @return {Phaser.Math.Vector2} The new Vector2 added to the curve - */ - addPoint: function (x, y) - { - var vec = new Vector2(x, y); - - this.points.push(vec); - - return vec; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Spline#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.points[0]); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.Spline#getResolution - * @since 3.0.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions * this.points.length; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Spline#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var points = this.points; - - var point = (points.length - 1) * t; - - var intPoint = Math.floor(point); - - var weight = point - intPoint; - - var p0 = points[(intPoint === 0) ? intPoint : intPoint - 1]; - var p1 = points[intPoint]; - var p2 = points[(intPoint > points.length - 2) ? points.length - 1 : intPoint + 1]; - var p3 = points[(intPoint > points.length - 3) ? points.length - 1 : intPoint + 2]; - - return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); - }, - - /** - * Exports a JSON object containing this curve data. - * - * @method Phaser.Curves.Spline#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - var points = []; - - for (var i = 0; i < this.points.length; i++) - { - points.push(this.points[i].x); - points.push(this.points[i].y); - } - - return { - type: this.type, - points: points - }; - } - -}); - -/** - * Imports a JSON object containing this curve data. - * - * @function Phaser.Curves.Spline.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Spline} The spline curve created. - */ -SplineCurve.fromJSON = function (data) -{ - return new SplineCurve(data.points); -}; - -module.exports = SplineCurve; - - -/***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A BaseShader is a small resource class that contains the data required for a WebGL Shader to be created. - * - * It contains the raw source code to the fragment and vertex shader, as well as an object that defines - * the uniforms the shader requires, if any. - * - * BaseShaders are stored in the Shader Cache, available in a Scene via `this.cache.shaders` and are referenced - * by a unique key-based string. Retrieve them via `this.cache.shaders.get(key)`. - * - * BaseShaders are created automatically by the GLSL File Loader when loading an external shader resource. - * They can also be created at runtime, allowing you to use dynamically generated shader source code. - * - * Default fragment and vertex source is used if not provided in the constructor, setting-up a basic shader, - * suitable for debug rendering. - * - * @class BaseShader - * @memberof Phaser.Display - * @constructor - * @since 3.17.0 - * - * @param {string} key - The key of this shader. Must be unique within the shader cache. - * @param {string} [fragmentSrc] - The fragment source for the shader. - * @param {string} [vertexSrc] - The vertex source for the shader. - * @param {any} [uniforms] - Optional object defining the uniforms the shader uses. - */ -var BaseShader = new Class({ - - initialize: - - function BaseShader (key, fragmentSrc, vertexSrc, uniforms) - { - if (!fragmentSrc || fragmentSrc === '') - { - fragmentSrc = [ - 'precision mediump float;', - - 'uniform vec2 resolution;', - - 'varying vec2 fragCoord;', - - 'void main () {', - ' vec2 uv = fragCoord / resolution.xy;', - ' gl_FragColor = vec4(uv.xyx, 1.0);', - '}' - ].join('\n'); - } - - if (!vertexSrc || vertexSrc === '') - { - vertexSrc = [ - 'precision mediump float;', - - 'uniform mat4 uProjectionMatrix;', - 'uniform mat4 uViewMatrix;', - 'uniform vec2 uResolution;', - - 'attribute vec2 inPosition;', - - 'varying vec2 fragCoord;', - 'varying vec2 outTexCoord;', - - 'void main () {', - ' gl_Position = uProjectionMatrix * uViewMatrix * vec4(inPosition, 1.0, 1.0);', - ' fragCoord = vec2(inPosition.x, uResolution.y - inPosition.y);', - ' outTexCoord = vec2(inPosition.x / uResolution.x, fragCoord.y / uResolution.y);', - '}' - ].join('\n'); - } - - if (uniforms === undefined) { uniforms = null; } - - /** - * The key of this shader, unique within the shader cache of this Phaser game instance. - * - * @name Phaser.Display.BaseShader#key - * @type {string} - * @since 3.17.0 - */ - this.key = key; - - /** - * The source code, as a string, of the fragment shader being used. - * - * @name Phaser.Display.BaseShader#fragmentSrc - * @type {string} - * @since 3.17.0 - */ - this.fragmentSrc = fragmentSrc; - - /** - * The source code, as a string, of the vertex shader being used. - * - * @name Phaser.Display.BaseShader#vertexSrc - * @type {string} - * @since 3.17.0 - */ - this.vertexSrc = vertexSrc; - - /** - * The default uniforms for this shader. - * - * @name Phaser.Display.BaseShader#uniforms - * @type {?any} - * @since 3.17.0 - */ - this.uniforms = uniforms; - } - -}); - -module.exports = BaseShader; - - -/***/ }), -/* 375 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Color = __webpack_require__(35); - -Color.ColorSpectrum = __webpack_require__(905); -Color.ColorToRGBA = __webpack_require__(906); -Color.ComponentToHex = __webpack_require__(376); -Color.GetColor = __webpack_require__(100); -Color.GetColor32 = __webpack_require__(322); -Color.HexStringToColor = __webpack_require__(321); -Color.HSLToColor = __webpack_require__(907); -Color.HSVColorWheel = __webpack_require__(908); -Color.HSVToRGB = __webpack_require__(184); -Color.HueToComponent = __webpack_require__(377); -Color.IntegerToColor = __webpack_require__(185); -Color.IntegerToRGB = __webpack_require__(324); -Color.Interpolate = __webpack_require__(909); -Color.ObjectToColor = __webpack_require__(325); -Color.RandomRGB = __webpack_require__(910); -Color.RGBStringToColor = __webpack_require__(326); -Color.RGBToHSV = __webpack_require__(323); -Color.RGBToString = __webpack_require__(911); -Color.ValueToColor = __webpack_require__(183); - -module.exports = Color; - - -/***/ }), -/* 376 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns a string containing a hex representation of the given color component. - * - * @function Phaser.Display.Color.ComponentToHex - * @since 3.0.0 - * - * @param {number} color - The color channel to get the hex value for, must be a value between 0 and 255. - * - * @return {string} A string of length 2 characters, i.e. 255 = ff, 100 = 64. - */ -var ComponentToHex = function (color) -{ - var hex = color.toString(16); - - return (hex.length === 1) ? '0' + hex : hex; -}; - -module.exports = ComponentToHex; - - -/***/ }), -/* 377 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts a hue to an RGB color. - * Based on code by Michael Jackson (https://github.com/mjijackson) - * - * @function Phaser.Display.Color.HueToComponent - * @since 3.0.0 - * - * @param {number} p - * @param {number} q - * @param {number} t - * - * @return {number} The combined color value. - */ -var HueToComponent = function (p, q, t) -{ - if (t < 0) - { - t += 1; - } - - if (t > 1) - { - t -= 1; - } - - if (t < 1 / 6) - { - return p + (q - p) * 6 * t; - } - - if (t < 1 / 2) - { - return q; - } - - if (t < 2 / 3) - { - return p + (q - p) * (2 / 3 - t) * 6; - } - - return p; -}; - -module.exports = HueToComponent; - - -/***/ }), -/* 378 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var OS = __webpack_require__(102); - -/** - * @callback ContentLoadedCallback - */ - -/** - * Inspects the readyState of the document. If the document is already complete then it invokes the given callback. - * If not complete it sets up several event listeners such as `deviceready`, and once those fire, it invokes the callback. - * Called automatically by the Phaser.Game instance. Should not usually be accessed directly. - * - * @function Phaser.DOM.DOMContentLoaded - * @since 3.0.0 - * - * @param {ContentLoadedCallback} callback - The callback to be invoked when the device is ready and the DOM content is loaded. - */ -var DOMContentLoaded = function (callback) -{ - if (document.readyState === 'complete' || document.readyState === 'interactive') - { - callback(); - - return; - } - - var check = function () - { - document.removeEventListener('deviceready', check, true); - document.removeEventListener('DOMContentLoaded', check, true); - window.removeEventListener('load', check, true); - - callback(); - }; - - if (!document.body) - { - window.setTimeout(check, 20); - } - else if (OS.cordova) - { - // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready - document.addEventListener('deviceready', check, false); - } - else - { - document.addEventListener('DOMContentLoaded', check, true); - window.addEventListener('load', check, true); - } -}; - -module.exports = DOMContentLoaded; - - -/***/ }), -/* 379 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Attempts to determine the document inner height across iOS and standard devices. - * Based on code by @tylerjpeterson - * - * @function Phaser.DOM.GetInnerHeight - * @since 3.16.0 - * - * @param {boolean} iOS - Is this running on iOS? - * - * @return {number} The inner height value. - */ -var GetInnerHeight = function (iOS) -{ - - if (!iOS) - { - return window.innerHeight; - } - - var axis = Math.abs(window.orientation); - - var size = { w: 0, h: 0 }; - - var ruler = document.createElement('div'); - - ruler.setAttribute('style', 'position: fixed; height: 100vh; width: 0; top: 0'); - - document.documentElement.appendChild(ruler); - - size.w = (axis === 90) ? ruler.offsetHeight : window.innerWidth; - size.h = (axis === 90) ? window.innerWidth : ruler.offsetHeight; - - document.documentElement.removeChild(ruler); - - ruler = null; - - if (Math.abs(window.orientation) !== 90) - { - return size.h; - } - else - { - return size.w; - } -}; - -module.exports = GetInnerHeight; - - -/***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(196); - -/** - * Attempts to determine the screen orientation using the Orientation API. - * - * @function Phaser.DOM.GetScreenOrientation - * @since 3.16.0 - * - * @param {number} width - The width of the viewport. - * @param {number} height - The height of the viewport. - * - * @return {string} The orientation. - */ -var GetScreenOrientation = function (width, height) -{ - var screen = window.screen; - var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; - - if (orientation && typeof orientation.type === 'string') - { - // Screen Orientation API specification - return orientation.type; - } - else if (typeof orientation === 'string') - { - // moz / ms-orientation are strings - return orientation; - } - - if (typeof window.orientation === 'number') - { - // Do this check first, as iOS supports this, but also has an incomplete window.screen implementation - // This may change by device based on "natural" orientation. - return (window.orientation === 0 || window.orientation === 180) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; - } - else if (window.matchMedia) - { - if (window.matchMedia('(orientation: portrait)').matches) - { - return CONST.ORIENTATION.PORTRAIT; - } - else if (window.matchMedia('(orientation: landscape)').matches) - { - return CONST.ORIENTATION.LANDSCAPE; - } - } - else - { - return (height > width) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; - } -}; - -module.exports = GetScreenOrientation; - - -/***/ }), -/* 381 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for centering the game canvas. - * - * @namespace Phaser.Scale.Center - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for centering the game canvas. - * - * To find out what each mode does please see [Phaser.Scale.Center]{@link Phaser.Scale.Center}. - * - * @typedef {Phaser.Scale.Center} Phaser.Scale.CenterType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * The game canvas is not centered within the parent by Phaser. - * You can still center it yourself via CSS. - * - * @name Phaser.Scale.Center.NO_CENTER - * @type {number} - * @const - * @since 3.16.0 - */ - NO_CENTER: 0, - - /** - * The game canvas is centered both horizontally and vertically within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_BOTH - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_BOTH: 1, - - /** - * The game canvas is centered horizontally within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_HORIZONTALLY - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_HORIZONTALLY: 2, - - /** - * The game canvas is centered both vertically within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_VERTICALLY - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_VERTICALLY: 3 - -}; - - -/***/ }), -/* 382 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for orientation. - * - * @namespace Phaser.Scale.Orientation - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for orientation. - * - * To find out what each mode does please see [Phaser.Scale.Orientation]{@link Phaser.Scale.Orientation}. - * - * @typedef {Phaser.Scale.Orientation} Phaser.Scale.OrientationType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * A landscape orientation. - * - * @name Phaser.Scale.Orientation.LANDSCAPE - * @type {string} - * @const - * @since 3.16.0 - */ - LANDSCAPE: 'landscape-primary', - - /** - * A portrait orientation. - * - * @name Phaser.Scale.Orientation.PORTRAIT - * @type {string} - * @const - * @since 3.16.0 - */ - PORTRAIT: 'portrait-primary' - -}; - - -/***/ }), -/* 383 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for the different scale modes available. - * - * @namespace Phaser.Scale.ScaleModes - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for the different scale modes available. - * - * To find out what each mode does please see [Phaser.Scale.ScaleModes]{@link Phaser.Scale.ScaleModes}. - * - * @typedef {Phaser.Scale.ScaleModes} Phaser.Scale.ScaleModeType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * No scaling happens at all. The canvas is set to the size given in the game config and Phaser doesn't change it - * again from that point on. If you change the canvas size, either via CSS, or directly via code, then you need - * to call the Scale Managers `resize` method to give the new dimensions, or input events will stop working. - * - * @name Phaser.Scale.ScaleModes.NONE - * @type {number} - * @const - * @since 3.16.0 - */ - NONE: 0, - - /** - * The height is automatically adjusted based on the width. - * - * @name Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT - * @type {number} - * @const - * @since 3.16.0 - */ - WIDTH_CONTROLS_HEIGHT: 1, - - /** - * The width is automatically adjusted based on the height. - * - * @name Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH - * @type {number} - * @const - * @since 3.16.0 - */ - HEIGHT_CONTROLS_WIDTH: 2, - - /** - * The width and height are automatically adjusted to fit inside the given target area, - * while keeping the aspect ratio. Depending on the aspect ratio there may be some space - * inside the area which is not covered. - * - * @name Phaser.Scale.ScaleModes.FIT - * @type {number} - * @const - * @since 3.16.0 - */ - FIT: 3, - - /** - * The width and height are automatically adjusted to make the size cover the entire target - * area while keeping the aspect ratio. This may extend further out than the target size. - * - * @name Phaser.Scale.ScaleModes.ENVELOP - * @type {number} - * @const - * @since 3.16.0 - */ - ENVELOP: 4, - - /** - * The Canvas is resized to fit all available _parent_ space, regardless of aspect ratio. - * - * @name Phaser.Scale.ScaleModes.RESIZE - * @type {number} - * @const - * @since 3.16.0 - */ - RESIZE: 5 - -}; - - -/***/ }), -/* 384 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for zoom modes. - * - * @namespace Phaser.Scale.Zoom - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for zoom modes. - * - * To find out what each mode does please see [Phaser.Scale.Zoom]{@link Phaser.Scale.Zoom}. - * - * @typedef {Phaser.Scale.Zoom} Phaser.Scale.ZoomType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * The game canvas will not be zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.NO_ZOOM - * @type {number} - * @const - * @since 3.16.0 - */ - NO_ZOOM: 1, - - /** - * The game canvas will be 2x zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.ZOOM_2X - * @type {number} - * @const - * @since 3.16.0 - */ - ZOOM_2X: 2, - - /** - * The game canvas will be 4x zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.ZOOM_4X - * @type {number} - * @const - * @since 3.16.0 - */ - ZOOM_4X: 4, - - /** - * Calculate the zoom value based on the maximum multiplied game size that will - * fit into the parent, or browser window if no parent is set. - * - * @name Phaser.Scale.Zoom.MAX_ZOOM - * @type {number} - * @const - * @since 3.16.0 - */ - MAX_ZOOM: -1 - -}; - - -/***/ }), -/* 385 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Attempts to get the target DOM element based on the given value, which can be either - * a string, in which case it will be looked-up by ID, or an element node. If nothing - * can be found it will return a reference to the document.body. - * - * @function Phaser.DOM.GetTarget - * @since 3.16.0 - * - * @param {HTMLElement} element - The DOM element to look-up. - */ -var GetTarget = function (element) -{ - var target; - - if (element !== '') - { - if (typeof element === 'string') - { - // Hopefully an element ID - target = document.getElementById(element); - } - else if (element && element.nodeType === 1) - { - // Quick test for a HTMLElement - target = element; - } - } - - // Fallback to the document body. Covers an invalid ID and a non HTMLElement object. - if (!target) - { - // Use the full window - target = document.body; - } - - return target; -}; - -module.exports = GetTarget; - - -/***/ }), -/* 386 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Takes the given data string and parses it as XML. - * First tries to use the window.DOMParser and reverts to the Microsoft.XMLDOM if that fails. - * The parsed XML object is returned, or `null` if there was an error while parsing the data. - * - * @function Phaser.DOM.ParseXML - * @since 3.0.0 - * - * @param {string} data - The XML source stored in a string. - * - * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. - */ -var ParseXML = function (data) -{ - var xml = ''; - - try - { - if (window['DOMParser']) - { - var domparser = new DOMParser(); - xml = domparser.parseFromString(data, 'text/xml'); - } - else - { - xml = new ActiveXObject('Microsoft.XMLDOM'); - xml.loadXML(data); - } - } - catch (e) - { - xml = null; - } - - if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) - { - return null; - } - else - { - return xml; - } -}; - -module.exports = ParseXML; - - -/***/ }), -/* 387 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(198); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(49); -var GameEvents = __webpack_require__(22); -var Keyboard = __webpack_require__(388); -var Mouse = __webpack_require__(389); -var Pointer = __webpack_require__(390); -var Touch = __webpack_require__(391); -var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(173); - -/** - * @classdesc - * The Input Manager is responsible for handling the pointer related systems in a single Phaser Game instance. - * - * Based on the Game Config it will create handlers for mouse and touch support. - * - * Keyboard and Gamepad are plugins, handled directly by the InputPlugin class. - * - * It then manages the events, pointer creation and general hit test related operations. - * - * You rarely need to interact with the Input Manager directly, and as such, all of its properties and methods - * should be considered private. Instead, you should use the Input Plugin, which is a Scene level system, responsible - * for dealing with all input events for a Scene. - * - * @class InputManager - * @memberof Phaser.Input - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Game instance that owns the Input Manager. - * @param {object} config - The Input Configuration object, as set in the Game Config. - */ -var InputManager = new Class({ - - initialize: - - function InputManager (game, config) - { - /** - * The Game instance that owns the Input Manager. - * A Game only maintains on instance of the Input Manager at any time. - * - * @name Phaser.Input.InputManager#game - * @type {Phaser.Game} - * @readonly - * @since 3.0.0 - */ - this.game = game; - - /** - * A reference to the global Game Scale Manager. - * Used for all bounds checks and pointer scaling. - * - * @name Phaser.Input.InputManager#scaleManager - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.0 - */ - this.scaleManager; - - /** - * The Canvas that is used for all DOM event input listeners. - * - * @name Phaser.Input.InputManager#canvas - * @type {HTMLCanvasElement} - * @since 3.0.0 - */ - this.canvas; - - /** - * The Game Configuration object, as set during the game boot. - * - * @name Phaser.Input.InputManager#config - * @type {Phaser.Core.Config} - * @since 3.0.0 - */ - this.config = config; - - /** - * If set, the Input Manager will run its update loop every frame. - * - * @name Phaser.Input.InputManager#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * The Event Emitter instance that the Input Manager uses to emit events from. - * - * @name Phaser.Input.InputManager#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = new EventEmitter(); - - /** - * Are any mouse or touch pointers currently over the game canvas? - * This is updated automatically by the canvas over and out handlers. - * - * @name Phaser.Input.InputManager#isOver - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - this.isOver = true; - - /** - * The default CSS cursor to be used when interacting with your game. - * - * See the `setDefaultCursor` method for more details. - * - * @name Phaser.Input.InputManager#defaultCursor - * @type {string} - * @since 3.10.0 - */ - this.defaultCursor = ''; - - /** - * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. - * - * @name Phaser.Input.InputManager#keyboard - * @type {?Phaser.Input.Keyboard.KeyboardManager} - * @since 3.16.0 - */ - this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; - - /** - * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. - * - * @name Phaser.Input.InputManager#mouse - * @type {?Phaser.Input.Mouse.MouseManager} - * @since 3.0.0 - */ - this.mouse = (config.inputMouse) ? new Mouse(this) : null; - - /** - * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. - * - * @name Phaser.Input.InputManager#touch - * @type {Phaser.Input.Touch.TouchManager} - * @since 3.0.0 - */ - this.touch = (config.inputTouch) ? new Touch(this) : null; - - /** - * An array of Pointers that have been added to the game. - * The first entry is reserved for the Mouse Pointer, the rest are Touch Pointers. - * - * By default there is 1 touch pointer enabled. If you need more use the `addPointer` method to start them, - * or set the `input.activePointers` property in the Game Config. - * - * @name Phaser.Input.InputManager#pointers - * @type {Phaser.Input.Pointer[]} - * @since 3.10.0 - */ - this.pointers = []; - - /** - * The number of touch objects activated and being processed each update. - * - * You can change this by either calling `addPointer` at run-time, or by - * setting the `input.activePointers` property in the Game Config. - * - * @name Phaser.Input.InputManager#pointersTotal - * @type {number} - * @readonly - * @since 3.10.0 - */ - this.pointersTotal = config.inputActivePointers; - - if (config.inputTouch && this.pointersTotal === 1) - { - this.pointersTotal = 2; - } - - for (var i = 0; i <= this.pointersTotal; i++) - { - var pointer = new Pointer(this, i); - - pointer.smoothFactor = config.inputSmoothFactor; - - this.pointers.push(pointer); - } - - /** - * The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_. - * If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer` - * which will always map to the most recently interacted pointer. - * - * @name Phaser.Input.InputManager#mousePointer - * @type {?Phaser.Input.Pointer} - * @since 3.10.0 - */ - this.mousePointer = (config.inputMouse) ? this.pointers[0] : null; - - /** - * The most recently active Pointer object. - * - * If you've only 1 Pointer in your game then this will accurately be either the first finger touched, or the mouse. - * - * If your game doesn't need to support multi-touch then you can safely use this property in all of your game - * code and it will adapt to be either the mouse or the touch, based on device. - * - * @name Phaser.Input.InputManager#activePointer - * @type {Phaser.Input.Pointer} - * @since 3.0.0 - */ - this.activePointer = this.pointers[0]; - - /** - * If the top-most Scene in the Scene List receives an input it will stop input from - * propagating any lower down the scene list, i.e. if you have a UI Scene at the top - * and click something on it, that click will not then be passed down to any other - * Scene below. Disable this to have input events passed through all Scenes, all the time. - * - * @name Phaser.Input.InputManager#globalTopOnly - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.globalTopOnly = true; - - /** - * The time this Input Manager was last updated. - * This value is populated by the Game Step each frame. - * - * @name Phaser.Input.InputManager#time - * @type {number} - * @readonly - * @since 3.16.2 - */ - this.time = 0; - - /** - * A re-cycled point-like object to store hit test values in. - * - * @name Phaser.Input.InputManager#_tempPoint - * @type {{x:number, y:number}} - * @private - * @since 3.0.0 - */ - this._tempPoint = { x: 0, y: 0 }; - - /** - * A re-cycled array to store hit results in. - * - * @name Phaser.Input.InputManager#_tempHitTest - * @type {array} - * @private - * @default [] - * @since 3.0.0 - */ - this._tempHitTest = []; - - /** - * A re-cycled matrix used in hit test calculations. - * - * @name Phaser.Input.InputManager#_tempMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.4.0 - */ - this._tempMatrix = new TransformMatrix(); - - /** - * A re-cycled matrix used in hit test calculations. - * - * @name Phaser.Input.InputManager#_tempMatrix2 - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - /** - * An internal private var that records Scenes aborting event processing. - * - * @name Phaser.Input.InputManager#_tempSkip - * @type {boolean} - * @private - * @since 3.18.0 - */ - this._tempSkip = false; - - /** - * An internal private array that avoids needing to create a new array on every DOM mouse event. - * - * @name Phaser.Input.InputManager#mousePointerContainer - * @type {Phaser.Input.Pointer[]} - * @private - * @since 3.18.0 - */ - this.mousePointerContainer = [ this.mousePointer ]; - - game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot handler is called by Phaser.Game when it first starts up. - * The renderer is available by now. - * - * @method Phaser.Input.InputManager#boot - * @protected - * @fires Phaser.Input.Events#MANAGER_BOOT - * @since 3.0.0 - */ - boot: function () - { - this.canvas = this.game.canvas; - - this.scaleManager = this.game.scale; - - this.events.emit(Events.MANAGER_BOOT); - - this.game.events.on(GameEvents.PRE_RENDER, this.preRender, this); - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * Internal canvas state change, called automatically by the Mouse Manager. - * - * @method Phaser.Input.InputManager#setCanvasOver - * @fires Phaser.Input.Events#GAME_OVER - * @private - * @since 3.16.0 - * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. - */ - setCanvasOver: function (event) - { - this.isOver = true; - - this.events.emit(Events.GAME_OVER, event); - }, - - /** - * Internal canvas state change, called automatically by the Mouse Manager. - * - * @method Phaser.Input.InputManager#setCanvasOut - * @fires Phaser.Input.Events#GAME_OUT - * @private - * @since 3.16.0 - * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. - */ - setCanvasOut: function (event) - { - this.isOver = false; - - this.events.emit(Events.GAME_OUT, event); - }, - - /** - * Internal update, called automatically by the Game Step right at the start. - * - * @method Phaser.Input.InputManager#preRender - * @private - * @since 3.18.0 - */ - preRender: function () - { - var time = this.game.loop.now; - var delta = this.game.loop.delta; - var scenes = this.game.scene.getScenes(true, true); - - this.time = time; - - this.events.emit(Events.MANAGER_UPDATE); - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene.sys.input && scene.sys.input.updatePoll(time, delta) && this.globalTopOnly) - { - // If the Scene returns true, it means it captured some input that no other Scene should get, so we bail out - return; - } - } - }, - - /** - * Tells the Input system to set a custom cursor. - * - * This cursor will be the default cursor used when interacting with the game canvas. - * - * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. - * - * Any valid CSS cursor value is allowed, including paths to image files, i.e.: - * - * ```javascript - * this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer'); - * ``` - * - * Please read about the differences between browsers when it comes to the file formats and sizes they support: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor - * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property - * - * It's up to you to pick a suitable cursor format that works across the range of browsers you need to support. - * - * @method Phaser.Input.InputManager#setDefaultCursor - * @since 3.10.0 - * - * @param {string} cursor - The CSS to be used when setting the default cursor. - */ - setDefaultCursor: function (cursor) - { - this.defaultCursor = cursor; - - if (this.canvas.style.cursor !== cursor) - { - this.canvas.style.cursor = cursor; - } - }, - - /** - * Called by the InputPlugin when processing over and out events. - * - * Tells the Input Manager to set a custom cursor during its postUpdate step. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor - * - * @method Phaser.Input.InputManager#setCursor - * @private - * @since 3.10.0 - * - * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. - */ - setCursor: function (interactiveObject) - { - if (interactiveObject.cursor) - { - this.canvas.style.cursor = interactiveObject.cursor; - } - }, - - /** - * Called by the InputPlugin when processing over and out events. - * - * Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step. - * - * @method Phaser.Input.InputManager#resetCursor - * @private - * @since 3.10.0 - * - * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. - */ - resetCursor: function (interactiveObject) - { - if (interactiveObject.cursor && this.canvas) - { - this.canvas.style.cursor = this.defaultCursor; - } - }, - - /** - * Adds new Pointer objects to the Input Manager. - * - * By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`. - * - * You can create more either by calling this method, or by setting the `input.activePointers` property - * in the Game Config, up to a maximum of 10 pointers. - * - * The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added - * via this method. - * - * @method Phaser.Input.InputManager#addPointer - * @since 3.10.0 - * - * @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total. - * - * @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created. - */ - addPointer: function (quantity) - { - if (quantity === undefined) { quantity = 1; } - - var output = []; - - if (this.pointersTotal + quantity > 10) - { - quantity = 10 - this.pointersTotal; - } - - for (var i = 0; i < quantity; i++) - { - var id = this.pointers.length; - - var pointer = new Pointer(this, id); - - pointer.smoothFactor = this.config.inputSmoothFactor; - - this.pointers.push(pointer); - - this.pointersTotal++; - - output.push(pointer); - } - - return output; - }, - - /** - * Internal method that gets a list of all the active Input Plugins in the game - * and updates each of them in turn, in reverse order (top to bottom), to allow - * for DOM top-level event handling simulation. - * - * @method Phaser.Input.InputManager#updateInputPlugins - * @since 3.16.0 - * - * @param {number} type - The type of event to process. - * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. - */ - updateInputPlugins: function (type, pointers) - { - var scenes = this.game.scene.getScenes(true, true); - - this._tempSkip = false; - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene.sys.input) - { - var capture = scene.sys.input.update(type, pointers); - - if ((capture && this.globalTopOnly) || this._tempSkip) - { - // If the Scene returns true, or called stopPropagation, it means it captured some input that no other Scene should get, so we bail out - return; - } - } - } - }, - - // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element) - // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element - // event.changedTouches = the touches that CHANGED in this event, not the total number of them - - /** - * Processes a touch start event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchStart - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchStart: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (!pointer.active) - { - pointer.touchstart(changedTouch, event); - - this.activePointer = pointer; - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_START, changed); - }, - - /** - * Processes a touch move event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchMove - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchMove: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchmove(changedTouch, event); - - this.activePointer = pointer; - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_MOVE, changed); - }, - - // For touch end its a list of the touch points that have been removed from the surface - // https://developer.mozilla.org/en-US/docs/DOM/TouchList - // event.changedTouches = the touches that CHANGED in this event, not the total number of them - - /** - * Processes a touch end event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchEnd - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchEnd: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchend(changedTouch, event); - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_END, changed); - }, - - /** - * Processes a touch cancel event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchCancel - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchCancel: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchcancel(changedTouch, event); - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_CANCEL, changed); - }, - - /** - * Processes a mouse down event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseDown - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseDown: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.down(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer); - }, - - /** - * Processes a mouse move event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseMove - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseMove: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.move(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer); - }, - - /** - * Processes a mouse up event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseUp - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseUp: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.up(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); - }, - - /** - * Processes a mouse wheel event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseWheel - * @private - * @since 3.18.0 - * - * @param {WheelEvent} event - The native DOM Wheel event. - */ - onMouseWheel: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.wheel(event); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer); - }, - - /** - * Processes a pointer lock change event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onPointerLockChange - * @fires Phaser.Input.Events#POINTERLOCK_CHANGE - * @private - * @since 3.19.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onPointerLockChange: function (event) - { - var isLocked = this.mouse.locked; - - this.mousePointer.locked = isLocked; - - this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked); - }, - - /** - * Checks if the given Game Object should be considered as a candidate for input or not. - * - * Checks if the Game Object has an input component that is enabled, that it will render, - * and finally, if it has a parent, that the parent parent, or any ancestor, is visible or not. - * - * @method Phaser.Input.InputManager#inputCandidate - * @private - * @since 3.10.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to test. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * - * @return {boolean} `true` if the Game Object should be considered for input, otherwise `false`. - */ - inputCandidate: function (gameObject, camera) - { - var input = gameObject.input; - - if (!input || !input.enabled || (!input.alwaysEnabled && !gameObject.willRender(camera))) - { - return false; - } - - var visible = true; - var parent = gameObject.parentContainer; - - if (parent) - { - do - { - if (!parent.willRender(camera)) - { - visible = false; - break; - } - - parent = parent.parentContainer; - - } while (parent); - } - - return visible; - }, - - /** - * Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects. - * - * The Game Objects are culled against the camera, and then the coordinates are translated into the local camera space - * and used to determine if they fall within the remaining Game Objects hit areas or not. - * - * If nothing is matched an empty array is returned. - * - * This method is called automatically by InputPlugin.hitTestPointer and doesn't usually need to be invoked directly. - * - * @method Phaser.Input.InputManager#hitTest - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to test against. - * @param {array} gameObjects - An array of interactive Game Objects to check. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * @param {array} [output] - An array to store the results in. If not given, a new empty array is created. - * - * @return {array} An array of the Game Objects that were hit during this hit test. - */ - hitTest: function (pointer, gameObjects, camera, output) - { - if (output === undefined) { output = this._tempHitTest; } - - var tempPoint = this._tempPoint; - - var csx = camera.scrollX; - var csy = camera.scrollY; - - output.length = 0; - - var x = pointer.x; - var y = pointer.y; - - // Stores the world point inside of tempPoint - camera.getWorldPoint(x, y, tempPoint); - - pointer.worldX = tempPoint.x; - pointer.worldY = tempPoint.y; - - var point = { x: 0, y: 0 }; - - var matrix = this._tempMatrix; - var parentMatrix = this._tempMatrix2; - - for (var i = 0; i < gameObjects.length; i++) - { - var gameObject = gameObjects[i]; - - // Checks if the Game Object can receive input (isn't being ignored by the camera, invisible, etc) - // and also checks all of its parents, if any - if (!this.inputCandidate(gameObject, camera)) - { - continue; - } - - var px = tempPoint.x + (csx * gameObject.scrollFactorX) - csx; - var py = tempPoint.y + (csy * gameObject.scrollFactorY) - csy; - - if (gameObject.parentContainer) - { - gameObject.getWorldTransformMatrix(matrix, parentMatrix); - - matrix.applyInverse(px, py, point); - } - else - { - TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); - } - - if (this.pointWithinHitArea(gameObject, point.x, point.y)) - { - output.push(gameObject); - } - } - - return output; - }, - - /** - * Checks if the given x and y coordinate are within the hit area of the Game Object. - * - * This method assumes that the coordinate values have already been translated into the space of the Game Object. - * - * If the coordinates are within the hit area they are set into the Game Objects Input `localX` and `localY` properties. - * - * @method Phaser.Input.InputManager#pointWithinHitArea - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object to check against. - * @param {number} x - The translated x coordinate for the hit test. - * @param {number} y - The translated y coordinate for the hit test. - * - * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. - */ - pointWithinHitArea: function (gameObject, x, y) - { - // Normalize the origin - x += gameObject.displayOriginX; - y += gameObject.displayOriginY; - - var input = gameObject.input; - - if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) - { - input.localX = x; - input.localY = y; - - return true; - } - else - { - return false; - } - }, - - /** - * Checks if the given x and y coordinate are within the hit area of the Interactive Object. - * - * This method assumes that the coordinate values have already been translated into the space of the Interactive Object. - * - * If the coordinates are within the hit area they are set into the Interactive Objects Input `localX` and `localY` properties. - * - * @method Phaser.Input.InputManager#pointWithinInteractiveObject - * @since 3.0.0 - * - * @param {Phaser.Types.Input.InteractiveObject} object - The Interactive Object to check against. - * @param {number} x - The translated x coordinate for the hit test. - * @param {number} y - The translated y coordinate for the hit test. - * - * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. - */ - pointWithinInteractiveObject: function (object, x, y) - { - if (!object.hitArea) - { - return false; - } - - // Normalize the origin - x += object.gameObject.displayOriginX; - y += object.gameObject.displayOriginY; - - object.localX = x; - object.localY = y; - - return object.hitAreaCallback(object.hitArea, x, y, object); - }, - - /** - * Transforms the pageX and pageY values of a Pointer into the scaled coordinate space of the Input Manager. - * - * @method Phaser.Input.InputManager#transformPointer - * @since 3.10.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to transform the values for. - * @param {number} pageX - The Page X value. - * @param {number} pageY - The Page Y value. - * @param {boolean} wasMove - Are we transforming the Pointer from a move event, or an up / down event? - */ - transformPointer: function (pointer, pageX, pageY, wasMove) - { - var p0 = pointer.position; - var p1 = pointer.prevPosition; - - // Store previous position - p1.x = p0.x; - p1.y = p0.y; - - // Translate coordinates - var x = this.scaleManager.transformX(pageX); - var y = this.scaleManager.transformY(pageY); - - var a = pointer.smoothFactor; - - if (!wasMove || a === 0) - { - // Set immediately - p0.x = x; - p0.y = y; - } - else - { - // Apply smoothing - p0.x = x * a + p1.x * (1 - a); - p0.y = y * a + p1.y * (1 - a); - } - }, - - /** - * Destroys the Input Manager and all of its systems. - * - * There is no way to recover from doing this. - * - * @method Phaser.Input.InputManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.events.removeAllListeners(); - - this.game.events.off(GameEvents.PRE_RENDER); - - if (this.keyboard) - { - this.keyboard.destroy(); - } - - if (this.mouse) - { - this.mouse.destroy(); - } - - if (this.touch) - { - this.touch.destroy(); - } - - for (var i = 0; i < this.pointers.length; i++) - { - this.pointers[i].destroy(); - } - - this.pointers = []; - this._tempHitTest = []; - this._tempMatrix.destroy(); - this.canvas = null; - this.game = null; - } - -}); - -module.exports = InputManager; - - -/***/ }), -/* 388 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArrayRemove = __webpack_require__(88); -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var InputEvents = __webpack_require__(49); -var KeyCodes = __webpack_require__(140); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * The Keyboard Manager is a helper class that belongs to the global Input Manager. - * - * Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically if keyboard - * input has been enabled in the Game Config. - * - * @class KeyboardManager - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.16.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var KeyboardManager = new Class({ - - initialize: - - function KeyboardManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Keyboard.KeyboardManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.16.0 - */ - this.manager = inputManager; - - /** - * An internal event queue. - * - * @name Phaser.Input.Keyboard.KeyboardManager#queue - * @type {KeyboardEvent[]} - * @private - * @since 3.16.0 - */ - this.queue = []; - - /** - * A flag that controls if the non-modified keys, matching those stored in the `captures` array, - * have `preventDefault` called on them or not. - * - * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are - * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). - * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. - * However, if the user presses just the r key on its own, it will have its event prevented. - * - * If you wish to stop capturing the keys, for example switching out to a DOM based element, then - * you can toggle this property at run-time. - * - * @name Phaser.Input.Keyboard.KeyboardManager#preventDefault - * @type {boolean} - * @since 3.16.0 - */ - this.preventDefault = true; - - /** - * An array of Key Code values that will automatically have `preventDefault` called on them, - * as long as the `KeyboardManager.preventDefault` boolean is set to `true`. - * - * By default the array is empty. - * - * The key must be non-modified when pressed in order to be captured. - * - * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are - * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). - * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. - * However, if the user presses just the r key on its own, it will have its event prevented. - * - * If you wish to stop capturing the keys, for example switching out to a DOM based element, then - * you can toggle the `KeyboardManager.preventDefault` boolean at run-time. - * - * If you need more specific control, you can create Key objects and set the flag on each of those instead. - * - * This array can be populated via the Game Config by setting the `input.keyboard.capture` array, or you - * can call the `addCapture` method. See also `removeCapture` and `clearCaptures`. - * - * @name Phaser.Input.Keyboard.KeyboardManager#captures - * @type {number[]} - * @since 3.16.0 - */ - this.captures = []; - - /** - * A boolean that controls if the Keyboard Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Keyboard.KeyboardManager#enabled - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.enabled = false; - - /** - * The Keyboard Event target, as defined in the Game Config. - * Typically the window in which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Keyboard.KeyboardManager#target - * @type {any} - * @since 3.16.0 - */ - this.target; - - /** - * The Key Down Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyDown - * @type {function} - * @since 3.16.00 - */ - this.onKeyDown = NOOP; - - /** - * The Key Up Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp - * @type {function} - * @since 3.16.00 - */ - this.onKeyUp = NOOP; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Keyboard Manager boot process. - * - * @method Phaser.Input.Keyboard.KeyboardManager#boot - * @private - * @since 3.16.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputKeyboard; - this.target = config.inputKeyboardEventTarget; - - this.addCapture(config.inputKeyboardCapture); - - if (!this.target && window) - { - this.target = window; - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - - this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, this); - }, - - /** - * Starts the Keyboard Event listeners running. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Keyboard.KeyboardManager#startListeners - * @since 3.16.0 - */ - startListeners: function () - { - var _this = this; - - this.onKeyDown = function (event) - { - if (event.defaultPrevented || !_this.enabled || !_this.manager) - { - // Do nothing if event already handled - return; - } - - _this.queue.push(event); - - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); - - var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); - - if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) - { - event.preventDefault(); - } - }; - - this.onKeyUp = function (event) - { - if (event.defaultPrevented || !_this.enabled || !_this.manager) - { - // Do nothing if event already handled - return; - } - - _this.queue.push(event); - - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); - - var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); - - if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) - { - event.preventDefault(); - } - }; - - var target = this.target; - - if (target) - { - target.addEventListener('keydown', this.onKeyDown, false); - target.addEventListener('keyup', this.onKeyUp, false); - - this.enabled = true; - } - }, - - /** - * Stops the Key Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Keyboard.KeyboardManager#stopListeners - * @since 3.16.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('keydown', this.onKeyDown, false); - target.removeEventListener('keyup', this.onKeyUp, false); - - this.enabled = false; - }, - - /** - * Clears the event queue. - * Called automatically by the Input Manager. - * - * @method Phaser.Input.Keyboard.KeyboardManager#postUpdate - * @private - * @since 3.16.0 - */ - postUpdate: function () - { - this.queue = []; - }, - - /** - * By default when a key is pressed Phaser will not stop the event from propagating up to the browser. - * There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll. - * - * This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser - * and cause the default browser behavior. - * - * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent - * the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one. - * - * You can pass in a single key code value, or an array of key codes, or a string: - * - * ```javascript - * this.input.keyboard.addCapture(62); - * ``` - * - * An array of key codes: - * - * ```javascript - * this.input.keyboard.addCapture([ 62, 63, 64 ]); - * ``` - * - * Or a string: - * - * ```javascript - * this.input.keyboard.addCapture('W,S,A,D'); - * ``` - * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. - * - * You can also provide an array mixing both strings and key code integers. - * - * If there are active captures after calling this method, the `preventDefault` property is set to `true`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#addCapture - * @since 3.16.0 - * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser. - */ - addCapture: function (keycode) - { - if (typeof keycode === 'string') - { - keycode = keycode.split(','); - } - - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } - - var captures = this.captures; - - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; - - if (typeof code === 'string') - { - code = KeyCodes[code.trim().toUpperCase()]; - } - - if (captures.indexOf(code) === -1) - { - captures.push(code); - } - } - - this.preventDefault = captures.length > 0; - }, - - /** - * Removes an existing key capture. - * - * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove - * the capture of a key, then it will remove it for any Scene in your game, not just the calling one. - * - * You can pass in a single key code value, or an array of key codes, or a string: - * - * ```javascript - * this.input.keyboard.removeCapture(62); - * ``` - * - * An array of key codes: - * - * ```javascript - * this.input.keyboard.removeCapture([ 62, 63, 64 ]); - * ``` - * - * Or a string: - * - * ```javascript - * this.input.keyboard.removeCapture('W,S,A,D'); - * ``` - * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. - * - * You can also provide an array mixing both strings and key code integers. - * - * If there are no captures left after calling this method, the `preventDefault` property is set to `false`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#removeCapture - * @since 3.16.0 - * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again. - */ - removeCapture: function (keycode) - { - if (typeof keycode === 'string') - { - keycode = keycode.split(','); - } - - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } - - var captures = this.captures; - - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; - - if (typeof code === 'string') - { - code = KeyCodes[code.toUpperCase()]; - } - - ArrayRemove(captures, code); - } - - this.preventDefault = captures.length > 0; - }, - - /** - * Removes all keyboard captures and sets the `preventDefault` property to `false`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures - * @since 3.16.0 - */ - clearCaptures: function () - { - this.captures = []; - - this.preventDefault = false; - }, - - /** - * Destroys this Keyboard Manager instance. - * - * @method Phaser.Input.Keyboard.KeyboardManager#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.stopListeners(); - - this.clearCaptures(); - - this.queue = []; - - this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = KeyboardManager; - - -/***/ }), -/* 389 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Features = __webpack_require__(187); -var InputEvents = __webpack_require__(49); -var NOOP = __webpack_require__(1); - -// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent -// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md - -/** - * @classdesc - * The Mouse Manager is a helper class that belongs to the Input Manager. - * - * Its role is to listen for native DOM Mouse Events and then pass them onto the Input Manager for further processing. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically. - * - * @class MouseManager - * @memberof Phaser.Input.Mouse - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var MouseManager = new Class({ - - initialize: - - function MouseManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Mouse.MouseManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = inputManager; - - /** - * If `true` the DOM `mousedown` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultDown - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultDown = true; - - /** - * If `true` the DOM `mouseup` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultUp - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultUp = true; - - /** - * If `true` the DOM `mousemove` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultMove - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultMove = true; - - /** - * If `true` the DOM `wheel` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultWheel - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultWheel = false; - - /** - * A boolean that controls if the Mouse Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Mouse.MouseManager#enabled - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.enabled = false; - - /** - * The Mouse target, as defined in the Game Config. - * Typically the canvas to which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Mouse.MouseManager#target - * @type {any} - * @since 3.0.0 - */ - this.target; - - /** - * If the mouse has been pointer locked successfully this will be set to true. - * - * @name Phaser.Input.Mouse.MouseManager#locked - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.locked = false; - - /** - * The Mouse Move Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseMove - * @type {function} - * @since 3.10.0 - */ - this.onMouseMove = NOOP; - - /** - * The Mouse Down Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseDown - * @type {function} - * @since 3.10.0 - */ - this.onMouseDown = NOOP; - - /** - * The Mouse Up Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseUp - * @type {function} - * @since 3.10.0 - */ - this.onMouseUp = NOOP; - - /** - * The Mouse Down Event handler specifically for events on the Window. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseDownWindow - * @type {function} - * @since 3.17.0 - */ - this.onMouseDownWindow = NOOP; - - /** - * The Mouse Up Event handler specifically for events on the Window. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseUpWindow - * @type {function} - * @since 3.17.0 - */ - this.onMouseUpWindow = NOOP; - - /** - * The Mouse Over Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseOver - * @type {function} - * @since 3.16.0 - */ - this.onMouseOver = NOOP; - - /** - * The Mouse Out Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseOut - * @type {function} - * @since 3.16.0 - */ - this.onMouseOut = NOOP; - - /** - * The Mouse Wheel Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseWheel - * @type {function} - * @since 3.18.0 - */ - this.onMouseWheel = NOOP; - - /** - * Internal pointerLockChange handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#pointerLockChange - * @type {function} - * @since 3.0.0 - */ - this.pointerLockChange = NOOP; - - /** - * Are the event listeners hooked into `window.top` or `window`? - * - * This is set during the `boot` sequence. If the browser does not have access to `window.top`, - * such as in cross-origin iframe environments, this property gets set to `false` and the events - * are hooked into `window` instead. - * - * @name Phaser.Input.Mouse.MouseManager#isTop - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.isTop = true; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Touch Manager boot process. - * - * @method Phaser.Input.Mouse.MouseManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputMouse; - this.target = config.inputMouseEventTarget; - this.passive = config.inputMousePassive; - - this.preventDefaultDown = config.inputMousePreventDefaultDown; - this.preventDefaultUp = config.inputMousePreventDefaultUp; - this.preventDefaultMove = config.inputMousePreventDefaultMove; - this.preventDefaultWheel = config.inputMousePreventDefaultWheel; - - if (!this.target) - { - this.target = this.manager.game.canvas; - } - else if (typeof this.target === 'string') - { - this.target = document.getElementById(this.target); - } - - if (config.disableContextMenu) - { - this.disableContextMenu(); - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - }, - - /** - * Attempts to disable the context menu from appearing if you right-click on the browser. - * - * Works by listening for the `contextmenu` event and prevent defaulting it. - * - * Use this if you need to enable right-button mouse support in your game, and the browser - * menu keeps getting in the way. - * - * @method Phaser.Input.Mouse.MouseManager#disableContextMenu - * @since 3.0.0 - * - * @return {this} This Mouse Manager instance. - */ - disableContextMenu: function () - { - document.body.addEventListener('contextmenu', function (event) - { - event.preventDefault(); - return false; - }); - - return this; - }, - - /** - * If the browser supports it, you can request that the pointer be locked to the browser window. - * - * This is classically known as 'FPS controls', where the pointer can't leave the browser until - * the user presses an exit key. - * - * If the browser successfully enters a locked state, a `POINTER_LOCK_CHANGE_EVENT` will be dispatched, - * from the games Input Manager, with an `isPointerLocked` property. - * - * It is important to note that pointer lock can only be enabled after an 'engagement gesture', - * see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture. - * - * Note for Firefox: There is a bug in certain Firefox releases that cause native DOM events like - * `mousemove` to fire continuously when in pointer lock mode. You can get around this by setting - * `this.preventDefaultMove` to `false` in this class. You may also need to do the same for - * `preventDefaultDown` and/or `preventDefaultUp`. Please test combinations of these if you encounter - * the error. - * - * @method Phaser.Input.Mouse.MouseManager#requestPointerLock - * @since 3.0.0 - */ - requestPointerLock: function () - { - if (Features.pointerLock) - { - var element = this.target; - - element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; - - element.requestPointerLock(); - } - }, - - /** - * If the browser supports pointer lock, this will request that the pointer lock is released. If - * the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be - * dispatched - from the game's input manager - with an `isPointerLocked` property. - * - * @method Phaser.Input.Mouse.MouseManager#releasePointerLock - * @since 3.0.0 - */ - releasePointerLock: function () - { - if (Features.pointerLock) - { - document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; - document.exitPointerLock(); - } - }, - - /** - * Starts the Mouse Event listeners running. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Mouse.MouseManager#startListeners - * @since 3.0.0 - */ - startListeners: function () - { - var target = this.target; - - if (!target) - { - return; - } - - var _this = this; - var manager = this.manager; - var canvas = manager.canvas; - var autoFocus = (window && window.focus && manager.game.config.autoFocus); - - this.onMouseMove = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseMove(event); - - if (_this.preventDefaultMove) - { - event.preventDefault(); - } - } - }; - - this.onMouseDown = function (event) - { - if (autoFocus) - { - window.focus(); - } - - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseDown(event); - - if (_this.preventDefaultDown && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onMouseDownWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - manager.onMouseDown(event); - } - }; - - this.onMouseUp = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseUp(event); - - if (_this.preventDefaultUp && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onMouseUpWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - manager.onMouseUp(event); - } - }; - - this.onMouseOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOver(event); - } - }; - - this.onMouseOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOut(event); - } - }; - - this.onMouseWheel = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseWheel(event); - } - - if (_this.preventDefaultWheel && event.target === canvas) - { - event.preventDefault(); - } - }; - - var passive = { passive: true }; - - target.addEventListener('mousemove', this.onMouseMove); - target.addEventListener('mousedown', this.onMouseDown); - target.addEventListener('mouseup', this.onMouseUp); - target.addEventListener('mouseover', this.onMouseOver, passive); - target.addEventListener('mouseout', this.onMouseOut, passive); - - if (this.preventDefaultWheel) - { - target.addEventListener('wheel', this.onMouseWheel, { passive: false }); - } - else - { - target.addEventListener('wheel', this.onMouseWheel, passive); - } - - if (window && manager.game.config.inputWindowEvents) - { - try - { - window.top.addEventListener('mousedown', this.onMouseDownWindow, passive); - window.top.addEventListener('mouseup', this.onMouseUpWindow, passive); - } - catch (exception) - { - window.addEventListener('mousedown', this.onMouseDownWindow, passive); - window.addEventListener('mouseup', this.onMouseUpWindow, passive); - - this.isTop = false; - } - } - - if (Features.pointerLock) - { - this.pointerLockChange = function (event) - { - var element = _this.target; - - _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; - - manager.onPointerLockChange(event); - }; - - document.addEventListener('pointerlockchange', this.pointerLockChange, true); - document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); - } - - this.enabled = true; - }, - - /** - * Stops the Mouse Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Mouse.MouseManager#stopListeners - * @since 3.0.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('mousemove', this.onMouseMove); - target.removeEventListener('mousedown', this.onMouseDown); - target.removeEventListener('mouseup', this.onMouseUp); - target.removeEventListener('mouseover', this.onMouseOver); - target.removeEventListener('mouseout', this.onMouseOut); - - if (window) - { - target = (this.isTop) ? window.top : window; - - target.removeEventListener('mousedown', this.onMouseDownWindow); - target.removeEventListener('mouseup', this.onMouseUpWindow); - } - - if (Features.pointerLock) - { - document.removeEventListener('pointerlockchange', this.pointerLockChange, true); - document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); - } - }, - - /** - * Destroys this Mouse Manager instance. - * - * @method Phaser.Input.Mouse.MouseManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stopListeners(); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = MouseManager; - - -/***/ }), -/* 390 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Angle = __webpack_require__(343); -var Class = __webpack_require__(0); -var Distance = __webpack_require__(48); -var FuzzyEqual = __webpack_require__(121); -var SmoothStepInterpolation = __webpack_require__(354); -var Vector2 = __webpack_require__(3); -var OS = __webpack_require__(102); - -/** - * @classdesc - * A Pointer object encapsulates both mouse and touch input within Phaser. - * - * By default, Phaser will create 2 pointers for your game to use. If you require more, i.e. for a multi-touch - * game, then use the `InputPlugin.addPointer` method to do so, rather than instantiating this class directly, - * otherwise it won't be managed by the input system. - * - * You can reference the current active pointer via `InputPlugin.activePointer`. You can also use the properties - * `InputPlugin.pointer1` through to `pointer10`, for each pointer you have enabled in your game. - * - * The properties of this object are set by the Input Plugin during processing. This object is then sent in all - * input related events that the Input Plugin emits, so you can reference properties from it directly in your - * callbacks. - * - * @class Pointer - * @memberof Phaser.Input - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} manager - A reference to the Input Manager. - * @param {number} id - The internal ID of this Pointer. - */ -var Pointer = new Class({ - - initialize: - - function Pointer (manager, id) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Pointer#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * The internal ID of this Pointer. - * - * @name Phaser.Input.Pointer#id - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.id = id; - - /** - * The most recent native DOM Event this Pointer has processed. - * - * @name Phaser.Input.Pointer#event - * @type {(TouchEvent|MouseEvent)} - * @since 3.0.0 - */ - this.event; - - /** - * The DOM element the Pointer was pressed down on, taken from the DOM event. - * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. - * - * @name Phaser.Input.Pointer#downElement - * @type {any} - * @readonly - * @since 3.16.0 - */ - this.downElement; - - /** - * The DOM element the Pointer was released on, taken from the DOM event. - * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. - * - * @name Phaser.Input.Pointer#upElement - * @type {any} - * @readonly - * @since 3.16.0 - */ - this.upElement; - - /** - * The camera the Pointer interacted with during its last update. - * - * A Pointer can only ever interact with one camera at once, which will be the top-most camera - * in the list should multiple cameras be positioned on-top of each other. - * - * @name Phaser.Input.Pointer#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @default null - * @since 3.0.0 - */ - this.camera = null; - - /** - * A read-only property that indicates which button was pressed, or released, on the pointer - * during the most recent event. It is only set during `up` and `down` events. - * - * On Touch devices the value is always 0. - * - * Users may change the configuration of buttons on their pointing device so that if an event's button property - * is zero, it may not have been caused by the button that is physically left–most on the pointing device; - * however, it should behave as if the left button was clicked in the standard button layout. - * - * @name Phaser.Input.Pointer#button - * @type {number} - * @readonly - * @default 0 - * @since 3.18.0 - */ - this.button = 0; - - /** - * 0: No button or un-initialized - * 1: Left button - * 2: Right button - * 4: Wheel button or middle button - * 8: 4th button (typically the "Browser Back" button) - * 16: 5th button (typically the "Browser Forward" button) - * - * For a mouse configured for left-handed use, the button actions are reversed. - * In this case, the values are read from right to left. - * - * @name Phaser.Input.Pointer#buttons - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.buttons = 0; - - /** - * The position of the Pointer in screen space. - * - * @name Phaser.Input.Pointer#position - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.position = new Vector2(); - - /** - * The previous position of the Pointer in screen space. - * - * The old x and y values are stored in here during the InputManager.transformPointer call. - * - * Use the properties `velocity`, `angle` and `distance` to create your own gesture recognition. - * - * @name Phaser.Input.Pointer#prevPosition - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.11.0 - */ - this.prevPosition = new Vector2(); - - /** - * An internal vector used for calculations of the pointer speed and angle. - * - * @name Phaser.Input.Pointer#midPoint - * @type {Phaser.Math.Vector2} - * @private - * @since 3.16.0 - */ - this.midPoint = new Vector2(-1, -1); - - /** - * The current velocity of the Pointer, based on its current and previous positions. - * - * This value is smoothed out each frame, according to the `motionFactor` property. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * @name Phaser.Input.Pointer#velocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.16.0 - */ - this.velocity = new Vector2(); - - /** - * The current angle the Pointer is moving, in radians, based on its previous and current position. - * - * The angle is based on the old position facing to the current position. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * @name Phaser.Input.Pointer#angle - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.angle = 0; - - /** - * The distance the Pointer has moved, based on its previous and current position. - * - * This value is smoothed out each frame, according to the `motionFactor` property. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * If you need the total distance travelled since the primary buttons was pressed down, - * then use the `Pointer.getDistance` method. - * - * @name Phaser.Input.Pointer#distance - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.distance = 0; - - /** - * The smoothing factor to apply to the Pointer position. - * - * Due to their nature, pointer positions are inherently noisy. While this is fine for lots of games, if you need cleaner positions - * then you can set this value to apply an automatic smoothing to the positions as they are recorded. - * - * The default value of zero means 'no smoothing'. - * Set to a small value, such as 0.2, to apply an average level of smoothing between positions. You can do this by changing this - * value directly, or by setting the `input.smoothFactor` property in the Game Config. - * - * Positions are only smoothed when the pointer moves. If the primary button on this Pointer enters an Up or Down state, then the position - * is always precise, and not smoothed. - * - * @name Phaser.Input.Pointer#smoothFactor - * @type {number} - * @default 0 - * @since 3.16.0 - */ - this.smoothFactor = 0; - - /** - * The factor applied to the motion smoothing each frame. - * - * This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, - * angle and distance of the Pointer. It's applied every frame, until the midPoint reaches the current - * position of the Pointer. 0.2 provides a good average but can be increased if you need a - * quicker update and are working in a high performance environment. Never set this value to - * zero. - * - * @name Phaser.Input.Pointer#motionFactor - * @type {number} - * @default 0.2 - * @since 3.16.0 - */ - this.motionFactor = 0.2; - - /** - * The x position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. - * - * If you wish to use this value _outside_ of an input event handler then you should update it first by calling - * the `Pointer.updateWorldPoint` method. - * - * @name Phaser.Input.Pointer#worldX - * @type {number} - * @default 0 - * @since 3.10.0 - */ - this.worldX = 0; - - /** - * The y position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. - * - * If you wish to use this value _outside_ of an input event handler then you should update it first by calling - * the `Pointer.updateWorldPoint` method. - * - * @name Phaser.Input.Pointer#worldY - * @type {number} - * @default 0 - * @since 3.10.0 - */ - this.worldY = 0; - - /** - * Time when this Pointer was most recently moved (regardless of the state of its buttons, if any) - * - * @name Phaser.Input.Pointer#moveTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.moveTime = 0; - - /** - * X coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. - * - * @name Phaser.Input.Pointer#downX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downX = 0; - - /** - * Y coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. - * - * @name Phaser.Input.Pointer#downY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downY = 0; - - /** - * The Event timestamp when the first button, or Touch input, was pressed. Used for dragging objects. - * - * @name Phaser.Input.Pointer#downTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downTime = 0; - - /** - * X coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. - * - * @name Phaser.Input.Pointer#upX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upX = 0; - - /** - * Y coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. - * - * @name Phaser.Input.Pointer#upY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upY = 0; - - /** - * The Event timestamp when the final button, or Touch input, was released. Used for dragging objects. - * - * @name Phaser.Input.Pointer#upTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upTime = 0; - - /** - * Is the primary button down? (usually button 0, the left mouse button) - * - * @name Phaser.Input.Pointer#primaryDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.primaryDown = false; - - /** - * Is _any_ button on this pointer considered as being down? - * - * @name Phaser.Input.Pointer#isDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isDown = false; - - /** - * Did the previous input event come from a Touch input (true) or Mouse? (false) - * - * @name Phaser.Input.Pointer#wasTouch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.wasTouch = false; - - /** - * Did this Pointer get canceled by a touchcancel event? - * - * Note: "canceled" is the American-English spelling of "cancelled". Please don't submit PRs correcting it! - * - * @name Phaser.Input.Pointer#wasCanceled - * @type {boolean} - * @default false - * @since 3.15.0 - */ - this.wasCanceled = false; - - /** - * If the mouse is locked, the horizontal relative movement of the Pointer in pixels since last frame. - * - * @name Phaser.Input.Pointer#movementX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.movementX = 0; - - /** - * If the mouse is locked, the vertical relative movement of the Pointer in pixels since last frame. - * - * @name Phaser.Input.Pointer#movementY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.movementY = 0; - - /** - * The identifier property of the Pointer as set by the DOM event when this Pointer is started. - * - * @name Phaser.Input.Pointer#identifier - * @type {number} - * @since 3.10.0 - */ - this.identifier = 0; - - /** - * The pointerId property of the Pointer as set by the DOM event when this Pointer is started. - * The browser can and will recycle this value. - * - * @name Phaser.Input.Pointer#pointerId - * @type {number} - * @since 3.10.0 - */ - this.pointerId = null; - - /** - * An active Pointer is one that is currently pressed down on the display. - * A Mouse is always considered as active. - * - * @name Phaser.Input.Pointer#active - * @type {boolean} - * @since 3.10.0 - */ - this.active = (id === 0) ? true : false; - - /** - * Is this pointer Pointer Locked? - * - * Only a mouse pointer can be locked and it only becomes locked when requested via - * the browsers Pointer Lock API. - * - * You can request this by calling the `this.input.mouse.requestPointerLock()` method from - * a `pointerdown` or `pointerup` event handler. - * - * @name Phaser.Input.Pointer#locked - * @readonly - * @type {boolean} - * @since 3.19.0 - */ - this.locked = false; - - /** - * The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * - * @name Phaser.Input.Pointer#deltaX - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaX = 0; - - /** - * The vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * This value will typically be less than 0 if the user scrolls up and greater than zero if scrolling down. - * - * @name Phaser.Input.Pointer#deltaY - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaY = 0; - - /** - * The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * - * @name Phaser.Input.Pointer#deltaZ - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaZ = 0; - }, - - /** - * Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are - * the result of a translation through the given Camera. - * - * Note that the values will be automatically replaced the moment the Pointer is - * updated by an input event, such as a mouse move, so should be used immediately. - * - * @method Phaser.Input.Pointer#updateWorldPoint - * @since 3.19.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * - * @return {this} This Pointer object. - */ - updateWorldPoint: function (camera) - { - // Stores the world point inside of tempPoint - var temp = camera.getWorldPoint(this.x, this.y); - - this.worldX = temp.x; - this.worldY = temp.y; - - return this; - }, - - /** - * Takes a Camera and returns a Vector2 containing the translated position of this Pointer - * within that Camera. This can be used to convert this Pointers position into camera space. - * - * @method Phaser.Input.Pointer#positionToCamera - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the translation. - * @param {(Phaser.Math.Vector2|object)} [output] - A Vector2-like object in which to store the translated position. - * - * @return {(Phaser.Math.Vector2|object)} A Vector2 containing the translated coordinates of this Pointer, based on the given camera. - */ - positionToCamera: function (camera, output) - { - return camera.getWorldPoint(this.x, this.y, output); - }, - - /** - * Calculates the motion of this Pointer, including its velocity and angle of movement. - * This method is called automatically each frame by the Input Manager. - * - * @method Phaser.Input.Pointer#updateMotion - * @private - * @since 3.16.0 - */ - updateMotion: function () - { - var cx = this.position.x; - var cy = this.position.y; - - var mx = this.midPoint.x; - var my = this.midPoint.y; - - if (cx === mx && cy === my) - { - // Nothing to do here - return; - } - - // Moving towards our goal ... - var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); - var vy = SmoothStepInterpolation(this.motionFactor, my, cy); - - if (FuzzyEqual(vx, cx, 0.1)) - { - vx = cx; - } - - if (FuzzyEqual(vy, cy, 0.1)) - { - vy = cy; - } - - this.midPoint.set(vx, vy); - - var dx = cx - vx; - var dy = cy - vy; - - this.velocity.set(dx, dy); - - this.angle = Angle(vx, vy, cx, cy); - - this.distance = Math.sqrt(dx * dx + dy * dy); - }, - - /** - * Internal method to handle a Mouse Up Event. - * - * @method Phaser.Input.Pointer#up - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - up: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - this.button = event.button; - - this.upElement = event.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - // 0: Main button pressed, usually the left button or the un-initialized state - if (event.button === 0) - { - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - } - - if (this.buttons === 0) - { - // No more buttons are still down - this.isDown = false; - - this.upTime = event.timeStamp; - - this.wasTouch = false; - } - }, - - /** - * Internal method to handle a Mouse Down Event. - * - * @method Phaser.Input.Pointer#down - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - down: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - this.button = event.button; - - this.downElement = event.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - // 0: Main button pressed, usually the left button or the un-initialized state - if (event.button === 0) - { - this.primaryDown = true; - this.downX = this.x; - this.downY = this.y; - } - - if (OS.macOS && event.ctrlKey) - { - // Override button settings on macOS - this.buttons = 2; - this.primaryDown = false; - } - - if (!this.isDown) - { - this.isDown = true; - - this.downTime = event.timeStamp; - } - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Mouse Move Event. - * - * @method Phaser.Input.Pointer#move - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - move: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, true); - - if (this.locked) - { - // Multiple DOM events may occur within one frame, but only one Phaser event will fire - this.movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; - this.movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; - } - - this.moveTime = event.timeStamp; - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Mouse Wheel Event. - * - * @method Phaser.Input.Pointer#wheel - * @private - * @since 3.18.0 - * - * @param {WheelEvent} event - The Wheel Event to process. - */ - wheel: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - this.deltaX = event.deltaX; - this.deltaY = event.deltaY; - this.deltaZ = event.deltaZ; - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Touch Start Event. - * - * @method Phaser.Input.Pointer#touchstart - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchstart: function (touch, event) - { - if (touch['pointerId']) - { - this.pointerId = touch.pointerId; - } - - this.identifier = touch.identifier; - this.target = touch.target; - this.active = true; - - this.buttons = 1; - - this.event = event; - - this.downElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = true; - this.downX = this.x; - this.downY = this.y; - this.downTime = event.timeStamp; - - this.isDown = true; - - this.wasTouch = true; - this.wasCanceled = false; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch Move Event. - * - * @method Phaser.Input.Pointer#touchmove - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchmove: function (touch, event) - { - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, true); - - this.moveTime = event.timeStamp; - - this.wasTouch = true; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch End Event. - * - * @method Phaser.Input.Pointer#touchend - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchend: function (touch, event) - { - this.buttons = 0; - - this.event = event; - - this.upElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - this.upTime = event.timeStamp; - - this.isDown = false; - - this.wasTouch = true; - this.wasCanceled = false; - - this.active = false; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch Cancel Event. - * - * @method Phaser.Input.Pointer#touchcancel - * @private - * @since 3.15.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchcancel: function (touch, event) - { - this.buttons = 0; - - this.event = event; - - this.upElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - this.upTime = event.timeStamp; - - this.isDown = false; - - this.wasTouch = true; - this.wasCanceled = true; - - this.active = false; - }, - - /** - * Checks to see if any buttons are being held down on this Pointer. - * - * @method Phaser.Input.Pointer#noButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if no buttons are being held down. - */ - noButtonDown: function () - { - return (this.buttons === 0); - }, - - /** - * Checks to see if the left button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#leftButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the left button is being held down. - */ - leftButtonDown: function () - { - return (this.buttons & 1) ? true : false; - }, - - /** - * Checks to see if the right button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#rightButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the right button is being held down. - */ - rightButtonDown: function () - { - return (this.buttons & 2) ? true : false; - }, - - /** - * Checks to see if the middle button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#middleButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the middle button is being held down. - */ - middleButtonDown: function () - { - return (this.buttons & 4) ? true : false; - }, - - /** - * Checks to see if the back button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#backButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the back button is being held down. - */ - backButtonDown: function () - { - return (this.buttons & 8) ? true : false; - }, - - /** - * Checks to see if the forward button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#forwardButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the forward button is being held down. - */ - forwardButtonDown: function () - { - return (this.buttons & 16) ? true : false; - }, - - /** - * Checks to see if the left button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#leftButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the left button was just released. - */ - leftButtonReleased: function () - { - return (this.button === 0 && !this.isDown); - }, - - /** - * Checks to see if the right button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#rightButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the right button was just released. - */ - rightButtonReleased: function () - { - return (this.button === 2 && !this.isDown); - }, - - /** - * Checks to see if the middle button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#middleButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the middle button was just released. - */ - middleButtonReleased: function () - { - return (this.button === 1 && !this.isDown); - }, - - /** - * Checks to see if the back button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#backButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the back button was just released. - */ - backButtonReleased: function () - { - return (this.button === 3 && !this.isDown); - }, - - /** - * Checks to see if the forward button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#forwardButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the forward button was just released. - */ - forwardButtonReleased: function () - { - return (this.button === 4 && !this.isDown); - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded distance, based on where - * the Pointer was when the button was released. - * - * If you wish to get the distance being travelled currently, based on the velocity of the Pointer, - * then see the `Pointer.distance` property. - * - * @method Phaser.Input.Pointer#getDistance - * @since 3.13.0 - * - * @return {number} The distance the Pointer moved. - */ - getDistance: function () - { - if (this.isDown) - { - return Distance(this.downX, this.downY, this.x, this.y); - } - else - { - return Distance(this.downX, this.downY, this.upX, this.upY); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * horizontal distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded horizontal distance, based on where - * the Pointer was when the button was released. - * - * @method Phaser.Input.Pointer#getDistanceX - * @since 3.16.0 - * - * @return {number} The horizontal distance the Pointer moved. - */ - getDistanceX: function () - { - if (this.isDown) - { - return Math.abs(this.downX - this.x); - } - else - { - return Math.abs(this.downX - this.upX); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * vertical distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded vertical distance, based on where - * the Pointer was when the button was released. - * - * @method Phaser.Input.Pointer#getDistanceY - * @since 3.16.0 - * - * @return {number} The vertical distance the Pointer moved. - */ - getDistanceY: function () - { - if (this.isDown) - { - return Math.abs(this.downY - this.y); - } - else - { - return Math.abs(this.downY - this.upY); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * duration since the button was pressed down. - * - * If no button is held down, it will return the last recorded duration, based on the time - * the last button on the Pointer was released. - * - * @method Phaser.Input.Pointer#getDuration - * @since 3.16.0 - * - * @return {number} The duration the Pointer was held down for in milliseconds. - */ - getDuration: function () - { - if (this.isDown) - { - return (this.manager.time - this.downTime); - } - else - { - return (this.upTime - this.downTime); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * angle between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded angle, based on where - * the Pointer was when the button was released. - * - * The angle is based on the old position facing to the current position. - * - * If you wish to get the current angle, based on the velocity of the Pointer, then - * see the `Pointer.angle` property. - * - * @method Phaser.Input.Pointer#getAngle - * @since 3.16.0 - * - * @return {number} The angle between the Pointer's coordinates in radians. - */ - getAngle: function () - { - if (this.isDown) - { - return Angle(this.downX, this.downY, this.x, this.y); - } - else - { - return Angle(this.downX, this.downY, this.upX, this.upY); - } - }, - - /** - * Takes the previous and current Pointer positions and then generates an array of interpolated values between - * the two. The array will be populated up to the size of the `steps` argument. - * - * ```javaScript - * var points = pointer.getInterpolatedPosition(4); - * - * // points[0] = { x: 0, y: 0 } - * // points[1] = { x: 2, y: 1 } - * // points[2] = { x: 3, y: 2 } - * // points[3] = { x: 6, y: 3 } - * ``` - * - * Use this if you need to get smoothed values between the previous and current pointer positions. DOM pointer - * events can often fire faster than the main browser loop, and this will help you avoid janky movement - * especially if you have an object following a Pointer. - * - * Note that if you provide an output array it will only be populated up to the number of steps provided. - * It will not clear any previous data that may have existed beyond the range of the steps count. - * - * Internally it uses the Smooth Step interpolation calculation. - * - * @method Phaser.Input.Pointer#getInterpolatedPosition - * @since 3.11.0 - * - * @param {number} [steps=10] - The number of interpolation steps to use. - * @param {array} [out] - An array to store the results in. If not provided a new one will be created. - * - * @return {array} An array of interpolated values. - */ - getInterpolatedPosition: function (steps, out) - { - if (steps === undefined) { steps = 10; } - if (out === undefined) { out = []; } - - var prevX = this.prevPosition.x; - var prevY = this.prevPosition.y; - - var curX = this.position.x; - var curY = this.position.y; - - for (var i = 0; i < steps; i++) - { - var t = (1 / steps) * i; - - out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; - } - - return out; - }, - - /** - * Destroys this Pointer instance and resets its external references. - * - * @method Phaser.Input.Pointer#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.camera = null; - this.manager = null; - this.position = null; - }, - - /** - * The x position of this Pointer. - * The value is in screen space. - * See `worldX` to get a camera converted position. - * - * @name Phaser.Input.Pointer#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.position.x = value; - } - - }, - - /** - * The y position of this Pointer. - * The value is in screen space. - * See `worldY` to get a camera converted position. - * - * @name Phaser.Input.Pointer#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.position.y = value; - } - - }, - - /** - * Time when this Pointer was most recently updated by a DOM Event. - * This comes directly from the `event.timeStamp` property. - * If no event has yet taken place, it will return zero. - * - * @name Phaser.Input.Pointer#time - * @type {number} - * @readonly - * @since 3.16.0 - */ - time: { - - get: function () - { - return (this.event) ? this.event.timeStamp : 0; - } - - } - -}); - -module.exports = Pointer; - - -/***/ }), -/* 391 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var InputEvents = __webpack_require__(49); -var NOOP = __webpack_require__(1); - -// https://developer.mozilla.org/en-US/docs/Web/API/Touch_events -// https://patrickhlauke.github.io/touch/tests/results/ -// https://www.html5rocks.com/en/mobile/touch/ - -/** - * @classdesc - * The Touch Manager is a helper class that belongs to the Input Manager. - * - * Its role is to listen for native DOM Touch Events and then pass them onto the Input Manager for further processing. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically. - * - * @class TouchManager - * @memberof Phaser.Input.Touch - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var TouchManager = new Class({ - - initialize: - - function TouchManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Touch.TouchManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = inputManager; - - /** - * If true the DOM events will have event.preventDefault applied to them, if false they will propagate fully. - * - * @name Phaser.Input.Touch.TouchManager#capture - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.capture = true; - - /** - * A boolean that controls if the Touch Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Touch.TouchManager#enabled - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.enabled = false; - - /** - * The Touch Event target, as defined in the Game Config. - * Typically the canvas to which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Touch.TouchManager#target - * @type {any} - * @since 3.0.0 - */ - this.target; - - /** - * The Touch Start event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchStart - * @type {function} - * @since 3.0.0 - */ - this.onTouchStart = NOOP; - - /** - * The Touch Start event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchStartWindow - * @type {function} - * @since 3.17.0 - */ - this.onTouchStartWindow = NOOP; - - /** - * The Touch Move event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchMove - * @type {function} - * @since 3.0.0 - */ - this.onTouchMove = NOOP; - - /** - * The Touch End event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchEnd - * @type {function} - * @since 3.0.0 - */ - this.onTouchEnd = NOOP; - - /** - * The Touch End event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchEndWindow - * @type {function} - * @since 3.17.0 - */ - this.onTouchEndWindow = NOOP; - - /** - * The Touch Cancel event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchCancel - * @type {function} - * @since 3.15.0 - */ - this.onTouchCancel = NOOP; - - /** - * The Touch Cancel event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchCancelWindow - * @type {function} - * @since 3.18.0 - */ - this.onTouchCancelWindow = NOOP; - - /** - * The Touch Over event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchOver - * @type {function} - * @since 3.16.0 - */ - this.onTouchOver = NOOP; - - /** - * The Touch Out event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchOut - * @type {function} - * @since 3.16.0 - */ - this.onTouchOut = NOOP; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Touch Manager boot process. - * - * @method Phaser.Input.Touch.TouchManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputTouch; - this.target = config.inputTouchEventTarget; - this.capture = config.inputTouchCapture; - - if (!this.target) - { - this.target = this.manager.game.canvas; - } - - if (config.disableContextMenu) - { - this.disableContextMenu(); - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - }, - - /** - * Attempts to disable the context menu from appearing if you touch-hold on the browser. - * - * Works by listening for the `contextmenu` event and prevent defaulting it. - * - * Use this if you need to disable the OS context menu on mobile. - * - * @method Phaser.Input.Touch.TouchManager#disableContextMenu - * @since 3.20.0 - * - * @return {this} This Touch Manager instance. - */ - disableContextMenu: function () - { - document.body.addEventListener('contextmenu', function (event) - { - event.preventDefault(); - return false; - }); - - return this; - }, - - /** - * Starts the Touch Event listeners running as long as an input target is set. - * - * This method is called automatically if Touch Input is enabled in the game config, - * which it is by default. However, you can call it manually should you need to - * delay input capturing until later in the game. - * - * @method Phaser.Input.Touch.TouchManager#startListeners - * @since 3.0.0 - */ - startListeners: function () - { - var _this = this; - var canvas = this.manager.canvas; - var autoFocus = (window && window.focus && this.manager.game.config.autoFocus); - - this.onTouchStart = function (event) - { - if (autoFocus) - { - window.focus(); - } - - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchStart(event); - - if (_this.capture && event.cancelable && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onTouchStartWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - _this.manager.onTouchStart(event); - } - }; - - this.onTouchMove = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchMove(event); - - if (_this.capture && event.cancelable) - { - event.preventDefault(); - } - } - }; - - this.onTouchEnd = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchEnd(event); - - if (_this.capture && event.cancelable && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onTouchEndWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - _this.manager.onTouchEnd(event); - } - }; - - this.onTouchCancel = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchCancel(event); - - if (_this.capture) - { - event.preventDefault(); - } - } - }; - - this.onTouchCancelWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchCancel(event); - } - }; - - this.onTouchOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.setCanvasOver(event); - } - }; - - this.onTouchOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.setCanvasOut(event); - } - }; - - var target = this.target; - - if (!target) - { - return; - } - - var passive = { passive: true }; - var nonPassive = { passive: false }; - - target.addEventListener('touchstart', this.onTouchStart, (this.capture) ? nonPassive : passive); - target.addEventListener('touchmove', this.onTouchMove, (this.capture) ? nonPassive : passive); - target.addEventListener('touchend', this.onTouchEnd, (this.capture) ? nonPassive : passive); - target.addEventListener('touchcancel', this.onTouchCancel, (this.capture) ? nonPassive : passive); - target.addEventListener('touchover', this.onTouchOver, (this.capture) ? nonPassive : passive); - target.addEventListener('touchout', this.onTouchOut, (this.capture) ? nonPassive : passive); - - if (window && this.manager.game.config.inputWindowEvents) - { - window.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); - window.addEventListener('touchend', this.onTouchEndWindow, nonPassive); - window.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); - } - - this.enabled = true; - }, - - /** - * Stops the Touch Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Touch.TouchManager#stopListeners - * @since 3.0.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('touchstart', this.onTouchStart); - target.removeEventListener('touchmove', this.onTouchMove); - target.removeEventListener('touchend', this.onTouchEnd); - target.removeEventListener('touchcancel', this.onTouchCancel); - target.removeEventListener('touchover', this.onTouchOver); - target.removeEventListener('touchout', this.onTouchOut); - - if (window) - { - window.removeEventListener('touchstart', this.onTouchStartWindow); - window.removeEventListener('touchend', this.onTouchEndWindow); - } - }, - - /** - * Destroys this Touch Manager instance. - * - * @method Phaser.Input.Touch.TouchManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stopListeners(); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = TouchManager; - - -/***/ }), -/* 392 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var EventEmitter = __webpack_require__(9); -var FileTypesManager = __webpack_require__(8); -var GameObjectCreator = __webpack_require__(16); -var GameObjectFactory = __webpack_require__(5); -var GetFastValue = __webpack_require__(2); -var PluginCache = __webpack_require__(24); -var Remove = __webpack_require__(88); - -/** - * @classdesc - * The PluginManager is responsible for installing and adding plugins to Phaser. - * - * It is a global system and therefore belongs to the Game instance, not a specific Scene. - * - * It works in conjunction with the PluginCache. Core internal plugins automatically register themselves - * with the Cache, but it's the Plugin Manager that is responsible for injecting them into the Scenes. - * - * There are two types of plugin: - * - * 1. A Global Plugin - * 2. A Scene Plugin - * - * A Global Plugin is a plugin that lives within the Plugin Manager rather than a Scene. You can get - * access to it by calling `PluginManager.get` and providing a key. Any Scene that requests a plugin in - * this way will all get access to the same plugin instance, allowing you to use a single plugin across - * multiple Scenes. - * - * A Scene Plugin is a plugin dedicated to running within a Scene. These are different to Global Plugins - * in that their instances do not live within the Plugin Manager, but within the Scene Systems class instead. - * And that every Scene created is given its own unique instance of a Scene Plugin. Examples of core Scene - * Plugins include the Input Plugin, the Tween Plugin and the physics Plugins. - * - * You can add a plugin to Phaser in three different ways: - * - * 1. Preload it - * 2. Include it in your source code and install it via the Game Config - * 3. Include it in your source code and install it within a Scene - * - * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. - * - * For information on creating your own plugin please see the Phaser 3 Plugin Template. - * - * @class PluginManager - * @memberof Phaser.Plugins - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. - */ -var PluginManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function PluginManager (game) - { - EventEmitter.call(this); - - /** - * The game instance that owns this Plugin Manager. - * - * @name Phaser.Plugins.PluginManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * The global plugins currently running and managed by this Plugin Manager. - * A plugin must have been started at least once in order to appear in this list. - * - * @name Phaser.Plugins.PluginManager#plugins - * @type {Phaser.Types.Plugins.GlobalPlugin[]} - * @since 3.8.0 - */ - this.plugins = []; - - /** - * A list of plugin keys that should be installed into Scenes as well as the Core Plugins. - * - * @name Phaser.Plugins.PluginManager#scenePlugins - * @type {string[]} - * @since 3.8.0 - */ - this.scenePlugins = []; - - /** - * A temporary list of plugins to install when the game has booted. - * - * @name Phaser.Plugins.PluginManager#_pendingGlobal - * @private - * @type {array} - * @since 3.8.0 - */ - this._pendingGlobal = []; - - /** - * A temporary list of scene plugins to install when the game has booted. - * - * @name Phaser.Plugins.PluginManager#_pendingScene - * @private - * @type {array} - * @since 3.8.0 - */ - this._pendingScene = []; - - if (game.isBooted) - { - this.boot(); - } - else - { - game.events.once(GameEvents.BOOT, this.boot, this); - } - }, - - /** - * Run once the game has booted and installs all of the plugins configured in the Game Config. - * - * @method Phaser.Plugins.PluginManager#boot - * @protected - * @since 3.0.0 - */ - boot: function () - { - var i; - var entry; - var key; - var plugin; - var start; - var mapping; - var data; - var config = this.game.config; - - // Any plugins to install? - var list = config.installGlobalPlugins; - - // Any plugins added outside of the game config, but before the game booted? - list = list.concat(this._pendingGlobal); - - for (i = 0; i < list.length; i++) - { - entry = list[i]; - - // { key: 'TestPlugin', plugin: TestPlugin, start: true, mapping: 'test', data: { msg: 'The plugin is alive' } } - - key = GetFastValue(entry, 'key', null); - plugin = GetFastValue(entry, 'plugin', null); - start = GetFastValue(entry, 'start', false); - mapping = GetFastValue(entry, 'mapping', null); - data = GetFastValue(entry, 'data', null); - - if (key) - { - if (plugin) - { - this.install(key, plugin, start, mapping, data); - } - else - { - console.warn('Missing `plugin` for key: ' + key); - } - - } - } - - // Any scene plugins to install? - list = config.installScenePlugins; - - // Any plugins added outside of the game config, but before the game booted? - list = list.concat(this._pendingScene); - - for (i = 0; i < list.length; i++) - { - entry = list[i]; - - // { key: 'moveSpritePlugin', plugin: MoveSpritePlugin, , mapping: 'move' } - - key = GetFastValue(entry, 'key', null); - plugin = GetFastValue(entry, 'plugin', null); - mapping = GetFastValue(entry, 'mapping', null); - - if (key) - { - if (plugin) - { - this.installScenePlugin(key, plugin, mapping); - } - else - { - console.warn('Missing `plugin` for key: ' + key); - } - } - } - - this._pendingGlobal = []; - this._pendingScene = []; - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * Called by the Scene Systems class. Tells the plugin manager to install all Scene plugins into it. - * - * First it will install global references, i.e. references from the Game systems into the Scene Systems (and Scene if mapped.) - * Then it will install Core Scene Plugins followed by Scene Plugins registered with the PluginManager. - * Finally it will install any references to Global Plugins that have a Scene mapping property into the Scene itself. - * - * @method Phaser.Plugins.PluginManager#addToScene - * @protected - * @since 3.8.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems class to install all the plugins in to. - * @param {array} globalPlugins - An array of global plugins to install. - * @param {array} scenePlugins - An array of scene plugins to install. - */ - addToScene: function (sys, globalPlugins, scenePlugins) - { - var i; - var pluginKey; - var pluginList; - var game = this.game; - var scene = sys.scene; - var map = sys.settings.map; - var isBooted = sys.settings.isBooted; - - // Reference the GlobalPlugins from Game into Scene.Systems - for (i = 0; i < globalPlugins.length; i++) - { - pluginKey = globalPlugins[i]; - - if (game[pluginKey]) - { - sys[pluginKey] = game[pluginKey]; - - // Scene level injection - if (map.hasOwnProperty(pluginKey)) - { - scene[map[pluginKey]] = sys[pluginKey]; - } - } - else if (pluginKey === 'game' && map.hasOwnProperty(pluginKey)) - { - scene[map[pluginKey]] = game; - } - } - - for (var s = 0; s < scenePlugins.length; s++) - { - pluginList = scenePlugins[s]; - - for (i = 0; i < pluginList.length; i++) - { - pluginKey = pluginList[i]; - - if (!PluginCache.hasCore(pluginKey)) - { - continue; - } - - var source = PluginCache.getCore(pluginKey); - - var plugin = new source.plugin(scene, this); - - sys[source.mapping] = plugin; - - // Scene level injection - if (source.custom) - { - scene[source.mapping] = plugin; - } - else if (map.hasOwnProperty(source.mapping)) - { - scene[map[source.mapping]] = plugin; - } - - // Scene is already booted, usually because this method is being called at run-time, so boot the plugin - if (isBooted) - { - plugin.boot(); - } - } - } - - // And finally, inject any 'global scene plugins' - pluginList = this.plugins; - - for (i = 0; i < pluginList.length; i++) - { - var entry = pluginList[i]; - - if (entry.mapping) - { - scene[entry.mapping] = entry.plugin; - } - } - }, - - /** - * Called by the Scene Systems class. Returns a list of plugins to be installed. - * - * @method Phaser.Plugins.PluginManager#getDefaultScenePlugins - * @protected - * @since 3.8.0 - * - * @return {string[]} A list keys of all the Scene Plugins to install. - */ - getDefaultScenePlugins: function () - { - var list = this.game.config.defaultPlugins; - - // Merge in custom Scene plugins - list = list.concat(this.scenePlugins); - - return list; - }, - - /** - * Installs a new Scene Plugin into the Plugin Manager and optionally adds it - * to the given Scene as well. A Scene Plugin added to the manager in this way - * will be automatically installed into all new Scenes using the key and mapping given. - * - * The `key` property is what the plugin is injected into Scene.Systems as. - * The `mapping` property is optional, and if specified is what the plugin is installed into - * the Scene as. For example: - * - * ```javascript - * this.plugins.installScenePlugin('powerupsPlugin', pluginCode, 'powerups'); - * - * // and from within the scene: - * this.sys.powerupsPlugin; // key value - * this.powerups; // mapping value - * ``` - * - * This method is called automatically by Phaser if you install your plugins using either the - * Game Configuration object, or by preloading them via the Loader. - * - * @method Phaser.Plugins.PluginManager#installScenePlugin - * @since 3.8.0 - * - * @param {string} key - The property key that will be used to add this plugin to Scene.Systems. - * @param {function} plugin - The plugin code. This should be the non-instantiated version. - * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. - * @param {Phaser.Scene} [addToScene] - Optionally automatically add this plugin to the given Scene. - * @param {boolean} [fromLoader=false] - Is this being called by the Loader? - */ - installScenePlugin: function (key, plugin, mapping, addToScene, fromLoader) - { - if (fromLoader === undefined) { fromLoader = false; } - - if (typeof plugin !== 'function') - { - console.warn('Invalid Scene Plugin: ' + key); - return; - } - - if (!PluginCache.hasCore(key)) - { - // Plugin is freshly loaded - PluginCache.register(key, plugin, mapping, true); - - this.scenePlugins.push(key); - } - else if (!fromLoader && PluginCache.hasCore(key)) - { - // Plugin wasn't from the loader but already exists - console.warn('Scene Plugin key in use: ' + key); - return; - } - - if (addToScene) - { - var instance = new plugin(addToScene, this); - - addToScene.sys[key] = instance; - - if (mapping && mapping !== '') - { - addToScene[mapping] = instance; - } - - instance.boot(); - } - }, - - /** - * Installs a new Global Plugin into the Plugin Manager and optionally starts it running. - * A global plugin belongs to the Plugin Manager, rather than a specific Scene, and can be accessed - * and used by all Scenes in your game. - * - * The `key` property is what you use to access this plugin from the Plugin Manager. - * - * ```javascript - * this.plugins.install('powerupsPlugin', pluginCode); - * - * // and from within the scene: - * this.plugins.get('powerupsPlugin'); - * ``` - * - * This method is called automatically by Phaser if you install your plugins using either the - * Game Configuration object, or by preloading them via the Loader. - * - * The same plugin can be installed multiple times into the Plugin Manager by simply giving each - * instance its own unique key. - * - * @method Phaser.Plugins.PluginManager#install - * @since 3.8.0 - * - * @param {string} key - The unique handle given to this plugin within the Plugin Manager. - * @param {function} plugin - The plugin code. This should be the non-instantiated version. - * @param {boolean} [start=false] - Automatically start the plugin running? This is always `true` if you provide a mapping value. - * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. - * @param {any} [data] - A value passed to the plugin's `init` method. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if `start` was false, or game isn't yet booted. - */ - install: function (key, plugin, start, mapping, data) - { - if (start === undefined) { start = false; } - if (mapping === undefined) { mapping = null; } - if (data === undefined) { data = null; } - - if (typeof plugin !== 'function') - { - console.warn('Invalid Plugin: ' + key); - return null; - } - - if (PluginCache.hasCustom(key)) - { - console.warn('Plugin key in use: ' + key); - return null; - } - - if (mapping !== null) - { - start = true; - } - - if (!this.game.isBooted) - { - this._pendingGlobal.push({ key: key, plugin: plugin, start: start, mapping: mapping, data: data }); - } - else - { - // Add it to the plugin store - PluginCache.registerCustom(key, plugin, mapping, data); - - if (start) - { - return this.start(key); - } - } - - return null; - }, - - /** - * Gets an index of a global plugin based on the given key. - * - * @method Phaser.Plugins.PluginManager#getIndex - * @protected - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {number} The index of the plugin within the plugins array. - */ - getIndex: function (key) - { - var list = this.plugins; - - for (var i = 0; i < list.length; i++) - { - var entry = list[i]; - - if (entry.key === key) - { - return i; - } - } - - return -1; - }, - - /** - * Gets a global plugin based on the given key. - * - * @method Phaser.Plugins.PluginManager#getEntry - * @protected - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {Phaser.Types.Plugins.GlobalPlugin} The plugin entry. - */ - getEntry: function (key) - { - var idx = this.getIndex(key); - - if (idx !== -1) - { - return this.plugins[idx]; - } - }, - - /** - * Checks if the given global plugin, based on its key, is active or not. - * - * @method Phaser.Plugins.PluginManager#isActive - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {boolean} `true` if the plugin is active, otherwise `false`. - */ - isActive: function (key) - { - var entry = this.getEntry(key); - - return (entry && entry.active); - }, - - /** - * Starts a global plugin running. - * - * If the plugin was previously active then calling `start` will reset it to an active state and then - * call its `start` method. - * - * If the plugin has never been run before a new instance of it will be created within the Plugin Manager, - * its active state set and then both of its `init` and `start` methods called, in that order. - * - * If the plugin is already running under the given key then nothing happens. - * - * @method Phaser.Plugins.PluginManager#start - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to start. - * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given or plugin is already stopped. - */ - start: function (key, runAs) - { - if (runAs === undefined) { runAs = key; } - - var entry = this.getEntry(runAs); - - // Plugin already running under this key? - if (entry && !entry.active) - { - // It exists, we just need to start it up again - entry.active = true; - entry.plugin.start(); - } - else if (!entry) - { - entry = this.createEntry(key, runAs); - } - - return (entry) ? entry.plugin : null; - }, - - /** - * Creates a new instance of a global plugin, adds an entry into the plugins array and returns it. - * - * @method Phaser.Plugins.PluginManager#createEntry - * @private - * @since 3.9.0 - * - * @param {string} key - The key of the plugin to create an instance of. - * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given. - */ - createEntry: function (key, runAs) - { - var entry = PluginCache.getCustom(key); - - if (entry) - { - var instance = new entry.plugin(this); - - entry = { - key: runAs, - plugin: instance, - active: true, - mapping: entry.mapping, - data: entry.data - }; - - this.plugins.push(entry); - - instance.init(entry.data); - instance.start(); - } - - return entry; - }, - - /** - * Stops a global plugin from running. - * - * If the plugin is active then its active state will be set to false and the plugins `stop` method - * will be called. - * - * If the plugin is not already running, nothing will happen. - * - * @method Phaser.Plugins.PluginManager#stop - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to stop. - * - * @return {this} The Plugin Manager. - */ - stop: function (key) - { - var entry = this.getEntry(key); - - if (entry && entry.active) - { - entry.active = false; - entry.plugin.stop(); - } - - return this; - }, - - /** - * Gets a global plugin from the Plugin Manager based on the given key and returns it. - * - * If it cannot find an active plugin based on the key, but there is one in the Plugin Cache with the same key, - * then it will create a new instance of the cached plugin and return that. - * - * @method Phaser.Plugins.PluginManager#get - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to get. - * @param {boolean} [autoStart=true] - Automatically start a new instance of the plugin if found in the cache, but not actively running. - * - * @return {?(Phaser.Plugins.BasePlugin|function)} The plugin, or `null` if no plugin was found matching the key. - */ - get: function (key, autoStart) - { - if (autoStart === undefined) { autoStart = true; } - - var entry = this.getEntry(key); - - if (entry) - { - return entry.plugin; - } - else - { - var plugin = this.getClass(key); - - if (plugin && autoStart) - { - entry = this.createEntry(key, key); - - return (entry) ? entry.plugin : null; - } - else if (plugin) - { - return plugin; - } - } - - return null; - }, - - /** - * Returns the plugin class from the cache. - * Used internally by the Plugin Manager. - * - * @method Phaser.Plugins.PluginManager#getClass - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to get. - * - * @return {Phaser.Plugins.BasePlugin} A Plugin object - */ - getClass: function (key) - { - return PluginCache.getCustomClass(key); - }, - - /** - * Removes a global plugin from the Plugin Manager and Plugin Cache. - * - * It is up to you to remove all references to this plugin that you may hold within your game code. - * - * @method Phaser.Plugins.PluginManager#removeGlobalPlugin - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to remove. - */ - removeGlobalPlugin: function (key) - { - var entry = this.getEntry(key); - - if (entry) - { - Remove(this.plugins, entry); - } - - PluginCache.removeCustom(key); - }, - - /** - * Removes a scene plugin from the Plugin Manager and Plugin Cache. - * - * This will not remove the plugin from any active Scenes that are already using it. - * - * It is up to you to remove all references to this plugin that you may hold within your game code. - * - * @method Phaser.Plugins.PluginManager#removeScenePlugin - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to remove. - */ - removeScenePlugin: function (key) - { - Remove(this.scenePlugins, key); - - PluginCache.remove(key); - }, - - /** - * Registers a new type of Game Object with the global Game Object Factory and / or Creator. - * This is usually called from within your Plugin code and is a helpful short-cut for creating - * new Game Objects. - * - * The key is the property that will be injected into the factories and used to create the - * Game Object. For example: - * - * ```javascript - * this.plugins.registerGameObject('clown', clownFactoryCallback, clownCreatorCallback); - * // later in your game code: - * this.add.clown(); - * this.make.clown(); - * ``` - * - * The callbacks are what are called when the factories try to create a Game Object - * matching the given key. It's important to understand that the callbacks are invoked within - * the context of the GameObjectFactory. In this context there are several properties available - * to use: - * - * this.scene - A reference to the Scene that owns the GameObjectFactory. - * this.displayList - A reference to the Display List the Scene owns. - * this.updateList - A reference to the Update List the Scene owns. - * - * See the GameObjectFactory and GameObjectCreator classes for more details. - * Any public property or method listed is available from your callbacks under `this`. - * - * @method Phaser.Plugins.PluginManager#registerGameObject - * @since 3.8.0 - * - * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. - * @param {function} [factoryCallback] - The callback to invoke when the Game Object Factory is called. - * @param {function} [creatorCallback] - The callback to invoke when the Game Object Creator is called. - */ - registerGameObject: function (key, factoryCallback, creatorCallback) - { - if (factoryCallback) - { - GameObjectFactory.register(key, factoryCallback); - } - - if (creatorCallback) - { - GameObjectCreator.register(key, creatorCallback); - } - - return this; - }, - - /** - * Removes a previously registered Game Object from the global Game Object Factory and / or Creator. - * This is usually called from within your Plugin destruction code to help clean-up after your plugin has been removed. - * - * @method Phaser.Plugins.PluginManager#removeGameObject - * @since 3.19.0 - * - * @param {string} key - The key of the Game Object to be removed from the factories. - * @param {boolean} [removeFromFactory=true] - Should the Game Object be removed from the Game Object Factory? - * @param {boolean} [removeFromCreator=true] - Should the Game Object be removed from the Game Object Creator? - */ - removeGameObject: function (key, removeFromFactory, removeFromCreator) - { - if (removeFromFactory === undefined) { removeFromFactory = true; } - if (removeFromCreator === undefined) { removeFromCreator = true; } - - if (removeFromFactory) - { - GameObjectFactory.remove(key); - } - - if (removeFromCreator) - { - GameObjectCreator.remove(key); - } - - return this; - }, - - /** - * Registers a new file type with the global File Types Manager, making it available to all Loader - * Plugins created after this. - * - * This is usually called from within your Plugin code and is a helpful short-cut for creating - * new loader file types. - * - * The key is the property that will be injected into the Loader Plugin and used to load the - * files. For example: - * - * ```javascript - * this.plugins.registerFileType('wad', doomWadLoaderCallback); - * // later in your preload code: - * this.load.wad(); - * ``` - * - * The callback is what is called when the loader tries to load a file matching the given key. - * It's important to understand that the callback is invoked within - * the context of the LoaderPlugin. In this context there are several properties / methods available - * to use: - * - * this.addFile - A method to add the new file to the load queue. - * this.scene - The Scene that owns the Loader Plugin instance. - * - * See the LoaderPlugin class for more details. Any public property or method listed is available from - * your callback under `this`. - * - * @method Phaser.Plugins.PluginManager#registerFileType - * @since 3.8.0 - * - * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. - * @param {function} callback - The callback to invoke when the Game Object Factory is called. - * @param {Phaser.Scene} [addToScene] - Optionally add this file type into the Loader Plugin owned by the given Scene. - */ - registerFileType: function (key, callback, addToScene) - { - FileTypesManager.register(key, callback); - - if (addToScene && addToScene.sys.load) - { - addToScene.sys.load[key] = callback; - } - }, - - /** - * Destroys this Plugin Manager and all associated plugins. - * It will iterate all plugins found and call their `destroy` methods. - * - * The PluginCache will remove all custom plugins. - * - * @method Phaser.Plugins.PluginManager#destroy - * @since 3.8.0 - */ - destroy: function () - { - for (var i = 0; i < this.plugins.length; i++) - { - this.plugins[i].plugin.destroy(); - } - - PluginCache.destroyCustomPlugins(); - - if (this.game.noReturn) - { - PluginCache.destroyCorePlugins(); - } - - this.game = null; - this.plugins = []; - this.scenePlugins = []; - } - -}); - -/* - * "Sometimes, the elegant implementation is just a function. - * Not a method. Not a class. Not a framework. Just a function." - * -- John Carmack - */ - -module.exports = PluginManager; - - -/***/ }), -/* 393 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(196); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(101); -var GameEvents = __webpack_require__(22); -var GetInnerHeight = __webpack_require__(379); -var GetTarget = __webpack_require__(385); -var GetScreenOrientation = __webpack_require__(380); -var NOOP = __webpack_require__(1); -var Rectangle = __webpack_require__(10); -var Size = __webpack_require__(394); -var SnapFloor = __webpack_require__(76); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * The Scale Manager handles the scaling, resizing and alignment of the game canvas. - * - * The way scaling is handled is by setting the game canvas to a fixed size, which is defined in the - * game configuration. You also define the parent container in the game config. If no parent is given, - * it will default to using the document body. The Scale Manager will then look at the available space - * within the _parent_ and scale the canvas accordingly. Scaling is handled by setting the canvas CSS - * width and height properties, leaving the width and height of the canvas element itself untouched. - * Scaling is therefore achieved by keeping the core canvas the same size and 'stretching' - * it via its CSS properties. This gives the same result and speed as using the `transform-scale` CSS - * property, without the need for browser prefix handling. - * - * The calculations for the scale are heavily influenced by the bounding parent size, which is the computed - * dimensions of the canvas's parent. The CSS rules of the parent element play an important role in the - * operation of the Scale Manager. For example, if the parent has no defined width or height, then actions - * like auto-centering will fail to achieve the required result. The Scale Manager works in tandem with the - * CSS you set-up on the page hosting your game, rather than taking control of it. - * - * #### Parent and Display canvas containment guidelines: - * - * - Style the Parent element (of the game canvas) to control the Parent size and thus the games size and layout. - * - * - The Parent element's CSS styles should _effectively_ apply maximum (and minimum) bounding behavior. - * - * - The Parent element should _not_ apply a padding as this is not accounted for. - * If a padding is required apply it to the Parent's parent or apply a margin to the Parent. - * If you need to add a border, margin or any other CSS around your game container, then use a parent element and - * apply the CSS to this instead, otherwise you'll be constantly resizing the shape of the game container. - * - * - The Display canvas layout CSS styles (i.e. margins, size) should not be altered / specified as - * they may be updated by the Scale Manager. - * - * #### Scale Modes - * - * The way the scaling is handled is determined by the `scaleMode` property. The default is `NONE`, - * which prevents Phaser from scaling or touching the canvas, or its parent, at all. In this mode, you are - * responsible for all scaling. The other scaling modes afford you automatic scaling. - * - * If you wish to scale your game so that it always fits into the available space within the parent, you - * should use the scale mode `FIT`. Look at the documentation for other scale modes to see what options are - * available. Here is a basic config showing how to set this scale mode: - * - * ```javascript - * scale: { - * parent: 'yourgamediv', - * mode: Phaser.Scale.FIT, - * width: 800, - * height: 600 - * } - * ``` - * - * Place the `scale` config object within your game config. - * - * If you wish for the canvas to be resized directly, so that the canvas itself fills the available space - * (i.e. it isn't scaled, it's resized) then use the `RESIZE` scale mode. This will give you a 1:1 mapping - * of canvas pixels to game size. In this mode CSS isn't used to scale the canvas, it's literally adjusted - * to fill all available space within the parent. You should be extremely careful about the size of the - * canvas you're creating when doing this, as the larger the area, the more work the GPU has to do and it's - * very easy to hit fill-rate limits quickly. - * - * For complex, custom-scaling requirements, you should probably consider using the `RESIZE` scale mode, - * with your own limitations in place re: canvas dimensions and managing the scaling with the game scenes - * yourself. For the vast majority of games, however, the `FIT` mode is likely to be the most used. - * - * Please appreciate that the Scale Manager cannot perform miracles. All it does is scale your game canvas - * as best it can, based on what it can infer from its surrounding area. There are all kinds of environments - * where it's up to you to guide and help the canvas position itself, especially when built into rendering - * frameworks like React and Vue. If your page requires meta tags to prevent user scaling gestures, or such - * like, then it's up to you to ensure they are present in the html. - * - * #### Centering - * - * You can also have the game canvas automatically centered. Again, this relies heavily on the parent being - * properly configured and styled, as the centering offsets are based entirely on the available space - * within the parent element. Centering is disabled by default, or can be applied horizontally, vertically, - * or both. Here's an example: - * - * ```javascript - * scale: { - * parent: 'yourgamediv', - * autoCenter: Phaser.Scale.CENTER_BOTH, - * width: 800, - * height: 600 - * } - * ``` - * - * #### Fullscreen API - * - * If the browser supports it, you can send your game into fullscreen mode. In this mode, the game will fill - * the entire display, removing all browser UI and anything else present on the screen. It will remain in this - * mode until your game either disables it, or until the user tabs out or presses ESCape if on desktop. It's a - * great way to achieve a desktop-game like experience from the browser, but it does require a modern browser - * to handle it. Some mobile browsers also support this. - * - * @class ScaleManager - * @memberof Phaser.Scale - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.16.0 - * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance. - */ -var ScaleManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function ScaleManager (game) - { - EventEmitter.call(this); - - /** - * A reference to the Phaser.Game instance. - * - * @name Phaser.Scale.ScaleManager#game - * @type {Phaser.Game} - * @readonly - * @since 3.15.0 - */ - this.game = game; - - /** - * A reference to the HTML Canvas Element that Phaser uses to render the game. - * - * @name Phaser.Scale.ScaleManager#canvas - * @type {HTMLCanvasElement} - * @since 3.16.0 - */ - this.canvas; - - /** - * The DOM bounds of the canvas element. - * - * @name Phaser.Scale.ScaleManager#canvasBounds - * @type {Phaser.Geom.Rectangle} - * @since 3.16.0 - */ - this.canvasBounds = new Rectangle(); - - /** - * The parent object of the Canvas. Often a div, or the browser window, or nothing in non-browser environments. - * - * This is set in the Game Config as the `parent` property. If undefined (or just not present), it will default - * to use the document body. If specifically set to `null` Phaser will ignore all parent operations. - * - * @name Phaser.Scale.ScaleManager#parent - * @type {?any} - * @since 3.16.0 - */ - this.parent = null; - - /** - * Is the parent element the browser window? - * - * @name Phaser.Scale.ScaleManager#parentIsWindow - * @type {boolean} - * @since 3.16.0 - */ - this.parentIsWindow = false; - - /** - * The Parent Size component. - * - * @name Phaser.Scale.ScaleManager#parentSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.parentSize = new Size(); - - /** - * The Game Size component. - * - * The un-modified game size, as requested in the game config (the raw width / height), - * as used for world bounds, cameras, etc - * - * @name Phaser.Scale.ScaleManager#gameSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.gameSize = new Size(); - - /** - * The Base Size component. - * - * The modified game size, which is the auto-rounded gameSize, used to set the canvas width and height - * (but not the CSS style) - * - * @name Phaser.Scale.ScaleManager#baseSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.baseSize = new Size(); - - /** - * The Display Size component. - * - * The size used for the canvas style, factoring in the scale mode, parent and other values. - * - * @name Phaser.Scale.ScaleManager#displaySize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.displaySize = new Size(); - - /** - * The game scale mode. - * - * @name Phaser.Scale.ScaleManager#scaleMode - * @type {Phaser.Scale.ScaleModeType} - * @since 3.16.0 - */ - this.scaleMode = CONST.SCALE_MODE.NONE; - - /** - * The game zoom factor. - * - * This value allows you to multiply your games base size by the given zoom factor. - * This is then used when calculating the display size, even in `NONE` situations. - * If you don't want Phaser to touch the canvas style at all, this value should be 1. - * - * Can also be set to `MAX_ZOOM` in which case the zoom value will be derived based - * on the game size and available space within the parent. - * - * @name Phaser.Scale.ScaleManager#zoom - * @type {number} - * @since 3.16.0 - */ - this.zoom = 1; - - /** - * Internal flag set when the game zoom factor is modified. - * - * @name Phaser.Scale.ScaleManager#_resetZoom - * @type {boolean} - * @readonly - * @since 3.19.0 - */ - this._resetZoom = false; - - /** - * The scale factor between the baseSize and the canvasBounds. - * - * @name Phaser.Scale.ScaleManager#displayScale - * @type {Phaser.Math.Vector2} - * @since 3.16.0 - */ - this.displayScale = new Vector2(1, 1); - - /** - * If set, the canvas sizes will be automatically passed through Math.floor. - * This results in rounded pixel display values, which is important for performance on legacy - * and low powered devices, but at the cost of not achieving a 'perfect' fit in some browser windows. - * - * @name Phaser.Scale.ScaleManager#autoRound - * @type {boolean} - * @since 3.16.0 - */ - this.autoRound = false; - - /** - * Automatically center the canvas within the parent? The different centering modes are: - * - * 1. No centering. - * 2. Center both horizontally and vertically. - * 3. Center horizontally. - * 4. Center vertically. - * - * Please be aware that in order to center the game canvas, you must have specified a parent - * that has a size set, or the canvas parent is the document.body. - * - * @name Phaser.Scale.ScaleManager#autoCenter - * @type {Phaser.Scale.CenterType} - * @since 3.16.0 - */ - this.autoCenter = CONST.CENTER.NO_CENTER; - - /** - * The current device orientation. - * - * Orientation events are dispatched via the Device Orientation API, typically only on mobile browsers. - * - * @name Phaser.Scale.ScaleManager#orientation - * @type {Phaser.Scale.OrientationType} - * @since 3.16.0 - */ - this.orientation = CONST.ORIENTATION.LANDSCAPE; - - /** - * A reference to the Device.Fullscreen object. - * - * @name Phaser.Scale.ScaleManager#fullscreen - * @type {Phaser.Device.Fullscreen} - * @since 3.16.0 - */ - this.fullscreen; - - /** - * The DOM Element which is sent into fullscreen mode. - * - * @name Phaser.Scale.ScaleManager#fullscreenTarget - * @type {?any} - * @since 3.16.0 - */ - this.fullscreenTarget = null; - - /** - * Did Phaser create the fullscreen target div, or was it provided in the game config? - * - * @name Phaser.Scale.ScaleManager#_createdFullscreenTarget - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._createdFullscreenTarget = false; - - /** - * The dirty state of the Scale Manager. - * Set if there is a change between the parent size and the current size. - * - * @name Phaser.Scale.ScaleManager#dirty - * @type {boolean} - * @since 3.16.0 - */ - this.dirty = false; - - /** - * How many milliseconds should elapse before checking if the browser size has changed? - * - * Most modern browsers dispatch a 'resize' event, which the Scale Manager will listen for. - * However, older browsers fail to do this, or do it consistently, so we fall back to a - * more traditional 'size check' based on a time interval. You can control how often it is - * checked here. - * - * @name Phaser.Scale.ScaleManager#resizeInterval - * @type {number} - * @since 3.16.0 - */ - this.resizeInterval = 500; - - /** - * Internal size interval tracker. - * - * @name Phaser.Scale.ScaleManager#_lastCheck - * @type {number} - * @private - * @since 3.16.0 - */ - this._lastCheck = 0; - - /** - * Internal flag to check orientation state. - * - * @name Phaser.Scale.ScaleManager#_checkOrientation - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._checkOrientation = false; - - /** - * Internal object containing our defined event listeners. - * - * @name Phaser.Scale.ScaleManager#listeners - * @type {object} - * @private - * @since 3.16.0 - */ - this.listeners = { - - orientationChange: NOOP, - windowResize: NOOP, - fullScreenChange: NOOP, - fullScreenError: NOOP - - }; - }, - - /** - * Called _before_ the canvas object is created and added to the DOM. - * - * @method Phaser.Scale.ScaleManager#preBoot - * @protected - * @listens Phaser.Core.Events#BOOT - * @since 3.16.0 - */ - preBoot: function () - { - // Parse the config to get the scaling values we need - this.parseConfig(this.game.config); - - this.game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot handler is called by Phaser.Game when it first starts up. - * The renderer is available by now and the canvas has been added to the DOM. - * - * @method Phaser.Scale.ScaleManager#boot - * @protected - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - */ - boot: function () - { - var game = this.game; - - this.canvas = game.canvas; - - this.fullscreen = game.device.fullscreen; - - if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) - { - this.displaySize.setAspectMode(this.scaleMode); - } - - if (this.scaleMode === CONST.SCALE_MODE.NONE) - { - this.resize(this.width, this.height); - } - else - { - this.getParentBounds(); - - // Only set the parent bounds if the parent has an actual size - if (this.parentSize.width > 0 && this.parentSize.height > 0) - { - this.displaySize.setParent(this.parentSize); - } - - this.refresh(); - } - - game.events.on(GameEvents.PRE_STEP, this.step, this); - game.events.once(GameEvents.READY, this.refresh, this); - game.events.once(GameEvents.DESTROY, this.destroy, this); - - this.startListeners(); - }, - - /** - * Parses the game configuration to set-up the scale defaults. - * - * @method Phaser.Scale.ScaleManager#parseConfig - * @protected - * @since 3.16.0 - * - * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. - */ - parseConfig: function (config) - { - // Get the parent element, if any - this.getParent(config); - - // Get the size of the parent element - // This can often set a height of zero (especially for un-styled divs) - this.getParentBounds(); - - var width = config.width; - var height = config.height; - var scaleMode = config.scaleMode; - var zoom = config.zoom; - var autoRound = config.autoRound; - - // If width = '100%', or similar value - if (typeof width === 'string') - { - // If we have a parent with a height, we'll work it out from that - var parentWidth = this.parentSize.width; - - if (parentWidth === 0) - { - parentWidth = window.innerWidth; - } - - var parentScaleX = parseInt(width, 10) / 100; - - width = Math.floor(parentWidth * parentScaleX); - } - - // If height = '100%', or similar value - if (typeof height === 'string') - { - // If we have a parent with a height, we'll work it out from that - var parentHeight = this.parentSize.height; - - if (parentHeight === 0) - { - parentHeight = window.innerHeight; - } - - var parentScaleY = parseInt(height, 10) / 100; - - height = Math.floor(parentHeight * parentScaleY); - } - - this.scaleMode = scaleMode; - - this.autoRound = autoRound; - - this.autoCenter = config.autoCenter; - - this.resizeInterval = config.resizeInterval; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.setSize(width, height); - - if (zoom === CONST.ZOOM.MAX_ZOOM) - { - zoom = this.getMaxZoom(); - } - - this.zoom = zoom; - - if (zoom !== 1) - { - this._resetZoom = true; - } - - // The modified game size - this.baseSize.setSize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - if (config.minWidth > 0) - { - this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom); - } - - if (config.maxWidth > 0) - { - this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) - this.displaySize.setSize(width, height); - - this.orientation = GetScreenOrientation(width, height); - }, - - /** - * Determines the parent element of the game canvas, if any, based on the game configuration. - * - * @method Phaser.Scale.ScaleManager#getParent - * @since 3.16.0 - * - * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. - */ - getParent: function (config) - { - var parent = config.parent; - - if (parent === null) - { - // User is responsible for managing the parent - return; - } - - this.parent = GetTarget(parent); - this.parentIsWindow = (this.parent === document.body); - - if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) - { - var DOMRect = this.parent.getBoundingClientRect(); - - if (this.parentIsWindow || DOMRect.height === 0) - { - document.documentElement.style.height = '100%'; - document.body.style.height = '100%'; - - DOMRect = this.parent.getBoundingClientRect(); - - // The parent STILL has no height, clearly no CSS - // has been set on it even though we fixed the body :( - if (!this.parentIsWindow && DOMRect.height === 0) - { - this.parent.style.overflow = 'hidden'; - this.parent.style.width = '100%'; - this.parent.style.height = '100%'; - } - } - } - - // And now get the fullscreenTarget - if (config.fullscreenTarget && !this.fullscreenTarget) - { - this.fullscreenTarget = GetTarget(config.fullscreenTarget); - } - }, - - /** - * Calculates the size of the parent bounds and updates the `parentSize` component, if the canvas has a dom parent. - * - * @method Phaser.Scale.ScaleManager#getParentBounds - * @since 3.16.0 - * - * @return {boolean} `true` if the parent bounds have changed size, otherwise `false`. - */ - getParentBounds: function () - { - if (!this.parent) - { - return false; - } - - var parentSize = this.parentSize; - - // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect - - var DOMRect = this.parent.getBoundingClientRect(); - - if (this.parentIsWindow && this.game.device.os.iOS) - { - DOMRect.height = GetInnerHeight(true); - } - - var newWidth = DOMRect.width; - var newHeight = DOMRect.height; - - if (parentSize.width !== newWidth || parentSize.height !== newHeight) - { - parentSize.setSize(newWidth, newHeight); - - return true; - } - else - { - return false; - } - }, - - /** - * Attempts to lock the orientation of the web browser using the Screen Orientation API. - * - * This API is only available on modern mobile browsers. - * See https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation for details. - * - * @method Phaser.Scale.ScaleManager#lockOrientation - * @since 3.16.0 - * - * @param {string} orientation - The orientation you'd like to lock the browser in. Should be an API string such as 'landscape', 'landscape-primary', 'portrait', etc. - * - * @return {boolean} `true` if the orientation was successfully locked, otherwise `false`. - */ - lockOrientation: function (orientation) - { - var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation; - - if (lock) - { - return lock.call(screen, orientation); - } - - return false; - }, - - /** - * This method will set the size of the Parent Size component, which is used in scaling - * and centering calculations. You only need to call this method if you have explicitly - * disabled the use of a parent in your game config, but still wish to take advantage of - * other Scale Manager features. - * - * @method Phaser.Scale.ScaleManager#setParentSize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the parent. - * @param {number} height - The new height of the parent. - * - * @return {this} The Scale Manager instance. - */ - setParentSize: function (width, height) - { - this.parentSize.setSize(width, height); - - return this.refresh(); - }, - - /** - * This method will set a new size for your game. - * - * It should only be used if you're looking to change the base size of your game and are using - * one of the Scale Manager scaling modes, i.e. `FIT`. If you're using `NONE` and wish to - * change the game and canvas size directly, then please use the `resize` method instead. - * - * @method Phaser.Scale.ScaleManager#setGameSize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the game. - * @param {number} height - The new height of the game. - * - * @return {this} The Scale Manager instance. - */ - setGameSize: function (width, height) - { - var autoRound = this.autoRound; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - var previousWidth = this.width; - var previousHeight = this.height; - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.resize(width, height); - - // The modified game size - this.baseSize.resize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // Update the aspect ratio - this.displaySize.setAspectRatio(width / height); - - this.canvas.width = this.baseSize.width; - this.canvas.height = this.baseSize.height; - - return this.refresh(previousWidth, previousHeight); - }, - - /** - * Call this to modify the size of the Phaser canvas element directly. - * You should only use this if you are using the `NONE` scale mode, - * it will update all internal components completely. - * - * If all you want to do is change the size of the parent, see the `setParentSize` method. - * - * If all you want is to change the base size of the game, but still have the Scale Manager - * manage all the scaling (i.e. you're **not** using `NONE`), then see the `setGameSize` method. - * - * This method will set the `gameSize`, `baseSize` and `displaySize` components to the given - * dimensions. It will then resize the canvas width and height to the values given, by - * directly setting the properties. Finally, if you have set the Scale Manager zoom value - * to anything other than 1 (the default), it will set the canvas CSS width and height to - * be the given size multiplied by the zoom factor (the canvas pixel size remains untouched). - * - * If you have enabled `autoCenter`, it is then passed to the `updateCenter` method and - * the margins are set, allowing the canvas to be centered based on its parent element - * alone. Finally, the `displayScale` is adjusted and the RESIZE event dispatched. - * - * @method Phaser.Scale.ScaleManager#resize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the game. - * @param {number} height - The new height of the game. - * - * @return {this} The Scale Manager instance. - */ - resize: function (width, height) - { - var zoom = this.zoom; - var autoRound = this.autoRound; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - var previousWidth = this.width; - var previousHeight = this.height; - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.resize(width, height); - - // The modified game size - this.baseSize.resize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) - this.displaySize.setSize((width * zoom), (height * zoom)); - - this.canvas.width = this.baseSize.width; - this.canvas.height = this.baseSize.height; - - var style = this.canvas.style; - - var styleWidth = width * zoom; - var styleHeight = height * zoom; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - if (styleWidth !== width || styleHeight !== height) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } - - return this.refresh(previousWidth, previousHeight); - }, - - /** - * Sets the zoom value of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#setZoom - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} value - The new zoom value of the game. - * - * @return {this} The Scale Manager instance. - */ - setZoom: function (value) - { - this.zoom = value; - this._resetZoom = true; - - return this.refresh(); - }, - - /** - * Sets the zoom to be the maximum possible based on the _current_ parent size. - * - * @method Phaser.Scale.ScaleManager#setMaxZoom - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @return {this} The Scale Manager instance. - */ - setMaxZoom: function () - { - this.zoom = this.getMaxZoom(); - this._resetZoom = true; - - return this.refresh(); - }, - - /** - * Refreshes the internal scale values, bounds sizes and orientation checks. - * - * Once finished, dispatches the resize event. - * - * This is called automatically by the Scale Manager when the browser window size changes, - * as long as it is using a Scale Mode other than 'NONE'. - * - * @method Phaser.Scale.ScaleManager#refresh - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} [previousWidth] - The previous width of the game. Only set if the gameSize has changed. - * @param {number} [previousHeight] - The previous height of the game. Only set if the gameSize has changed. - * - * @return {this} The Scale Manager instance. - */ - refresh: function (previousWidth, previousHeight) - { - if (previousWidth === undefined) { previousWidth = this.width; } - if (previousHeight === undefined) { previousHeight = this.height; } - - this.updateScale(); - this.updateBounds(); - this.updateOrientation(); - - this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); - - var domContainer = this.game.domContainer; - - if (domContainer) - { - this.baseSize.setCSS(domContainer); - - var canvasStyle = this.canvas.style; - var domStyle = domContainer.style; - - domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; - - domStyle.marginLeft = canvasStyle.marginLeft; - domStyle.marginTop = canvasStyle.marginTop; - } - - this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); - - return this; - }, - - /** - * Internal method that checks the current screen orientation, only if the internal check flag is set. - * - * If the orientation has changed it updates the orientation property and then dispatches the orientation change event. - * - * @method Phaser.Scale.ScaleManager#updateOrientation - * @fires Phaser.Scale.Events#ORIENTATION_CHANGE - * @since 3.16.0 - */ - updateOrientation: function () - { - if (this._checkOrientation) - { - this._checkOrientation = false; - - var newOrientation = GetScreenOrientation(this.width, this.height); - - if (newOrientation !== this.orientation) - { - this.orientation = newOrientation; - - this.emit(Events.ORIENTATION_CHANGE, newOrientation); - } - } - }, - - /** - * Internal method that manages updating the size components based on the scale mode. - * - * @method Phaser.Scale.ScaleManager#updateScale - * @since 3.16.0 - */ - updateScale: function () - { - var style = this.canvas.style; - - var width = this.gameSize.width; - var height = this.gameSize.height; - - var styleWidth; - var styleHeight; - - var zoom = this.zoom; - var autoRound = this.autoRound; - - if (this.scaleMode === CONST.SCALE_MODE.NONE) - { - // No scale - this.displaySize.setSize((width * zoom), (height * zoom)); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - if (this._resetZoom) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - - this._resetZoom = false; - } - } - else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) - { - // Resize to match parent - - // This will constrain using min/max - this.displaySize.setSize(this.parentSize.width, this.parentSize.height); - - this.gameSize.setSize(this.displaySize.width, this.displaySize.height); - - this.baseSize.setSize(this.displaySize.width, this.displaySize.height); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - this.canvas.width = styleWidth; - this.canvas.height = styleHeight; - } - else - { - // All other scale modes - this.displaySize.setSize(this.parentSize.width, this.parentSize.height); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } - - // Update the parentSize in case the canvas / style change modified it - this.getParentBounds(); - - // Finally, update the centering - this.updateCenter(); - }, - - /** - * Calculates and returns the largest possible zoom factor, based on the current - * parent and game sizes. If the parent has no dimensions (i.e. an unstyled div), - * or is smaller than the un-zoomed game, then this will return a value of 1 (no zoom) - * - * @method Phaser.Scale.ScaleManager#getMaxZoom - * @since 3.16.0 - * - * @return {number} The maximum possible zoom factor. At a minimum this value is always at least 1. - */ - getMaxZoom: function () - { - var zoomH = SnapFloor(this.parentSize.width, this.gameSize.width, 0, true); - var zoomV = SnapFloor(this.parentSize.height, this.gameSize.height, 0, true); - - return Math.max(Math.min(zoomH, zoomV), 1); - }, - - /** - * Calculates and updates the canvas CSS style in order to center it within the - * bounds of its parent. If you have explicitly set parent to be `null` in your - * game config then this method will likely give incorrect results unless you have called the - * `setParentSize` method first. - * - * It works by modifying the canvas CSS `marginLeft` and `marginTop` properties. - * - * If they have already been set by your own style sheet, or code, this will overwrite them. - * - * To prevent the Scale Manager from centering the canvas, either do not set the - * `autoCenter` property in your game config, or make sure it is set to `NO_CENTER`. - * - * @method Phaser.Scale.ScaleManager#updateCenter - * @since 3.16.0 - */ - updateCenter: function () - { - var autoCenter = this.autoCenter; - - if (autoCenter === CONST.CENTER.NO_CENTER) - { - return; - } - - var canvas = this.canvas; - - var style = canvas.style; - - var bounds = canvas.getBoundingClientRect(); - - // var width = parseInt(canvas.style.width, 10) || canvas.width; - // var height = parseInt(canvas.style.height, 10) || canvas.height; - - var width = bounds.width; - var height = bounds.height; - - var offsetX = Math.floor((this.parentSize.width - width) / 2); - var offsetY = Math.floor((this.parentSize.height - height) / 2); - - if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) - { - offsetY = 0; - } - else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) - { - offsetX = 0; - } - - style.marginLeft = offsetX + 'px'; - style.marginTop = offsetY + 'px'; - }, - - /** - * Updates the `canvasBounds` rectangle to match the bounding client rectangle of the - * canvas element being used to track input events. - * - * @method Phaser.Scale.ScaleManager#updateBounds - * @since 3.16.0 - */ - updateBounds: function () - { - var bounds = this.canvasBounds; - var clientRect = this.canvas.getBoundingClientRect(); - - bounds.x = clientRect.left + (window.pageXOffset || 0) - (document.documentElement.clientLeft || 0); - bounds.y = clientRect.top + (window.pageYOffset || 0) - (document.documentElement.clientTop || 0); - bounds.width = clientRect.width; - bounds.height = clientRect.height; - }, - - /** - * Transforms the pageX value into the scaled coordinate space of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#transformX - * @since 3.16.0 - * - * @param {number} pageX - The DOM pageX value. - * - * @return {number} The translated value. - */ - transformX: function (pageX) - { - return (pageX - this.canvasBounds.left) * this.displayScale.x; - }, - - /** - * Transforms the pageY value into the scaled coordinate space of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#transformY - * @since 3.16.0 - * - * @param {number} pageY - The DOM pageY value. - * - * @return {number} The translated value. - */ - transformY: function (pageY) - { - return (pageY - this.canvasBounds.top) * this.displayScale.y; - }, - - /** - * Sends a request to the browser to ask it to go in to full screen mode, using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API Fullscreen API}. - * - * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. - * - * This method _must_ be called from a `pointerup` user-input gesture (**not** `pointerdown`). You cannot launch - * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked - * from fullscreen unless the iframe has the `allowfullscreen` attribute. - * - * On touch devices, such as Android and iOS Safari, you should always use `pointerup` and NOT `pointerdown`, - * otherwise the request will fail unless the document in which your game is embedded has already received - * some form of touch input, which you cannot guarantee. Activating fullscreen via `pointerup` circumvents - * this issue. - * - * Performing an action that navigates to another page, or opens another tab, will automatically cancel - * fullscreen mode, as will the user pressing the ESC key. To cancel fullscreen mode directly from your game, - * i.e. by clicking an icon, call the `stopFullscreen` method. - * - * A browser can only send one DOM element into fullscreen. You can control which element this is by - * setting the `fullscreenTarget` property in your game config, or changing the property in the Scale Manager. - * Note that the game canvas _must_ be a child of the target. If you do not give a target, Phaser will - * automatically create a blank `
` element and move the canvas into it, before going fullscreen. - * When it leaves fullscreen, the div will be removed. - * - * @method Phaser.Scale.ScaleManager#startFullscreen - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_FAILED - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. - */ - startFullscreen: function (fullscreenOptions) - { - if (fullscreenOptions === undefined) { fullscreenOptions = { navigationUI: 'hide' }; } - - var fullscreen = this.fullscreen; - - if (!fullscreen.available) - { - this.emit(Events.FULLSCREEN_UNSUPPORTED); - - return; - } - - if (!fullscreen.active) - { - var fsTarget = this.getFullscreenTarget(); - - if (fullscreen.keyboard) - { - fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); - } - else - { - fsTarget[fullscreen.request](fullscreenOptions); - } - } - }, - - /** - * The browser has successfully entered fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#fullscreenSuccessHandler - * @private - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#RESIZE - * @since 3.17.0 - */ - fullscreenSuccessHandler: function () - { - this.getParentBounds(); - - this.refresh(); - - this.emit(Events.ENTER_FULLSCREEN); - }, - - /** - * The browser failed to enter fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#fullscreenErrorHandler - * @private - * @fires Phaser.Scale.Events#FULLSCREEN_FAILED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.17.0 - * - * @param {any} error - The DOM error event. - */ - fullscreenErrorHandler: function (error) - { - this.removeFullscreenTarget(); - - this.emit(Events.FULLSCREEN_FAILED, error); - }, - - /** - * An internal method that gets the target element that is used when entering fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#getFullscreenTarget - * @since 3.16.0 - * - * @return {object} The fullscreen target element. - */ - getFullscreenTarget: function () - { - if (!this.fullscreenTarget) - { - var fsTarget = document.createElement('div'); - - fsTarget.style.margin = '0'; - fsTarget.style.padding = '0'; - fsTarget.style.width = '100%'; - fsTarget.style.height = '100%'; - - this.fullscreenTarget = fsTarget; - - this._createdFullscreenTarget = true; - } - - if (this._createdFullscreenTarget) - { - var canvasParent = this.canvas.parentNode; - - canvasParent.insertBefore(this.fullscreenTarget, this.canvas); - - this.fullscreenTarget.appendChild(this.canvas); - } - - return this.fullscreenTarget; - }, - - /** - * Removes the fullscreen target that was added to the DOM. - * - * @method Phaser.Scale.ScaleManager#removeFullscreenTarget - * @since 3.17.0 - */ - removeFullscreenTarget: function () - { - if (this._createdFullscreenTarget) - { - var fsTarget = this.fullscreenTarget; - - if (fsTarget && fsTarget.parentNode) - { - var parent = fsTarget.parentNode; - - parent.insertBefore(this.canvas, fsTarget); - - parent.removeChild(fsTarget); - } - } - }, - - /** - * Calling this method will cancel fullscreen mode, if the browser has entered it. - * - * @method Phaser.Scale.ScaleManager#stopFullscreen - * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @since 3.16.0 - */ - stopFullscreen: function () - { - var fullscreen = this.fullscreen; - - if (!fullscreen.available) - { - this.emit(Events.FULLSCREEN_UNSUPPORTED); - - return false; - } - - if (fullscreen.active) - { - document[fullscreen.cancel](); - } - - this.removeFullscreenTarget(); - - // Get the parent size again as it will have changed - this.getParentBounds(); - - this.emit(Events.LEAVE_FULLSCREEN); - - this.refresh(); - }, - - /** - * Toggles the fullscreen mode. If already in fullscreen, calling this will cancel it. - * If not in fullscreen, this will request the browser to enter fullscreen mode. - * - * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. - * - * This method _must_ be called from a user-input gesture, such as `pointerdown`. You cannot launch - * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked - * from fullscreen unless the iframe has the `allowfullscreen` attribute. - * - * @method Phaser.Scale.ScaleManager#toggleFullscreen - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. - */ - toggleFullscreen: function (fullscreenOptions) - { - if (this.fullscreen.active) - { - this.stopFullscreen(); - } - else - { - this.startFullscreen(fullscreenOptions); - } - }, - - /** - * An internal method that starts the different DOM event listeners running. - * - * @method Phaser.Scale.ScaleManager#startListeners - * @since 3.16.0 - */ - startListeners: function () - { - var _this = this; - var listeners = this.listeners; - - listeners.orientationChange = function () - { - _this.updateBounds(); - - _this._checkOrientation = true; - _this.dirty = true; - }; - - listeners.windowResize = function () - { - _this.updateBounds(); - - _this.dirty = true; - }; - - // Only dispatched on mobile devices - window.addEventListener('orientationchange', listeners.orientationChange, false); - - window.addEventListener('resize', listeners.windowResize, false); - - if (this.fullscreen.available) - { - listeners.fullScreenChange = function (event) - { - return _this.onFullScreenChange(event); - }; - - listeners.fullScreenError = function (event) - { - return _this.onFullScreenError(event); - }; - - var vendors = [ 'webkit', 'moz', '' ]; - - vendors.forEach(function (prefix) - { - document.addEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.addEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); - - // MS Specific - document.addEventListener('MSFullscreenChange', listeners.fullScreenChange, false); - document.addEventListener('MSFullscreenError', listeners.fullScreenError, false); - } - }, - - /** - * Triggered when a fullscreenchange event is dispatched by the DOM. - * - * @method Phaser.Scale.ScaleManager#onFullScreenChange - * @protected - * @since 3.16.0 - */ - onFullScreenChange: function () - { - if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) - { - this.fullscreenSuccessHandler(); - } - else - { - // They pressed ESC while in fullscreen mode - this.stopFullscreen(); - } - }, - - /** - * Triggered when a fullscreenerror event is dispatched by the DOM. - * - * @method Phaser.Scale.ScaleManager#onFullScreenError - * @since 3.16.0 - */ - onFullScreenError: function () - { - this.removeFullscreenTarget(); - }, - - /** - * Internal method, called automatically by the game step. - * Monitors the elapsed time and resize interval to see if a parent bounds check needs to take place. - * - * @method Phaser.Scale.ScaleManager#step - * @since 3.16.0 - * - * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). - * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. - */ - step: function (time, delta) - { - if (!this.parent) - { - return; - } - - this._lastCheck += delta; - - if (this.dirty || this._lastCheck > this.resizeInterval) - { - // Returns true if the parent bounds have changed size - if (this.getParentBounds()) - { - this.refresh(); - } - - this.dirty = false; - this._lastCheck = 0; - } - }, - - /** - * Stops all DOM event listeners. - * - * @method Phaser.Scale.ScaleManager#stopListeners - * @since 3.16.0 - */ - stopListeners: function () - { - var listeners = this.listeners; - - window.removeEventListener('orientationchange', listeners.orientationChange, false); - window.removeEventListener('resize', listeners.windowResize, false); - - var vendors = [ 'webkit', 'moz', '' ]; - - vendors.forEach(function (prefix) - { - document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); - - // MS Specific - document.removeEventListener('MSFullscreenChange', listeners.fullScreenChange, false); - document.removeEventListener('MSFullscreenError', listeners.fullScreenError, false); - }, - - /** - * Destroys this Scale Manager, releasing all references to external resources. - * Once destroyed, the Scale Manager cannot be used again. - * - * @method Phaser.Scale.ScaleManager#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.stopListeners(); - - this.game = null; - this.canvas = null; - this.canvasBounds = null; - this.parent = null; - this.fullscreenTarget = null; - - this.parentSize.destroy(); - this.gameSize.destroy(); - this.baseSize.destroy(); - this.displaySize.destroy(); - }, - - /** - * Is the browser currently in fullscreen mode or not? - * - * @name Phaser.Scale.ScaleManager#isFullscreen - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isFullscreen: { - - get: function () - { - return this.fullscreen.active; - } - - }, - - /** - * The game width. - * - * This is typically the size given in the game configuration. - * - * @name Phaser.Scale.ScaleManager#width - * @type {number} - * @readonly - * @since 3.16.0 - */ - width: { - - get: function () - { - return this.gameSize.width; - } - - }, - - /** - * The game height. - * - * This is typically the size given in the game configuration. - * - * @name Phaser.Scale.ScaleManager#height - * @type {number} - * @readonly - * @since 3.16.0 - */ - height: { - - get: function () - { - return this.gameSize.height; - } - - }, - - /** - * Is the device in a portrait orientation as reported by the Orientation API? - * This value is usually only available on mobile devices. - * - * @name Phaser.Scale.ScaleManager#isPortrait - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isPortrait: { - - get: function () - { - return (this.orientation === CONST.ORIENTATION.PORTRAIT); - } - - }, - - /** - * Is the device in a landscape orientation as reported by the Orientation API? - * This value is usually only available on mobile devices. - * - * @name Phaser.Scale.ScaleManager#isLandscape - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isLandscape: { - - get: function () - { - return (this.orientation === CONST.ORIENTATION.LANDSCAPE); - } - - }, - - /** - * Are the game dimensions portrait? (i.e. taller than they are wide) - * - * This is different to the device itself being in a portrait orientation. - * - * @name Phaser.Scale.ScaleManager#isGamePortrait - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isGamePortrait: { - - get: function () - { - return (this.height > this.width); - } - - }, - - /** - * Are the game dimensions landscape? (i.e. wider than they are tall) - * - * This is different to the device itself being in a landscape orientation. - * - * @name Phaser.Scale.ScaleManager#isGameLandscape - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isGameLandscape: { - - get: function () - { - return (this.width > this.height); - } - - } - -}); - -module.exports = ScaleManager; - - -/***/ }), -/* 394 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Clamp = __webpack_require__(17); -var Class = __webpack_require__(0); -var SnapFloor = __webpack_require__(76); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * The Size component allows you to set `width` and `height` properties and define the relationship between them. - * - * The component can automatically maintain the aspect ratios between the two values, and clamp them - * to a defined min-max range. You can also control the dominant axis. When dimensions are given to the Size component - * that would cause it to exceed its min-max range, the dimensions are adjusted based on the dominant axis. - * - * @class Size - * @memberof Phaser.Structs - * @constructor - * @since 3.16.0 - * - * @param {number} [width=0] - The width of the Size component. - * @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`. - * @param {number} [aspectMode=0] - The aspect mode of the Size component. Defaults to 0, no mode. - * @param {any} [parent=null] - The parent of this Size component. Can be any object with public `width` and `height` properties. Dimensions are clamped to keep them within the parent bounds where possible. - */ -var Size = new Class({ - - initialize: - - function Size (width, height, aspectMode, parent) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - if (aspectMode === undefined) { aspectMode = 0; } - if (parent === undefined) { parent = null; } - - /** - * Internal width value. - * - * @name Phaser.Structs.Size#_width - * @type {number} - * @private - * @since 3.16.0 - */ - this._width = width; - - /** - * Internal height value. - * - * @name Phaser.Structs.Size#_height - * @type {number} - * @private - * @since 3.16.0 - */ - this._height = height; - - /** - * Internal parent reference. - * - * @name Phaser.Structs.Size#_parent - * @type {any} - * @private - * @since 3.16.0 - */ - this._parent = parent; - - /** - * The aspect mode this Size component will use when calculating its dimensions. - * This property is read-only. To change it use the `setAspectMode` method. - * - * @name Phaser.Structs.Size#aspectMode - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.aspectMode = aspectMode; - - /** - * The proportional relationship between the width and height. - * - * This property is read-only and is updated automatically when either the `width` or `height` properties are changed, - * depending on the aspect mode. - * - * @name Phaser.Structs.Size#aspectRatio - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.aspectRatio = (height === 0) ? 1 : width / height; - - /** - * The minimum allowed width. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. - * - * @name Phaser.Structs.Size#minWidth - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.minWidth = 0; - - /** - * The minimum allowed height. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. - * - * @name Phaser.Structs.Size#minHeight - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.minHeight = 0; - - /** - * The maximum allowed width. - * This value is read-only. To change it see the `setMax` method. - * - * @name Phaser.Structs.Size#maxWidth - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.maxWidth = Number.MAX_VALUE; - - /** - * The maximum allowed height. - * This value is read-only. To change it see the `setMax` method. - * - * @name Phaser.Structs.Size#maxHeight - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.maxHeight = Number.MAX_VALUE; - - /** - * A Vector2 containing the horizontal and vertical snap values, which the width and height are snapped to during resizing. - * - * By default this is disabled. - * - * This property is read-only. To change it see the `setSnap` method. - * - * @name Phaser.Structs.Size#snapTo - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.16.0 - */ - this.snapTo = new Vector2(); - }, - - /** - * Sets the aspect mode of this Size component. - * - * The aspect mode controls what happens when you modify the `width` or `height` properties, or call `setSize`. - * - * It can be a number from 0 to 4, or a Size constant: - * - * 0. NONE = Do not make the size fit the aspect ratio. Change the ratio when the size changes. - * 1. WIDTH_CONTROLS_HEIGHT = The height is automatically adjusted based on the width. - * 2. HEIGHT_CONTROLS_WIDTH = The width is automatically adjusted based on the height. - * 3. FIT = The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. - * 4. ENVELOP = The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. - * - * Calling this method automatically recalculates the `width` and the `height`, if required. - * - * @method Phaser.Structs.Size#setAspectMode - * @since 3.16.0 - * - * @param {number} [value=0] - The aspect mode value. - * - * @return {this} This Size component instance. - */ - setAspectMode: function (value) - { - if (value === undefined) { value = 0; } - - this.aspectMode = value; - - return this.setSize(this._width, this._height); - }, - - /** - * By setting a Snap To value when this Size component is modified its dimensions will automatically - * by snapped to the nearest grid slice, using floor. For example, if you have snap value of 16, - * and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored) - * - * Note that snapping takes place before adjustments by the parent, or the min / max settings. If these - * values are not multiples of the given snap values, then this can result in un-snapped dimensions. - * - * Call this method with no arguments to reset the snap values. - * - * Calling this method automatically recalculates the `width` and the `height`, if required. - * - * @method Phaser.Structs.Size#setSnap - * @since 3.16.0 - * - * @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero. - * @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero. - * - * @return {this} This Size component instance. - */ - setSnap: function (snapWidth, snapHeight) - { - if (snapWidth === undefined) { snapWidth = 0; } - if (snapHeight === undefined) { snapHeight = snapWidth; } - - this.snapTo.set(snapWidth, snapHeight); - - return this.setSize(this._width, this._height); - }, - - /** - * Sets, or clears, the parent of this Size component. - * - * To clear the parent call this method with no arguments. - * - * The parent influences the maximum extents to which this Size component can expand, - * based on the aspect mode: - * - * NONE - The parent clamps both the width and height. - * WIDTH_CONTROLS_HEIGHT - The parent clamps just the width. - * HEIGHT_CONTROLS_WIDTH - The parent clamps just the height. - * FIT - The parent clamps whichever axis is required to ensure the size fits within it. - * ENVELOP - The parent is used to ensure the size fully envelops the parent. - * - * Calling this method automatically calls `setSize`. - * - * @method Phaser.Structs.Size#setParent - * @since 3.16.0 - * - * @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent. - * - * @return {this} This Size component instance. - */ - setParent: function (parent) - { - this._parent = parent; - - return this.setSize(this._width, this._height); - }, - - /** - * Set the minimum width and height values this Size component will allow. - * - * The minimum values can never be below zero, or greater than the maximum values. - * - * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. - * - * Note that based on the aspect mode, and if this Size component has a parent set or not, the minimums set here - * _can_ be exceed in some situations. - * - * @method Phaser.Structs.Size#setMin - * @since 3.16.0 - * - * @param {number} [width=0] - The minimum allowed width of the Size component. - * @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setMin: function (width, height) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - - this.minWidth = Clamp(width, 0, this.maxWidth); - this.minHeight = Clamp(height, 0, this.maxHeight); - - return this.setSize(this._width, this._height); - }, - - /** - * Set the maximum width and height values this Size component will allow. - * - * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. - * - * Note that based on the aspect mode, and if this Size component has a parent set or not, the maximums set here - * _can_ be exceed in some situations. - * - * @method Phaser.Structs.Size#setMax - * @since 3.16.0 - * - * @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component. - * @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setMax: function (width, height) - { - if (width === undefined) { width = Number.MAX_VALUE; } - if (height === undefined) { height = width; } - - this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); - this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); - - return this.setSize(this._width, this._height); - }, - - /** - * Sets the width and height of this Size component based on the aspect mode. - * - * If the aspect mode is 'none' then calling this method will change the aspect ratio, otherwise the current - * aspect ratio is honored across all other modes. - * - * If snapTo values have been set then the given width and height are snapped first, prior to any further - * adjustment via min/max values, or a parent. - * - * If minimum and/or maximum dimensions have been specified, the values given to this method will be clamped into - * that range prior to adjustment, but may still exceed them depending on the aspect mode. - * - * If this Size component has a parent set, and the aspect mode is `fit` or `envelop`, then the given sizes will - * be clamped to the range specified by the parent. - * - * @method Phaser.Structs.Size#setSize - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setSize: function (width, height) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - - switch (this.aspectMode) - { - case Size.NONE: - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; - break; - - case Size.WIDTH_CONTROLS_HEIGHT: - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(this._width * (1 / this.aspectRatio), false); - break; - - case Size.HEIGHT_CONTROLS_WIDTH: - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this._width = this.getNewWidth(this._height * this.aspectRatio, false); - break; - - case Size.FIT: - this.constrain(width, height, true); - break; - - case Size.ENVELOP: - this.constrain(width, height, false); - break; - } - - return this; - }, - - /** - * Sets a new aspect ratio, overriding what was there previously. - * - * It then calls `setSize` immediately using the current dimensions. - * - * @method Phaser.Structs.Size#setAspectRatio - * @since 3.16.0 - * - * @param {number} ratio - The new aspect ratio. - * - * @return {this} This Size component instance. - */ - setAspectRatio: function (ratio) - { - this.aspectRatio = ratio; - - return this.setSize(this._width, this._height); - }, - - /** - * Sets a new width and height for this Size component and updates the aspect ratio based on them. - * - * It _doesn't_ change the `aspectMode` and still factors in size limits such as the min max and parent bounds. - * - * @method Phaser.Structs.Size#resize - * @since 3.16.0 - * - * @param {number} width - The new width of the Size component. - * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - resize: function (width, height) - { - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; - - return this; - }, - - /** - * Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width. - * - * @method Phaser.Structs.Size#getNewWidth - * @since 3.16.0 - * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. - * - * @return {number} The modified width value. - */ - getNewWidth: function (value, checkParent) - { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minWidth, this.maxWidth); - - if (checkParent && this._parent && value > this._parent.width) - { - value = Math.max(this.minWidth, this._parent.width); - } - - return value; - }, - - /** - * Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height. - * - * @method Phaser.Structs.Size#getNewHeight - * @since 3.16.0 - * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. - * - * @return {number} The modified height value. - */ - getNewHeight: function (value, checkParent) - { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minHeight, this.maxHeight); - - if (checkParent && this._parent && value > this._parent.height) - { - value = Math.max(this.minHeight, this._parent.height); - } - - return value; - }, - - /** - * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. - * - * If `fit` is true there may be some space inside the target area which is not covered if its aspect ratio differs. - * If `fit` is false the size may extend further out than the target area if the aspect ratios differ. - * - * If this Size component has a parent set, then the width and height passed to this method will be clamped so - * it cannot exceed that of the parent. - * - * @method Phaser.Structs.Size#constrain - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * @param {boolean} [fit=true] - Perform a `fit` (true) constraint, or an `envelop` (false) constraint. - * - * @return {this} This Size component instance. - */ - constrain: function (width, height, fit) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - if (fit === undefined) { fit = true; } - - width = this.getNewWidth(width); - height = this.getNewHeight(height); - - var snap = this.snapTo; - var newRatio = (height === 0) ? 1 : width / height; - - if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) - { - // We need to change the height to fit the width - - width = SnapFloor(width, snap.x); - - height = width / this.aspectRatio; - - if (snap.y > 0) - { - height = SnapFloor(height, snap.y); - - // Reduce the width accordingly - width = height * this.aspectRatio; - } - } - else if ((fit && this.aspectRatio < newRatio) || (!fit && this.aspectRatio > newRatio)) - { - // We need to change the width to fit the height - - height = SnapFloor(height, snap.y); - - width = height * this.aspectRatio; - - if (snap.x > 0) - { - width = SnapFloor(width, snap.x); - - // Reduce the height accordingly - height = width * (1 / this.aspectRatio); - } - } - - this._width = width; - this._height = height; - - return this; - }, - - /** - * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. - * - * There may be some space inside the target area which is not covered if its aspect ratio differs. - * - * If this Size component has a parent set, then the width and height passed to this method will be clamped so - * it cannot exceed that of the parent. - * - * @method Phaser.Structs.Size#fitTo - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * - * @return {this} This Size component instance. - */ - fitTo: function (width, height) - { - return this.constrain(width, height, true); - }, - - /** - * The current `width` and `height` are adjusted so that they fully envelope the given dimensions, while keeping the aspect ratio. - * - * The size may extend further out than the target area if the aspect ratios differ. - * - * If this Size component has a parent set, then the values are clamped so that it never exceeds the parent - * on the longest axis. - * - * @method Phaser.Structs.Size#envelop - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * - * @return {this} This Size component instance. - */ - envelop: function (width, height) - { - return this.constrain(width, height, false); - }, - - /** - * Sets the width of this Size component. - * - * Depending on the aspect mode, changing the width may also update the height and aspect ratio. - * - * @method Phaser.Structs.Size#setWidth - * @since 3.16.0 - * - * @param {number} width - The new width of the Size component. - * - * @return {this} This Size component instance. - */ - setWidth: function (value) - { - return this.setSize(value, this._height); - }, - - /** - * Sets the height of this Size component. - * - * Depending on the aspect mode, changing the height may also update the width and aspect ratio. - * - * @method Phaser.Structs.Size#setHeight - * @since 3.16.0 - * - * @param {number} height - The new height of the Size component. - * - * @return {this} This Size component instance. - */ - setHeight: function (value) - { - return this.setSize(this._width, value); - }, - - /** - * Returns a string representation of this Size component. - * - * @method Phaser.Structs.Size#toString - * @since 3.16.0 - * - * @return {string} A string representation of this Size component. - */ - toString: function () - { - return '[{ Size (width=' + this._width + ' height=' + this._height + ' aspectRatio=' + this.aspectRatio + ' aspectMode=' + this.aspectMode + ') }]'; - }, - - /** - * Sets the values of this Size component to the `element.style.width` and `height` - * properties of the given DOM Element. The properties are set as `px` values. - * - * @method Phaser.Structs.Size#setCSS - * @since 3.17.0 - * - * @param {HTMLElement} element - The DOM Element to set the CSS style on. - */ - setCSS: function (element) - { - if (element && element.style) - { - element.style.width = this._width + 'px'; - element.style.height = this._height + 'px'; - } - }, - - /** - * Copies the aspect mode, aspect ratio, width and height from this Size component - * to the given Size component. Note that the parent, if set, is not copied across. - * - * @method Phaser.Structs.Size#copy - * @since 3.16.0 - * - * @param {Phaser.Structs.Size} destination - The Size component to copy the values to. - * - * @return {Phaser.Structs.Size} The updated destination Size component. - */ - copy: function (destination) - { - destination.setAspectMode(this.aspectMode); - - destination.aspectRatio = this.aspectRatio; - - return destination.setSize(this.width, this.height); - }, - - /** - * Destroys this Size component. - * - * This clears the local properties and any parent object, if set. - * - * A destroyed Size component cannot be re-used. - * - * @method Phaser.Structs.Size#destroy - * @since 3.16.0 - */ - destroy: function () - { - this._parent = null; - this.snapTo = null; - }, - - /** - * The width of this Size component. - * - * This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled. - * - * A width can never be less than zero. - * - * Changing this value will automatically update the `height` if the aspect ratio lock is enabled. - * You can also use the `setWidth` and `getWidth` methods. - * - * @name Phaser.Structs.Size#width - * @type {number} - * @since 3.16.0 - */ - width: { - - get: function () - { - return this._width; - }, - - set: function (value) - { - this.setSize(value, this._height); - } - - }, - - /** - * The height of this Size component. - * - * This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled. - * - * A height can never be less than zero. - * - * Changing this value will automatically update the `width` if the aspect ratio lock is enabled. - * You can also use the `setHeight` and `getHeight` methods. - * - * @name Phaser.Structs.Size#height - * @type {number} - * @since 3.16.0 - */ - height: { - - get: function () - { - return this._height; - }, - - set: function (value) - { - this.setSize(this._width, value); - } - - } - -}); - -/** - * Do not make the size fit the aspect ratio. Change the ratio when the size changes. - * - * @name Phaser.Structs.Size.NONE - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.NONE = 0; - -/** - * The height is automatically adjusted based on the width. - * - * @name Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.WIDTH_CONTROLS_HEIGHT = 1; - -/** - * The width is automatically adjusted based on the height. - * - * @name Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.HEIGHT_CONTROLS_WIDTH = 2; - -/** - * The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. - * - * @name Phaser.Structs.Size.FIT - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.FIT = 3; - -/** - * The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. - * - * @name Phaser.Structs.Size.ENVELOP - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.ENVELOP = 4; - -module.exports = Size; - - -/***/ }), -/* 395 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(141); -var Events = __webpack_require__(21); -var GameEvents = __webpack_require__(22); -var GetValue = __webpack_require__(6); -var LoaderEvents = __webpack_require__(90); -var NOOP = __webpack_require__(1); -var Scene = __webpack_require__(396); -var Systems = __webpack_require__(199); - -/** - * @classdesc - * The Scene Manager. - * - * The Scene Manager is a Game level system, responsible for creating, processing and updating all of the - * Scenes in a Game instance. -ó * - * - * @class SceneManager - * @memberof Phaser.Scenes - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance this Scene Manager belongs to. - * @param {object} sceneConfig - Scene specific configuration settings. - */ -var SceneManager = new Class({ - - initialize: - - function SceneManager (game, sceneConfig) - { - /** - * The Game that this SceneManager belongs to. - * - * @name Phaser.Scenes.SceneManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * An object that maps the keys to the scene so we can quickly get a scene from a key without iteration. - * - * @name Phaser.Scenes.SceneManager#keys - * @type {object} - * @since 3.0.0 - */ - this.keys = {}; - - /** - * The array in which all of the scenes are kept. - * - * @name Phaser.Scenes.SceneManager#scenes - * @type {array} - * @since 3.0.0 - */ - this.scenes = []; - - /** - * Scenes pending to be added are stored in here until the manager has time to add it. - * - * @name Phaser.Scenes.SceneManager#_pending - * @type {array} - * @private - * @since 3.0.0 - */ - this._pending = []; - - /** - * An array of scenes waiting to be started once the game has booted. - * - * @name Phaser.Scenes.SceneManager#_start - * @type {array} - * @private - * @since 3.0.0 - */ - this._start = []; - - /** - * An operations queue, because we don't manipulate the scenes array during processing. - * - * @name Phaser.Scenes.SceneManager#_queue - * @type {array} - * @private - * @since 3.0.0 - */ - this._queue = []; - - /** - * Boot time data to merge. - * - * @name Phaser.Scenes.SceneManager#_data - * @type {object} - * @private - * @since 3.4.0 - */ - this._data = {}; - - /** - * Is the Scene Manager actively processing the Scenes list? - * - * @name Phaser.Scenes.SceneManager#isProcessing - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.isProcessing = false; - - /** - * Has the Scene Manager properly started? - * - * @name Phaser.Scenes.SceneManager#isBooted - * @type {boolean} - * @default false - * @readonly - * @since 3.4.0 - */ - this.isBooted = false; - - /** - * Do any of the Cameras in any of the Scenes require a custom viewport? - * If not we can skip scissor tests. - * - * @name Phaser.Scenes.SceneManager#customViewports - * @type {number} - * @default 0 - * @since 3.12.0 - */ - this.customViewports = 0; - - if (sceneConfig) - { - if (!Array.isArray(sceneConfig)) - { - sceneConfig = [ sceneConfig ]; - } - - for (var i = 0; i < sceneConfig.length; i++) - { - // The i === 0 part just autostarts the first Scene given (unless it says otherwise in its config) - this._pending.push({ - key: 'default', - scene: sceneConfig[i], - autoStart: (i === 0), - data: {} - }); - } - } - - game.events.once(GameEvents.READY, this.bootQueue, this); - }, - - /** - * Internal first-time Scene boot handler. - * - * @method Phaser.Scenes.SceneManager#bootQueue - * @private - * @since 3.2.0 - */ - bootQueue: function () - { - if (this.isBooted) - { - return; - } - - var i; - var entry; - var key; - var sceneConfig; - - for (i = 0; i < this._pending.length; i++) - { - entry = this._pending[i]; - - key = entry.key; - sceneConfig = entry.scene; - - var newScene; - - if (sceneConfig instanceof Scene) - { - newScene = this.createSceneFromInstance(key, sceneConfig); - } - else if (typeof sceneConfig === 'object') - { - newScene = this.createSceneFromObject(key, sceneConfig); - } - else if (typeof sceneConfig === 'function') - { - newScene = this.createSceneFromFunction(key, sceneConfig); - } - - // Replace key in case the scene changed it - key = newScene.sys.settings.key; - - this.keys[key] = newScene; - - this.scenes.push(newScene); - - // Any data to inject? - if (this._data[key]) - { - newScene.sys.settings.data = this._data[key].data; - - if (this._data[key].autoStart) - { - entry.autoStart = true; - } - } - - if (entry.autoStart || newScene.sys.settings.active) - { - this._start.push(key); - } - } - - // Clear the pending lists - this._pending.length = 0; - - this._data = {}; - - this.isBooted = true; - - // _start might have been populated by the above - for (i = 0; i < this._start.length; i++) - { - entry = this._start[i]; - - this.start(entry); - } - - this._start.length = 0; - }, - - /** - * Process the Scene operations queue. - * - * @method Phaser.Scenes.SceneManager#processQueue - * @since 3.0.0 - */ - processQueue: function () - { - var pendingLength = this._pending.length; - var queueLength = this._queue.length; - - if (pendingLength === 0 && queueLength === 0) - { - return; - } - - var i; - var entry; - - if (pendingLength) - { - for (i = 0; i < pendingLength; i++) - { - entry = this._pending[i]; - - this.add(entry.key, entry.scene, entry.autoStart, entry.data); - } - - // _start might have been populated by this.add - for (i = 0; i < this._start.length; i++) - { - entry = this._start[i]; - - this.start(entry); - } - - // Clear the pending lists - this._start.length = 0; - this._pending.length = 0; - - return; - } - - for (i = 0; i < this._queue.length; i++) - { - entry = this._queue[i]; - - this[entry.op](entry.keyA, entry.keyB); - } - - this._queue.length = 0; - }, - - /** - * Adds a new Scene into the SceneManager. - * You must give each Scene a unique key by which you'll identify it. - * - * The `sceneConfig` can be: - * - * * A `Phaser.Scene` object, or an object that extends it. - * * A plain JavaScript object - * * A JavaScript ES6 Class that extends `Phaser.Scene` - * * A JavaScript ES5 prototype based Class - * * A JavaScript function - * - * If a function is given then a new Scene will be created by calling it. - * - * @method Phaser.Scenes.SceneManager#add - * @since 3.0.0 - * - * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. - * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig|function)} sceneConfig - The config for the Scene - * @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added. - * @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. - * - * @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`. - */ - add: function (key, sceneConfig, autoStart, data) - { - if (autoStart === undefined) { autoStart = false; } - if (data === undefined) { data = {}; } - - // If processing or not booted then put scene into a holding pattern - if (this.isProcessing || !this.isBooted) - { - this._pending.push({ - key: key, - scene: sceneConfig, - autoStart: autoStart, - data: data - }); - - if (!this.isBooted) - { - this._data[key] = { data: data }; - } - - return null; - } - - key = this.getKey(key, sceneConfig); - - var newScene; - - if (sceneConfig instanceof Scene) - { - newScene = this.createSceneFromInstance(key, sceneConfig); - } - else if (typeof sceneConfig === 'object') - { - sceneConfig.key = key; - - newScene = this.createSceneFromObject(key, sceneConfig); - } - else if (typeof sceneConfig === 'function') - { - newScene = this.createSceneFromFunction(key, sceneConfig); - } - - // Any data to inject? - newScene.sys.settings.data = data; - - // Replace key in case the scene changed it - key = newScene.sys.settings.key; - - this.keys[key] = newScene; - - this.scenes.push(newScene); - - if (autoStart || newScene.sys.settings.active) - { - if (this._pending.length) - { - this._start.push(key); - } - else - { - this.start(key); - } - } - - return newScene; - }, - - /** - * Removes a Scene from the SceneManager. - * - * The Scene is removed from the local scenes array, it's key is cleared from the keys - * cache and Scene.Systems.destroy is then called on it. - * - * If the SceneManager is processing the Scenes when this method is called it will - * queue the operation for the next update sequence. - * - * @method Phaser.Scenes.SceneManager#remove - * @since 3.2.0 - * - * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - remove: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'remove', keyA: key, keyB: null }); - } - else - { - var sceneToRemove = this.getScene(key); - - if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) - { - return this; - } - - var index = this.scenes.indexOf(sceneToRemove); - var sceneKey = sceneToRemove.sys.settings.key; - - if (index > -1) - { - delete this.keys[sceneKey]; - this.scenes.splice(index, 1); - - if (this._start.indexOf(sceneKey) > -1) - { - index = this._start.indexOf(sceneKey); - this._start.splice(index, 1); - } - - sceneToRemove.sys.destroy(); - } - } - - return this; - }, - - /** - * Boot the given Scene. - * - * @method Phaser.Scenes.SceneManager#bootScene - * @private - * @fires Phaser.Scenes.Events#TRANSITION_INIT - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to boot. - */ - bootScene: function (scene) - { - var sys = scene.sys; - var settings = sys.settings; - - sys.sceneUpdate = NOOP; - - if (scene.init) - { - scene.init.call(scene, settings.data); - - settings.status = CONST.INIT; - - if (settings.isTransition) - { - sys.events.emit(Events.TRANSITION_INIT, settings.transitionFrom, settings.transitionDuration); - } - } - - var loader; - - if (sys.load) - { - loader = sys.load; - - loader.reset(); - } - - if (loader && scene.preload) - { - scene.preload.call(scene); - - // Is the loader empty? - if (loader.list.size === 0) - { - this.create(scene); - } - else - { - settings.status = CONST.LOADING; - - // Start the loader going as we have something in the queue - loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); - - loader.start(); - } - } - else - { - // No preload? Then there was nothing to load either - this.create(scene); - } - }, - - /** - * Handles load completion for a Scene's Loader. - * - * Starts the Scene that the Loader belongs to. - * - * @method Phaser.Scenes.SceneManager#loadComplete - * @private - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading. - */ - loadComplete: function (loader) - { - var scene = loader.scene; - - // TODO - Remove. This should *not* be handled here - // Try to unlock HTML5 sounds every time any loader completes - if (this.game.sound && this.game.sound.onBlurPausedSounds) - { - this.game.sound.unlock(); - } - - this.create(scene); - }, - - /** - * Handle payload completion for a Scene. - * - * @method Phaser.Scenes.SceneManager#payloadComplete - * @private - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading its Scene's payload. - */ - payloadComplete: function (loader) - { - this.bootScene(loader.scene); - }, - - /** - * Updates the Scenes. - * - * @method Phaser.Scenes.SceneManager#update - * @since 3.0.0 - * - * @param {number} time - Time elapsed. - * @param {number} delta - Delta time from the last update. - */ - update: function (time, delta) - { - this.processQueue(); - - this.isProcessing = true; - - // Loop through the active scenes in reverse order - for (var i = this.scenes.length - 1; i >= 0; i--) - { - var sys = this.scenes[i].sys; - - if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) - { - sys.step(time, delta); - } - } - }, - - /** - * Renders the Scenes. - * - * @method Phaser.Scenes.SceneManager#render - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer to use. - */ - render: function (renderer) - { - // Loop through the scenes in forward order - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) - { - sys.render(renderer); - } - } - - this.isProcessing = false; - }, - - /** - * Calls the given Scene's {@link Phaser.Scene#create} method and updates its status. - * - * @method Phaser.Scenes.SceneManager#create - * @private - * @fires Phaser.Scenes.Events#CREATE - * @fires Phaser.Scenes.Events#TRANSITION_INIT - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to create. - */ - create: function (scene) - { - var sys = scene.sys; - var settings = sys.settings; - - if (scene.create) - { - settings.status = CONST.CREATING; - - scene.create.call(scene, settings.data); - - if (settings.status === CONST.DESTROYED) - { - return; - } - } - - if (settings.isTransition) - { - sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration); - } - - // If the Scene has an update function we'll set it now, otherwise it'll remain as NOOP - if (scene.update) - { - sys.sceneUpdate = scene.update; - } - - settings.status = CONST.RUNNING; - - sys.events.emit(Events.CREATE, scene); - }, - - /** - * Creates and initializes a Scene from a function. - * - * @method Phaser.Scenes.SceneManager#createSceneFromFunction - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {function} scene - The function to create the Scene from. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromFunction: function (key, scene) - { - var newScene = new scene(); - - if (newScene instanceof Scene) - { - var configKey = newScene.sys.settings.key; - - if (configKey !== '') - { - key = configKey; - } - - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } - - return this.createSceneFromInstance(key, newScene); - } - else - { - newScene.sys = new Systems(newScene); - - newScene.sys.settings.key = key; - - newScene.sys.init(this.game); - - return newScene; - } - }, - - /** - * Creates and initializes a Scene instance. - * - * @method Phaser.Scenes.SceneManager#createSceneFromInstance - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {Phaser.Scene} newScene - The Scene instance. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromInstance: function (key, newScene) - { - var configKey = newScene.sys.settings.key; - - if (configKey === '') - { - newScene.sys.settings.key = key; - } - - newScene.sys.init(this.game); - - return newScene; - }, - - /** - * Creates and initializes a Scene from an Object definition. - * - * @method Phaser.Scenes.SceneManager#createSceneFromObject - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {(string|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig)} sceneConfig - The Scene config. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromObject: function (key, sceneConfig) - { - var newScene = new Scene(sceneConfig); - - var configKey = newScene.sys.settings.key; - - if (configKey !== '') - { - key = configKey; - } - else - { - newScene.sys.settings.key = key; - } - - newScene.sys.init(this.game); - - // Extract callbacks - - var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; - - for (var i = 0; i < defaults.length; i++) - { - var sceneCallback = GetValue(sceneConfig, defaults[i], null); - - if (sceneCallback) - { - newScene[defaults[i]] = sceneCallback; - } - } - - // Now let's move across any other functions or properties that may exist in the extend object: - - /* - scene: { - preload: preload, - create: create, - extend: { - hello: 1, - test: 'atari', - addImage: addImage - } - } - */ - - if (sceneConfig.hasOwnProperty('extend')) - { - for (var propertyKey in sceneConfig.extend) - { - if (!sceneConfig.extend.hasOwnProperty(propertyKey)) - { - continue; - } - - var value = sceneConfig.extend[propertyKey]; - - if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') - { - // Populate the DataManager - newScene.data.merge(value); - } - else if (propertyKey !== 'sys') - { - newScene[propertyKey] = value; - } - } - } - - return newScene; - }, - - /** - * Retrieves the key of a Scene from a Scene config. - * - * @method Phaser.Scenes.SceneManager#getKey - * @private - * @since 3.0.0 - * - * @param {string} key - The key to check in the Scene config. - * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|function)} sceneConfig - The Scene config. - * - * @return {string} The Scene key. - */ - getKey: function (key, sceneConfig) - { - if (!key) { key = 'default'; } - - if (typeof sceneConfig === 'function') - { - return key; - } - else if (sceneConfig instanceof Scene) - { - key = sceneConfig.sys.settings.key; - } - else if (typeof sceneConfig === 'object' && sceneConfig.hasOwnProperty('key')) - { - key = sceneConfig.key; - } - - // By this point it's either 'default' or extracted from the Scene - - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } - else - { - return key; - } - }, - - /** - * Returns an array of all the current Scenes being managed by this Scene Manager. - * - * You can filter the output by the active state of the Scene and choose to have - * the array returned in normal or reversed order. - * - * @method Phaser.Scenes.SceneManager#getScenes - * @since 3.16.0 - * - * @param {boolean} [isActive=true] - Only include Scene's that are currently active? - * @param {boolean} [inReverse=false] - Return the array of Scenes in reverse? - * - * @return {Phaser.Scene[]} An array containing all of the Scenes in the Scene Manager. - */ - getScenes: function (isActive, inReverse) - { - if (isActive === undefined) { isActive = true; } - if (inReverse === undefined) { inReverse = false; } - - var out = []; - var scenes = this.scenes; - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene && (!isActive || (isActive && scene.sys.isActive()))) - { - out.push(scene); - } - } - - return (inReverse) ? out.reverse() : out; - }, - - /** - * Retrieves a Scene. - * - * @method Phaser.Scenes.SceneManager#getScene - * @since 3.0.0 - * - * @param {string|Phaser.Scene} key - The Scene to retrieve. - * - * @return {?Phaser.Scene} The Scene. - */ - getScene: function (key) - { - if (typeof key === 'string') - { - if (this.keys[key]) - { - return this.keys[key]; - } - } - else - { - for (var i = 0; i < this.scenes.length; i++) - { - if (key === this.scenes[i]) - { - return key; - } - } - } - - return null; - }, - - /** - * Determines whether a Scene is running. - * - * @method Phaser.Scenes.SceneManager#isActive - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is running. - */ - isActive: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isActive(); - } - - return null; - }, - - /** - * Determines whether a Scene is paused. - * - * @method Phaser.Scenes.SceneManager#isPaused - * @since 3.17.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is paused. - */ - isPaused: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isPaused(); - } - - return null; - }, - - /** - * Determines whether a Scene is visible. - * - * @method Phaser.Scenes.SceneManager#isVisible - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is visible. - */ - isVisible: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isVisible(); - } - - return null; - }, - - /** - * Determines whether a Scene is sleeping. - * - * @method Phaser.Scenes.SceneManager#isSleeping - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is sleeping. - */ - isSleeping: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isSleeping(); - } - - return null; - }, - - /** - * Pauses the given Scene. - * - * @method Phaser.Scenes.SceneManager#pause - * @since 3.0.0 - * - * @param {string} key - The Scene to pause. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its pause event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - pause: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.pause(data); - } - - return this; - }, - - /** - * Resumes the given Scene. - * - * @method Phaser.Scenes.SceneManager#resume - * @since 3.0.0 - * - * @param {string} key - The Scene to resume. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its resume event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - resume: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.resume(data); - } - - return this; - }, - - /** - * Puts the given Scene to sleep. - * - * @method Phaser.Scenes.SceneManager#sleep - * @since 3.0.0 - * - * @param {string} key - The Scene to put to sleep. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its sleep event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - sleep: function (key, data) - { - var scene = this.getScene(key); - - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.sleep(data); - } - - return this; - }, - - /** - * Awakens the given Scene. - * - * @method Phaser.Scenes.SceneManager#wake - * @since 3.0.0 - * - * @param {string} key - The Scene to wake up. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its wake event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - wake: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.wake(data); - } - - return this; - }, - - /** - * Runs the given Scene. - * - * If the given Scene is paused, it will resume it. If sleeping, it will wake it. - * If not running at all, it will be started. - * - * Use this if you wish to open a modal Scene by calling `pause` on the current - * Scene, then `run` on the modal Scene. - * - * @method Phaser.Scenes.SceneManager#run - * @since 3.10.0 - * - * @param {string} key - The Scene to run. - * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. - * - * @return {Phaser.Scenes.SceneManager} This Scene Manager. - */ - run: function (key, data) - { - var scene = this.getScene(key); - - if (!scene) - { - for (var i = 0; i < this._pending.length; i++) - { - if (this._pending[i].key === key) - { - this.queueOp('start', key, data); - break; - } - } - return this; - } - - if (scene.sys.isSleeping()) - { - // Sleeping? - scene.sys.wake(data); - } - else if (scene.sys.isPaused()) - { - // Paused? - scene.sys.resume(data); - } - else - { - // Not actually running? - this.start(key, data); - } - }, - - /** - * Starts the given Scene. - * - * @method Phaser.Scenes.SceneManager#start - * @since 3.0.0 - * - * @param {string} key - The Scene to start. - * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - start: function (key, data) - { - // If the Scene Manager is not running, then put the Scene into a holding pattern - if (!this.isBooted) - { - this._data[key] = { - autoStart: true, - data: data - }; - - return this; - } - - var scene = this.getScene(key); - - if (scene) - { - var sys = scene.sys; - - // If the Scene is already running (perhaps they called start from a launched sub-Scene?) - // then we close it down before starting it again. - if (sys.isActive() || sys.isPaused()) - { - sys.shutdown(); - - sys.sceneUpdate = NOOP; - - sys.start(data); - } - else - { - sys.sceneUpdate = NOOP; - - sys.start(data); - - var loader; - - if (sys.load) - { - loader = sys.load; - } - - // Files payload? - if (loader && sys.settings.hasOwnProperty('pack')) - { - loader.reset(); - - if (loader.addPack({ payload: sys.settings.pack })) - { - sys.settings.status = CONST.LOADING; - - loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); - - loader.start(); - - return this; - } - } - } - - this.bootScene(scene); - } - - return this; - }, - - /** - * Stops the given Scene. - * - * @method Phaser.Scenes.SceneManager#stop - * @since 3.0.0 - * - * @param {string} key - The Scene to stop. - * @param {object} [data] - Optional data object to pass to Scene.shutdown. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - stop: function (key, data) - { - var scene = this.getScene(key); - - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.shutdown(data); - } - - return this; - }, - - /** - * Sleeps one one Scene and starts the other. - * - * @method Phaser.Scenes.SceneManager#switch - * @since 3.0.0 - * - * @param {string} from - The Scene to sleep. - * @param {string} to - The Scene to start. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - switch: function (from, to) - { - var sceneA = this.getScene(from); - var sceneB = this.getScene(to); - - if (sceneA && sceneB && sceneA !== sceneB) - { - this.sleep(from); - - if (this.isSleeping(to)) - { - this.wake(to); - } - else - { - this.start(to); - } - } - - return this; - }, - - /** - * Retrieves a Scene by numeric index. - * - * @method Phaser.Scenes.SceneManager#getAt - * @since 3.0.0 - * - * @param {number} index - The index of the Scene to retrieve. - * - * @return {(Phaser.Scene|undefined)} The Scene. - */ - getAt: function (index) - { - return this.scenes[index]; - }, - - /** - * Retrieves the numeric index of a Scene. - * - * @method Phaser.Scenes.SceneManager#getIndex - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The key of the Scene. - * - * @return {number} The index of the Scene. - */ - getIndex: function (key) - { - var scene = this.getScene(key); - - return this.scenes.indexOf(scene); - }, - - /** - * Brings a Scene to the top of the Scenes list. - * - * This means it will render above all other Scenes. - * - * @method Phaser.Scenes.SceneManager#bringToTop - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - bringToTop: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'bringToTop', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); - - if (index !== -1 && index < this.scenes.length) - { - var scene = this.getScene(key); - - this.scenes.splice(index, 1); - this.scenes.push(scene); - } - } - - return this; - }, - - /** - * Sends a Scene to the back of the Scenes list. - * - * This means it will render below all other Scenes. - * - * @method Phaser.Scenes.SceneManager#sendToBack - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - sendToBack: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); - - if (index !== -1 && index > 0) - { - var scene = this.getScene(key); - - this.scenes.splice(index, 1); - this.scenes.unshift(scene); - } - } - - return this; - }, - - /** - * Moves a Scene down one position in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#moveDown - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveDown: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'moveDown', keyA: key, keyB: null }); - } - else - { - var indexA = this.getIndex(key); - - if (indexA > 0) - { - var indexB = indexA - 1; - var sceneA = this.getScene(key); - var sceneB = this.getAt(indexB); - - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } - - return this; - }, - - /** - * Moves a Scene up one position in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#moveUp - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveUp: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); - } - else - { - var indexA = this.getIndex(key); - - if (indexA < this.scenes.length - 1) - { - var indexB = indexA + 1; - var sceneA = this.getScene(key); - var sceneB = this.getAt(indexB); - - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } - - return this; - }, - - /** - * Moves a Scene so it is immediately above another Scene in the Scenes list. - * - * This means it will render over the top of the other Scene. - * - * @method Phaser.Scenes.SceneManager#moveAbove - * @since 3.2.0 - * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. - * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveAbove: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); - - // Remove - this.scenes.splice(indexB, 1); - - // Add in new location - this.scenes.splice(indexA + 1, 0, tempScene); - } - } - - return this; - }, - - /** - * Moves a Scene so it is immediately below another Scene in the Scenes list. - * - * This means it will render behind the other Scene. - * - * @method Phaser.Scenes.SceneManager#moveBelow - * @since 3.2.0 - * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. - * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveBelow: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'moveBelow', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); - - // Remove - this.scenes.splice(indexB, 1); - - if (indexA === 0) - { - this.scenes.unshift(tempScene); - } - else - { - // Add in new location - this.scenes.splice(indexA, 0, tempScene); - } - } - } - - return this; - }, - - /** - * Queue a Scene operation for the next update. - * - * @method Phaser.Scenes.SceneManager#queueOp - * @private - * @since 3.0.0 - * - * @param {string} op - The operation to perform. - * @param {(string|Phaser.Scene)} keyA - Scene A. - * @param {(any|string|Phaser.Scene)} [keyB] - Scene B, or a data object. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - queueOp: function (op, keyA, keyB) - { - this._queue.push({ op: op, keyA: keyA, keyB: keyB }); - - return this; - }, - - /** - * Swaps the positions of two Scenes in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#swapPosition - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. - * @param {(string|Phaser.Scene)} keyB - The second Scene to swap. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - swapPosition: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'swapPosition', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== indexB && indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexA); - - this.scenes[indexA] = this.scenes[indexB]; - this.scenes[indexB] = tempScene; - } - } - - return this; - }, - - /** - * Dumps debug information about each Scene to the developer console. - * - * @method Phaser.Scenes.SceneManager#dump - * @since 3.2.0 - */ - dump: function () - { - var out = []; - var map = [ 'pending', 'init', 'start', 'loading', 'creating', 'running', 'paused', 'sleeping', 'shutdown', 'destroyed' ]; - - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - var key = (sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED)) ? '[*] ' : '[-] '; - key += sys.settings.key + ' (' + map[sys.settings.status] + ')'; - - out.push(key); - } - - console.log(out.join('\n')); - }, - - /** - * Destroy the SceneManager and all of its Scene's systems. - * - * @method Phaser.Scenes.SceneManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - sys.destroy(); - } - - this.update = NOOP; - - this.scenes = []; - - this._pending = []; - this._start = []; - this._queue = []; - - this.game = null; - } - -}); - -module.exports = SceneManager; - - -/***/ }), -/* 396 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Systems = __webpack_require__(199); - -/** - * @classdesc - * A base Phaser.Scene class which can be extended for your own use. - * - * You can also define the optional methods {@link Phaser.Types.Scenes.SceneInitCallback init()}, {@link Phaser.Types.Scenes.ScenePreloadCallback preload()}, and {@link Phaser.Types.Scenes.SceneCreateCallback create()}. - * - * @class Scene - * @memberof Phaser - * @constructor - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. - */ -var Scene = new Class({ - - initialize: - - function Scene (config) - { - /** - * The Scene Systems. You must never overwrite this property, or all hell will break lose. - * - * @name Phaser.Scene#sys - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.sys = new Systems(this, config); - - /** - * A reference to the Phaser.Game instance. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game; - - /** - * A reference to the global Animation Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#anims - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 - */ - this.anims; - - /** - * A reference to the global Cache. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#cache - * @type {Phaser.Cache.CacheManager} - * @since 3.0.0 - */ - this.cache; - - /** - * A reference to the game level Data Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#registry - * @type {Phaser.Data.DataManager} - * @since 3.0.0 - */ - this.registry; - - /** - * A reference to the Sound Manager. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#sound - * @type {Phaser.Sound.BaseSoundManager} - * @since 3.0.0 - */ - this.sound; - - /** - * A reference to the Texture Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#textures - * @type {Phaser.Textures.TextureManager} - * @since 3.0.0 - */ - this.textures; - - /** - * A scene level Event Emitter. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events; - - /** - * A scene level Camera System. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#cameras - * @type {Phaser.Cameras.Scene2D.CameraManager} - * @since 3.0.0 - */ - this.cameras; - - /** - * A scene level Game Object Factory. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#add - * @type {Phaser.GameObjects.GameObjectFactory} - * @since 3.0.0 - */ - this.add; - - /** - * A scene level Game Object Creator. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#make - * @type {Phaser.GameObjects.GameObjectCreator} - * @since 3.0.0 - */ - this.make; - - /** - * A reference to the Scene Manager Plugin. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#scene - * @type {Phaser.Scenes.ScenePlugin} - * @since 3.0.0 - */ - this.scene; - - /** - * A scene level Game Object Display List. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#children - * @type {Phaser.GameObjects.DisplayList} - * @since 3.0.0 - */ - this.children; - - /** - * A scene level Lights Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#lights - * @type {Phaser.GameObjects.LightsManager} - * @since 3.0.0 - */ - this.lights; - - /** - * A scene level Data Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#data - * @type {Phaser.Data.DataManager} - * @since 3.0.0 - */ - this.data; - - /** - * A scene level Input Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#input - * @type {Phaser.Input.InputPlugin} - * @since 3.0.0 - */ - this.input; - - /** - * A scene level Loader Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#load - * @type {Phaser.Loader.LoaderPlugin} - * @since 3.0.0 - */ - this.load; - - /** - * A scene level Time and Clock Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#time - * @type {Phaser.Time.Clock} - * @since 3.0.0 - */ - this.time; - - /** - * A scene level Tween Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#tweens - * @type {Phaser.Tweens.TweenManager} - * @since 3.0.0 - */ - this.tweens; - - /** - * A scene level Arcade Physics Plugin. - * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. - * - * @name Phaser.Scene#physics - * @type {Phaser.Physics.Arcade.ArcadePhysics} - * @since 3.0.0 - */ - this.physics; - - /** - * A scene level Matter Physics Plugin. - * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. - * - * @name Phaser.Scene#matter - * @type {Phaser.Physics.Matter.MatterPhysics} - * @since 3.0.0 - */ - this.matter; - - if (false) - {} - - /** - * A reference to the global Scale Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#scale - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.2 - */ - this.scale; - - /** - * A reference to the Plugin Manager. - * - * The Plugin Manager is a global system that allows plugins to register themselves with it, and can then install - * those plugins into Scenes as required. - * - * @name Phaser.Scene#plugins - * @type {Phaser.Plugins.PluginManager} - * @since 3.0.0 - */ - this.plugins; - - /** - * A reference to the renderer instance Phaser is using, either Canvas or WebGL. - * - * @name Phaser.Scene#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.50.0 - */ - this.renderer; - }, - - /** - * Should be overridden by your own Scenes. - * This method is called once per game step while the scene is running. - * - * @method Phaser.Scene#update - * @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. - */ - update: function () - { - } - -}); - -module.exports = Scene; - - -/***/ }), -/* 397 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var UppercaseFirst = __webpack_require__(200); - -/** - * Builds an array of which physics plugins should be activated for the given Scene. - * - * @function Phaser.Scenes.GetPhysicsPlugins - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - The scene system to get the physics systems of. - * - * @return {array} An array of Physics systems to start for this Scene. - */ -var GetPhysicsPlugins = function (sys) -{ - var defaultSystem = sys.game.config.defaultPhysicsSystem; - var sceneSystems = GetFastValue(sys.settings, 'physics', false); - - if (!defaultSystem && !sceneSystems) - { - // No default physics system or systems in this scene - return; - } - - // Let's build the systems array - var output = []; - - if (defaultSystem) - { - output.push(UppercaseFirst(defaultSystem + 'Physics')); - } - - if (sceneSystems) - { - for (var key in sceneSystems) - { - key = UppercaseFirst(key.concat('Physics')); - - if (output.indexOf(key) === -1) - { - output.push(key); - } - } - } - - // An array of Physics systems to start for this Scene - return output; -}; - -module.exports = GetPhysicsPlugins; - - -/***/ }), -/* 398 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); - -/** - * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. - * - * @function Phaser.Scenes.GetScenePlugins - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems object to check for plugins. - * - * @return {array} An array of all plugins which should be activated, either the default ones or the ones configured in the Scene Systems object. - */ -var GetScenePlugins = function (sys) -{ - var defaultPlugins = sys.plugins.getDefaultScenePlugins(); - - var scenePlugins = GetFastValue(sys.settings, 'plugins', false); - - // Scene Plugins always override Default Plugins - if (Array.isArray(scenePlugins)) - { - return scenePlugins; - } - else if (defaultPlugins) - { - return defaultPlugins; - } - else - { - // No default plugins or plugins in this scene - return []; - } -}; - -module.exports = GetScenePlugins; - - -/***/ }), -/* 399 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(141); -var GetValue = __webpack_require__(6); -var Merge = __webpack_require__(142); -var InjectionMap = __webpack_require__(974); - -/** - * @namespace Phaser.Scenes.Settings - */ - -var Settings = { - - /** - * Takes a Scene configuration object and returns a fully formed System Settings object. - * - * @function Phaser.Scenes.Settings.create - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - The Scene configuration object used to create this Scene Settings. - * - * @return {Phaser.Types.Scenes.SettingsObject} The Scene Settings object created as a result of the config and default settings. - */ - create: function (config) - { - if (typeof config === 'string') - { - config = { key: config }; - } - else if (config === undefined) - { - // Pass the 'hasOwnProperty' checks - config = {}; - } - - return { - - status: CONST.PENDING, - - key: GetValue(config, 'key', ''), - active: GetValue(config, 'active', false), - visible: GetValue(config, 'visible', true), - - isBooted: false, - - isTransition: false, - transitionFrom: null, - transitionDuration: 0, - transitionAllowInput: true, - - // Loader payload array - - data: {}, - - pack: GetValue(config, 'pack', false), - - // Cameras - - cameras: GetValue(config, 'cameras', null), - - // Scene Property Injection Map - - map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), - - // Physics - - physics: GetValue(config, 'physics', {}), - - // Loader - - loader: GetValue(config, 'loader', {}), - - // Plugins - - plugins: GetValue(config, 'plugins', false), - - // Input - - input: GetValue(config, 'input', {}) - - }; - } - -}; - -module.exports = Settings; - - -/***/ }), -/* 400 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); -var CanvasTexture = __webpack_require__(401); -var Class = __webpack_require__(0); -var Color = __webpack_require__(35); -var CONST = __webpack_require__(39); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(103); -var GameEvents = __webpack_require__(22); -var GenerateTexture = __webpack_require__(366); -var GetValue = __webpack_require__(6); -var Parser = __webpack_require__(403); -var Texture = __webpack_require__(201); - -/** - * @callback EachTextureCallback - * - * @param {Phaser.Textures.Texture} texture - Each texture in Texture Manager. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. - */ - -/** - * @classdesc - * Textures are managed by the global TextureManager. This is a singleton class that is - * responsible for creating and delivering Textures and their corresponding Frames to Game Objects. - * - * Sprites and other Game Objects get the texture data they need from the TextureManager. - * - * Access it via `scene.textures`. - * - * @class TextureManager - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Textures - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. - */ -var TextureManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function TextureManager (game) - { - EventEmitter.call(this); - - /** - * The Game that this TextureManager belongs to. - * - * @name Phaser.Textures.TextureManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * The name of this manager. - * - * @name Phaser.Textures.TextureManager#name - * @type {string} - * @since 3.0.0 - */ - this.name = 'TextureManager'; - - /** - * An object that has all of textures that Texture Manager creates. - * Textures are assigned to keys so we can access to any texture that this object has directly by key value without iteration. - * - * @name Phaser.Textures.TextureManager#list - * @type {object} - * @default {} - * @since 3.0.0 - */ - this.list = {}; - - /** - * The temporary canvas element to save an pixel data of an arbitrary texture in getPixel() and getPixelAlpha() method. - * - * @name Phaser.Textures.TextureManager#_tempCanvas - * @type {HTMLCanvasElement} - * @private - * @since 3.0.0 - */ - this._tempCanvas = CanvasPool.create2D(this, 1, 1); - - /** - * The context of the temporary canvas element made to save an pixel data in getPixel() and getPixelAlpha() method. - * - * @name Phaser.Textures.TextureManager#_tempContext - * @type {CanvasRenderingContext2D} - * @private - * @since 3.0.0 - */ - this._tempContext = this._tempCanvas.getContext('2d'); - - /** - * An counting value used for emitting 'ready' event after all of managers in game is loaded. - * - * @name Phaser.Textures.TextureManager#_pending - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._pending = 0; - - game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot Handler called by Phaser.Game when it first starts up. - * - * @method Phaser.Textures.TextureManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - this.on(Events.LOAD, this.updatePending, this); - this.on(Events.ERROR, this.updatePending, this); - - var config = this.game.config; - - this.addBase64('__DEFAULT', config.defaultImage); - this.addBase64('__MISSING', config.missingImage); - this.addBase64('__WHITE', config.whiteImage); - - this._pending = 3; - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * After 'onload' or 'onerror' invoked twice, emit 'ready' event. - * - * @method Phaser.Textures.TextureManager#updatePending - * @private - * @since 3.0.0 - */ - updatePending: function () - { - this._pending--; - - if (this._pending === 0) - { - this.off(Events.LOAD); - this.off(Events.ERROR); - - this.emit(Events.READY); - } - }, - - /** - * Checks the given texture key and throws a console.warn if the key is already in use, then returns false. - * If you wish to avoid the console.warn then use `TextureManager.exists` instead. - * - * @method Phaser.Textures.TextureManager#checkKey - * @since 3.7.0 - * - * @param {string} key - The texture key to check. - * - * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. - */ - checkKey: function (key) - { - if (this.exists(key)) - { - // eslint-disable-next-line no-console - console.error('Texture key already in use: ' + key); - - return false; - } - - return true; - }, - - /** - * Removes a Texture from the Texture Manager and destroys it. This will immediately - * clear all references to it from the Texture Manager, and if it has one, destroy its - * WebGLTexture. This will emit a `removetexture` event. - * - * Note: If you have any Game Objects still using this texture they will start throwing - * errors the next time they try to render. Make sure that removing the texture is the final - * step when clearing down to avoid this. - * - * @method Phaser.Textures.TextureManager#remove - * @fires Phaser.Textures.Events#REMOVE - * @since 3.7.0 - * - * @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it. - * - * @return {Phaser.Textures.TextureManager} The Texture Manager. - */ - remove: function (key) - { - if (typeof key === 'string') - { - if (this.exists(key)) - { - key = this.get(key); - } - else - { - console.warn('No texture found matching key: ' + key); - return this; - } - } - - // By this point key should be a Texture, if not, the following fails anyway - if (this.list.hasOwnProperty(key.key)) - { - key.destroy(); - - this.emit(Events.REMOVE, key.key); - } - - return this; - }, - - /** - * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. - * - * @method Phaser.Textures.TextureManager#removeKey - * @since 3.17.0 - * - * @param {string} key - The key to remove from the texture list. - * - * @return {Phaser.Textures.TextureManager} The Texture Manager. - */ - removeKey: function (key) - { - if (this.list.hasOwnProperty(key)) - { - delete this.list[key]; - } - - return this; - }, - - /** - * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. - * - * It works by creating an `Image` DOM object, then setting the `src` attribute to - * the given base64 encoded data. As a result, the process is asynchronous by its nature, - * so be sure to listen for the events this method dispatches before using the texture. - * - * @method Phaser.Textures.TextureManager#addBase64 - * @fires Phaser.Textures.Events#ADD - * @fires Phaser.Textures.Events#ERROR - * @fires Phaser.Textures.Events#LOAD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {*} data - The Base64 encoded data. - * - * @return {this} This Texture Manager instance. - */ - addBase64: function (key, data) - { - if (this.checkKey(key)) - { - var _this = this; - - var image = new Image(); - - image.onerror = function () - { - _this.emit(Events.ERROR, key); - }; - - image.onload = function () - { - var texture = _this.create(key, image); - - Parser.Image(texture, 0); - - _this.emit(Events.ADD, key, texture); - - _this.emit(Events.LOAD, key, texture); - }; - - image.src = data; - } - - return this; - }, - - /** - * Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data. - * - * You can also provide the image type and encoder options. - * - * This will only work with bitmap based texture frames, such as those created from Texture Atlases. - * It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please - * see the WebGL Snapshot function instead. - * - * @method Phaser.Textures.TextureManager#getBase64 - * @since 3.12.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png. - * @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored. - * - * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. - */ - getBase64: function (key, frame, type, encoderOptions) - { - if (type === undefined) { type = 'image/png'; } - if (encoderOptions === undefined) { encoderOptions = 0.92; } - - var data = ''; - - var textureFrame = this.getFrame(key, frame); - - if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) - { - console.warn('Cannot getBase64 from WebGL Texture'); - } - else if (textureFrame) - { - var cd = textureFrame.canvasData; - - var canvas = CanvasPool.create2D(this, cd.width, cd.height); - var ctx = canvas.getContext('2d'); - - ctx.drawImage( - textureFrame.source.image, - cd.x, - cd.y, - cd.width, - cd.height, - 0, - 0, - cd.width, - cd.height - ); - - data = canvas.toDataURL(type, encoderOptions); - - CanvasPool.remove(canvas); - } - - return data; - }, - - /** - * Adds a new Texture to the Texture Manager created from the given Image element. - * - * @method Phaser.Textures.TextureManager#addImage - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addImage: function (key, source, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.Image(texture, 0); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Takes a WebGL Texture and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. - * - * This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites. - * - * If the `width` and `height` arguments are omitted, but the WebGL Texture was created by Phaser's WebGL Renderer - * and has `glTexture.width` and `glTexture.height` properties, these values will be used instead. - * - * This is a WebGL only feature. - * - * @method Phaser.Textures.TextureManager#addGLTexture - * @fires Phaser.Textures.Events#ADD - * @since 3.19.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {WebGLTexture} glTexture - The source Render Texture. - * @param {number} [width] - The new width of the Texture. Read from `glTexture.width` if omitted. - * @param {number} [height] - The new height of the Texture. Read from `glTexture.height` if omitted. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addGLTexture: function (key, glTexture, width, height) - { - var texture = null; - - if (this.checkKey(key)) - { - if (width === undefined) { width = glTexture.width; } - if (height === undefined) { height = glTexture.height; } - - texture = this.create(key, glTexture, width, height); - - texture.add('__BASE', 0, 0, 0, width, height); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Render Texture to the Texture Manager using the given key. - * This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites. - * - * @method Phaser.Textures.TextureManager#addRenderTexture - * @fires Phaser.Textures.Events#ADD - * @since 3.12.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addRenderTexture: function (key, renderTexture) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, renderTexture); - - texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Creates a new Texture using the given config values. - * - * Generated textures consist of a Canvas element to which the texture data is drawn. - * - * Generates a texture based on the given Create configuration object. - * - * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the - * data cells map to a single color. For example, if the texture config looked like this: - * - * ```javascript - * var star = [ - * '.....828.....', - * '....72227....', - * '....82228....', - * '...7222227...', - * '2222222222222', - * '8222222222228', - * '.72222222227.', - * '..787777787..', - * '..877777778..', - * '.78778887787.', - * '.27887.78872.', - * '.787.....787.' - * ]; - * - * this.textures.generate('star', { data: star, pixelWidth: 4 }); - * ``` - * - * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array - * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color - * number 8 in the palette. If a cell contains a period character `.` then it is transparent. - * - * The default palette is Arne16, but you can specify your own using the `palette` property. - * - * @method Phaser.Textures.TextureManager#generate - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.Types.Create.GenerateTextureConfig} config - The configuration object needed to generate the texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - generate: function (key, config) - { - if (this.checkKey(key)) - { - var canvas = CanvasPool.create(this, 1, 1); - - config.canvas = canvas; - - GenerateTexture(config); - - return this.addCanvas(key, canvas); - } - else - { - return null; - } - }, - - /** - * Creates a new Texture using a blank Canvas element of the size given. - * - * Canvas elements are automatically pooled and calling this method will - * extract a free canvas from the CanvasPool, or create one if none are available. - * - * @method Phaser.Textures.TextureManager#createCanvas - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {number} [width=256] - The width of the Canvas element. - * @param {number} [height=256] - The height of the Canvas element. - * - * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. - */ - createCanvas: function (key, width, height) - { - if (width === undefined) { width = 256; } - if (height === undefined) { height = 256; } - - if (this.checkKey(key)) - { - var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); - - return this.addCanvas(key, canvas); - } - - return null; - }, - - /** - * Creates a new Canvas Texture object from an existing Canvas element - * and adds it to this Texture Manager, unless `skipCache` is true. - * - * @method Phaser.Textures.TextureManager#addCanvas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture. - * @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache? - * - * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. - */ - addCanvas: function (key, source, skipCache) - { - if (skipCache === undefined) { skipCache = false; } - - var texture = null; - - if (skipCache) - { - texture = new CanvasTexture(this, key, source, source.width, source.height); - } - else if (this.checkKey(key)) - { - texture = new CanvasTexture(this, key, source, source.width, source.height); - - this.list[key] = texture; - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a new Texture Atlas to this Texture Manager. - * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. - * - * @method Phaser.Textures.TextureManager#addAtlas - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlas: function (key, source, data, dataSource) - { - // New Texture Packer format? - if (Array.isArray(data.textures) || Array.isArray(data.frames)) - { - return this.addAtlasJSONArray(key, source, data, dataSource); - } - else - { - return this.addAtlasJSONHash(key, source, data, dataSource); - } - }, - - /** - * Adds a Texture Atlas to this Texture Manager. - * The frame data of the atlas must be stored in an Array within the JSON. - * This is known as a JSON Array in software such as Texture Packer. - * - * @method Phaser.Textures.TextureManager#addAtlasJSONArray - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(HTMLImageElement|HTMLImageElement[])} source - The source Image element/s. - * @param {(object|object[])} data - The Texture Atlas data/s. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasJSONArray: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - // Multi-Atlas? - if (Array.isArray(data)) - { - var singleAtlasFile = (data.length === 1); // multi-pack with one atlas file for all images - - // !! Assumes the textures are in the same order in the source array as in the json data !! - for (var i = 0; i < texture.source.length; i++) - { - var atlasData = singleAtlasFile ? data[0] : data[i]; - - Parser.JSONArray(texture, i, atlasData); - } - } - else - { - Parser.JSONArray(texture, 0, data); - } - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Texture Atlas to this Texture Manager. - * The frame data of the atlas must be stored in an Object within the JSON. - * This is known as a JSON Hash in software such as Texture Packer. - * - * @method Phaser.Textures.TextureManager#addAtlasJSONHash - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasJSONHash: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - if (Array.isArray(data)) - { - for (var i = 0; i < data.length; i++) - { - Parser.JSONHash(texture, i, data[i]); - } - } - else - { - Parser.JSONHash(texture, 0, data); - } - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Texture Atlas to this Texture Manager, where the atlas data is given - * in the XML format. - * - * @method Phaser.Textures.TextureManager#addAtlasXML - * @fires Phaser.Textures.Events#ADD - * @since 3.7.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas XML data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasXML: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.AtlasXML(texture, 0, data); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Unity Texture Atlas to this Texture Manager. - * The data must be in the form of a Unity YAML file. - * - * @method Phaser.Textures.TextureManager#addUnityAtlas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addUnityAtlas: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.UnityYAML(texture, 0, data); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Sprite Sheet to this Texture Manager. - * - * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact - * same size and cannot be trimmed or rotated. - * - * @method Phaser.Textures.TextureManager#addSpriteSheet - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addSpriteSheet: function (key, source, config) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - var width = texture.source[0].width; - var height = texture.source[0].height; - - Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. - * - * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact - * same size and cannot be trimmed or rotated. - * - * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addSpriteSheetFromAtlas: function (key, config) - { - if (!this.checkKey(key)) - { - return null; - } - - var atlasKey = GetValue(config, 'atlas', null); - var atlasFrame = GetValue(config, 'frame', null); - - if (!atlasKey || !atlasFrame) - { - return; - } - - var atlas = this.get(atlasKey); - var sheet = atlas.get(atlasFrame); - - if (sheet) - { - var texture = this.create(key, sheet.source.image); - - if (sheet.trimmed) - { - // If trimmed we need to help the parser adjust - Parser.SpriteSheetFromAtlas(texture, sheet, config); - } - else - { - Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); - } - - this.emit(Events.ADD, key, texture); - - return texture; - } - }, - - /** - * Creates a new Texture using the given source and dimensions. - * - * @method Phaser.Textures.TextureManager#create - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {number} width - The width of the Texture. - * @param {number} height - The height of the Texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - create: function (key, source, width, height) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = new Texture(this, key, source, width, height); - - this.list[key] = texture; - } - - return texture; - }, - - /** - * Checks the given key to see if a Texture using it exists within this Texture Manager. - * - * @method Phaser.Textures.TextureManager#exists - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * - * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. - */ - exists: function (key) - { - return (this.list.hasOwnProperty(key)); - }, - - /** - * Returns a Texture from the Texture Manager that matches the given key. - * - * If the key is `undefined` it will return the `__DEFAULT` Texture. - * - * If the key is an instance of a Texture, it will return the key directly. - * - * Finally. if the key is given, but not found and not a Texture instance, it will return the `__MISSING` Texture. - * - * @method Phaser.Textures.TextureManager#get - * @since 3.0.0 - * - * @param {(string|Phaser.Textures.Texture)} key - The unique string-based key of the Texture, or a Texture instance. - * - * @return {Phaser.Textures.Texture} The Texture that was created. - */ - get: function (key) - { - if (key === undefined) { key = '__DEFAULT'; } - - if (this.list[key]) - { - return this.list[key]; - } - else if (key instanceof Texture) - { - return key; - } - else - { - return this.list['__MISSING']; - } - }, - - /** - * Takes a Texture key and Frame name and returns a clone of that Frame if found. - * - * @method Phaser.Textures.TextureManager#cloneFrame - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} frame - The string or index of the Frame to be cloned. - * - * @return {Phaser.Textures.Frame} A Clone of the given Frame. - */ - cloneFrame: function (key, frame) - { - if (this.list[key]) - { - return this.list[key].get(frame).clone(); - } - }, - - /** - * Takes a Texture key and Frame name and returns a reference to that Frame, if found. - * - * @method Phaser.Textures.TextureManager#getFrame - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * - * @return {Phaser.Textures.Frame} A Texture Frame object. - */ - getFrame: function (key, frame) - { - if (this.list[key]) - { - return this.list[key].get(frame); - } - }, - - /** - * Returns an array with all of the keys of all Textures in this Texture Manager. - * The output array will exclude the `__DEFAULT` and `__MISSING` keys. - * - * @method Phaser.Textures.TextureManager#getTextureKeys - * @since 3.0.0 - * - * @return {string[]} An array containing all of the Texture keys stored in this Texture Manager. - */ - getTextureKeys: function () - { - var output = []; - - for (var key in this.list) - { - if (key !== '__DEFAULT' && key !== '__MISSING') - { - output.push(key); - } - } - - return output; - }, - - /** - * Given a Texture and an `x` and `y` coordinate this method will return a new - * Color object that has been populated with the color and alpha values of the pixel - * at that location in the Texture. - * - * @method Phaser.Textures.TextureManager#getPixel - * @since 3.0.0 - * - * @param {number} x - The x coordinate of the pixel within the Texture. - * @param {number} y - The y coordinate of the pixel within the Texture. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {?Phaser.Display.Color} A Color object populated with the color values of the requested pixel, - * or `null` if the coordinates were out of bounds. - */ - getPixel: function (x, y, key, frame) - { - var textureFrame = this.getFrame(key, frame); - - if (textureFrame) - { - // Adjust for trim (if not trimmed x and y are just zero) - x -= textureFrame.x; - y -= textureFrame.y; - - var data = textureFrame.data.cut; - - x += data.x; - y += data.y; - - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; - - ctx.clearRect(0, 0, 1, 1); - ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - - var rgb = ctx.getImageData(0, 0, 1, 1); - - return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); - } - } - - return null; - }, - - /** - * Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255 - * corresponding to the alpha value of the pixel at that location in the Texture. If the coordinate - * is out of bounds it will return null. - * - * @method Phaser.Textures.TextureManager#getPixelAlpha - * @since 3.10.0 - * - * @param {number} x - The x coordinate of the pixel within the Texture. - * @param {number} y - The y coordinate of the pixel within the Texture. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds. - */ - getPixelAlpha: function (x, y, key, frame) - { - var textureFrame = this.getFrame(key, frame); - - if (textureFrame) - { - // Adjust for trim (if not trimmed x and y are just zero) - x -= textureFrame.x; - y -= textureFrame.y; - - var data = textureFrame.data.cut; - - x += data.x; - y += data.y; - - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; - - ctx.clearRect(0, 0, 1, 1); - ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - - var rgb = ctx.getImageData(0, 0, 1, 1); - - return rgb.data[3]; - } - } - - return null; - }, - - /** - * Sets the given Game Objects `texture` and `frame` properties so that it uses - * the Texture and Frame specified in the `key` and `frame` arguments to this method. - * - * @method Phaser.Textures.TextureManager#setTexture - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the texture would be set on. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on. - */ - setTexture: function (gameObject, key, frame) - { - if (this.list[key]) - { - gameObject.texture = this.list[key]; - gameObject.frame = gameObject.texture.get(frame); - } - - return gameObject; - }, - - /** - * Changes the key being used by a Texture to the new key provided. - * - * The old key is removed, allowing it to be re-used. - * - * Game Objects are linked to Textures by a reference to the Texture object, so - * all existing references will be retained. - * - * @method Phaser.Textures.TextureManager#renameTexture - * @since 3.12.0 - * - * @param {string} currentKey - The current string-based key of the Texture you wish to rename. - * @param {string} newKey - The new unique string-based key to use for the Texture. - * - * @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`. - */ - renameTexture: function (currentKey, newKey) - { - var texture = this.get(currentKey); - - if (texture && currentKey !== newKey) - { - texture.key = newKey; - - this.list[newKey] = texture; - - delete this.list[currentKey]; - - return true; - } - - return false; - }, - - /** - * Passes all Textures to the given callback. - * - * @method Phaser.Textures.TextureManager#each - * @since 3.0.0 - * - * @param {EachTextureCallback} callback - The callback function to be sent the Textures. - * @param {object} scope - The value to use as `this` when executing the callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. - */ - each: function (callback, scope) - { - var args = [ null ]; - - for (var i = 1; i < arguments.length; i++) - { - args.push(arguments[i]); - } - - for (var texture in this.list) - { - args[0] = this.list[texture]; - - callback.apply(scope, args); - } - }, - - /** - * Destroys the Texture Manager and all Textures stored within it. - * - * @method Phaser.Textures.TextureManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var texture in this.list) - { - this.list[texture].destroy(); - } - - this.list = {}; - - this.game = null; - - CanvasPool.remove(this._tempCanvas); - } - -}); - -module.exports = TextureManager; - - -/***/ }), -/* 401 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); -var Color = __webpack_require__(35); -var CONST = __webpack_require__(39); -var IsSizePowerOfTwo = __webpack_require__(136); -var Texture = __webpack_require__(201); - -/** - * @classdesc - * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. - * - * You can use the properties of this texture to draw to the canvas element directly, using all of the standard - * canvas operations available in the browser. Any Game Object can be given this texture and will render with it. - * - * Note: When running under WebGL the Canvas Texture needs to re-generate its base WebGLTexture and reupload it to - * the GPU every time you modify it, otherwise the changes you make to this texture will not be visible. To do this - * you should call `CanvasTexture.refresh()` once you are finished with your changes to the canvas. Try and keep - * this to a minimum, especially on large canvas sizes, or you may inadvertently thrash the GPU by constantly uploading - * texture data to it. This restriction does not apply if using the Canvas Renderer. - * - * It starts with only one frame that covers the whole of the canvas. You can add further frames, that specify - * sections of the canvas using the `add` method. - * - * Should you need to resize the canvas use the `setSize` method so that it accurately updates all of the underlying - * texture data as well. Forgetting to do this (i.e. by changing the canvas size directly from your code) could cause - * graphical errors. - * - * @class CanvasTexture - * @extends Phaser.Textures.Texture - * @memberof Phaser.Textures - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Textures.TextureManager} manager - A reference to the Texture Manager this Texture belongs to. - * @param {string} key - The unique string-based key of this Texture. - * @param {HTMLCanvasElement} source - The canvas element that is used as the base of this texture. - * @param {number} width - The width of the canvas. - * @param {number} height - The height of the canvas. - */ -var CanvasTexture = new Class({ - - Extends: Texture, - - initialize: - - function CanvasTexture (manager, key, source, width, height) - { - Texture.call(this, manager, key, source, width, height); - - this.add('__BASE', 0, 0, 0, width, height); - - /** - * A reference to the Texture Source of this Canvas. - * - * @name Phaser.Textures.CanvasTexture#_source - * @type {Phaser.Textures.TextureSource} - * @private - * @since 3.7.0 - */ - this._source = this.frames['__BASE'].source; - - /** - * The source Canvas Element. - * - * @name Phaser.Textures.CanvasTexture#canvas - * @readonly - * @type {HTMLCanvasElement} - * @since 3.7.0 - */ - this.canvas = this._source.image; - - /** - * The 2D Canvas Rendering Context. - * - * @name Phaser.Textures.CanvasTexture#context - * @readonly - * @type {CanvasRenderingContext2D} - * @since 3.7.0 - */ - this.context = this.canvas.getContext('2d'); - - /** - * The width of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. - * - * @name Phaser.Textures.CanvasTexture#width - * @readonly - * @type {number} - * @since 3.7.0 - */ - this.width = width; - - /** - * The height of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. - * - * @name Phaser.Textures.CanvasTexture#height - * @readonly - * @type {number} - * @since 3.7.0 - */ - this.height = height; - - /** - * The context image data. - * Use the `update` method to populate this when the canvas changes. - * - * @name Phaser.Textures.CanvasTexture#imageData - * @type {ImageData} - * @since 3.13.0 - */ - this.imageData = this.context.getImageData(0, 0, width, height); - - /** - * A Uint8ClampedArray view into the `buffer`. - * Use the `update` method to populate this when the canvas changes. - * Note that this is unavailable in some browsers, such as Epic Browser, due to their security restrictions. - * - * @name Phaser.Textures.CanvasTexture#data - * @type {Uint8ClampedArray} - * @since 3.13.0 - */ - this.data = null; - - if (this.imageData) - { - this.data = this.imageData.data; - } - - /** - * An Uint32Array view into the `buffer`. - * - * @name Phaser.Textures.CanvasTexture#pixels - * @type {Uint32Array} - * @since 3.13.0 - */ - this.pixels = null; - - /** - * An ArrayBuffer the same size as the context ImageData. - * - * @name Phaser.Textures.CanvasTexture#buffer - * @type {ArrayBuffer} - * @since 3.13.0 - */ - this.buffer; - - if (this.data) - { - if (this.imageData.data.buffer) - { - this.buffer = this.imageData.data.buffer; - this.pixels = new Uint32Array(this.buffer); - } - else if (window.ArrayBuffer) - { - this.buffer = new ArrayBuffer(this.imageData.data.length); - this.pixels = new Uint32Array(this.buffer); - } - else - { - this.pixels = this.imageData.data; - } - } - }, - - /** - * This re-creates the `imageData` from the current context. - * It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array. - * - * Warning: This is a very expensive operation, so use it sparingly. - * - * @method Phaser.Textures.CanvasTexture#update - * @since 3.13.0 - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - update: function () - { - this.imageData = this.context.getImageData(0, 0, this.width, this.height); - - this.data = this.imageData.data; - - if (this.imageData.data.buffer) - { - this.buffer = this.imageData.data.buffer; - this.pixels = new Uint32Array(this.buffer); - } - else if (window.ArrayBuffer) - { - this.buffer = new ArrayBuffer(this.imageData.data.length); - this.pixels = new Uint32Array(this.buffer); - } - else - { - this.pixels = this.imageData.data; - } - - if (this.manager.game.config.renderType === CONST.WEBGL) - { - this.refresh(); - } - - return this; - }, - - /** - * Draws the given Image or Canvas element to this CanvasTexture, then updates the internal - * ImageData buffer and arrays. - * - * @method Phaser.Textures.CanvasTexture#draw - * @since 3.13.0 - * - * @param {number} x - The x coordinate to draw the source at. - * @param {number} y - The y coordinate to draw the source at. - * @param {(HTMLImageElement|HTMLCanvasElement)} source - The element to draw to this canvas. - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - draw: function (x, y, source) - { - this.context.drawImage(source, x, y); - - return this.update(); - }, - - /** - * Draws the given texture frame to this CanvasTexture, then updates the internal - * ImageData buffer and arrays. - * - * @method Phaser.Textures.CanvasTexture#drawFrame - * @since 3.16.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * @param {number} [x=0] - The x coordinate to draw the source at. - * @param {number} [y=0] - The y coordinate to draw the source at. - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - drawFrame: function (key, frame, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - var textureFrame = this.manager.getFrame(key, frame); - - if (textureFrame) - { - var cd = textureFrame.canvasData; - - var width = textureFrame.cutWidth; - var height = textureFrame.cutHeight; - var res = textureFrame.source.resolution; - - this.context.drawImage( - textureFrame.source.image, - cd.x, cd.y, - width, - height, - x, y, - width / res, - height / res - ); - - return this.update(); - } - else - { - return this; - } - }, - - /** - * Sets a pixel in the CanvasTexture to the given color and alpha values. - * - * This is an expensive operation to run in large quantities, so use sparingly. - * - * @method Phaser.Textures.CanvasTexture#setPixel - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} red - The red color value. A number between 0 and 255. - * @param {number} green - The green color value. A number between 0 and 255. - * @param {number} blue - The blue color value. A number between 0 and 255. - * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. - * - * @return {this} This CanvasTexture. - */ - setPixel: function (x, y, red, green, blue, alpha) - { - if (alpha === undefined) { alpha = 255; } - - x = Math.abs(Math.floor(x)); - y = Math.abs(Math.floor(y)); - - var index = this.getIndex(x, y); - - if (index > -1) - { - var imageData = this.context.getImageData(x, y, 1, 1); - - imageData.data[0] = red; - imageData.data[1] = green; - imageData.data[2] = blue; - imageData.data[3] = alpha; - - this.context.putImageData(imageData, x, y); - } - - return this; - }, - - /** - * Puts the ImageData into the context of this CanvasTexture at the given coordinates. - * - * @method Phaser.Textures.CanvasTexture#putData - * @since 3.16.0 - * - * @param {ImageData} imageData - The ImageData to put at the given location. - * @param {number} x - The x coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [dirtyX=0] - Horizontal position (x coordinate) of the top-left corner from which the image data will be extracted. - * @param {number} [dirtyY=0] - Vertical position (x coordinate) of the top-left corner from which the image data will be extracted. - * @param {number} [dirtyWidth] - Width of the rectangle to be painted. Defaults to the width of the image data. - * @param {number} [dirtyHeight] - Height of the rectangle to be painted. Defaults to the height of the image data. - * - * @return {this} This CanvasTexture. - */ - putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) - { - if (dirtyX === undefined) { dirtyX = 0; } - if (dirtyY === undefined) { dirtyY = 0; } - if (dirtyWidth === undefined) { dirtyWidth = imageData.width; } - if (dirtyHeight === undefined) { dirtyHeight = imageData.height; } - - this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight); - - return this; - }, - - /** - * Gets an ImageData region from this CanvasTexture from the position and size specified. - * You can write this back using `CanvasTexture.putData`, or manipulate it. - * - * @method Phaser.Textures.CanvasTexture#getData - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} width - The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left. - * @param {number} height - The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up. - * - * @return {ImageData} The ImageData extracted from this CanvasTexture. - */ - getData: function (x, y, width, height) - { - x = Clamp(Math.floor(x), 0, this.width - 1); - y = Clamp(Math.floor(y), 0, this.height - 1); - width = Clamp(width, 1, this.width - x); - height = Clamp(height, 1, this.height - y); - - var imageData = this.context.getImageData(x, y, width, height); - - return imageData; - }, - - /** - * Get the color of a specific pixel from this texture and store it in a Color object. - * - * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, - * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. - * - * @method Phaser.Textures.CanvasTexture#getPixel - * @since 3.13.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {Phaser.Display.Color} [out] - A Color object to store the pixel values in. If not provided a new Color object will be created. - * - * @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties. - */ - getPixel: function (x, y, out) - { - if (!out) - { - out = new Color(); - } - - var index = this.getIndex(x, y); - - if (index > -1) - { - var data = this.data; - - var r = data[index + 0]; - var g = data[index + 1]; - var b = data[index + 2]; - var a = data[index + 3]; - - out.setTo(r, g, b, a); - } - - return out; - }, - - /** - * Returns an array containing all of the pixels in the given region. - * - * If the requested region extends outside the bounds of this CanvasTexture, - * the region is truncated to fit. - * - * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, - * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. - * - * @method Phaser.Textures.CanvasTexture#getPixels - * @since 3.16.0 - * - * @param {number} [x=0] - The x coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [y=0] - The y coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [width] - The width of the region to get. Must be an integer. Defaults to the canvas width if not given. - * @param {number} [height] - The height of the region to get. Must be an integer. If not given will be set to the `width`. - * - * @return {Phaser.Types.Textures.PixelConfig[][]} A 2d array of Pixel objects. - */ - getPixels: function (x, y, width, height) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = width; } - - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); - - var left = Clamp(x, 0, this.width); - var right = Clamp(x + width, 0, this.width); - var top = Clamp(y, 0, this.height); - var bottom = Clamp(y + height, 0, this.height); - - var pixel = new Color(); - - var out = []; - - for (var py = top; py < bottom; py++) - { - var row = []; - - for (var px = left; px < right; px++) - { - pixel = this.getPixel(px, py, pixel); - - row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); - } - - out.push(row); - } - - return out; - }, - - /** - * Returns the Image Data index for the given pixel in this CanvasTexture. - * - * The index can be used to read directly from the `this.data` array. - * - * The index points to the red value in the array. The subsequent 3 indexes - * point to green, blue and alpha respectively. - * - * @method Phaser.Textures.CanvasTexture#getIndex - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * - * @return {number} - */ - getIndex: function (x, y) - { - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); - - if (x < this.width && y < this.height) - { - return (x + y * this.width) * 4; - } - else - { - return -1; - } - }, - - /** - * This should be called manually if you are running under WebGL. - * It will refresh the WebGLTexture from the Canvas source. Only call this if you know that the - * canvas has changed, as there is a significant GPU texture allocation cost involved in doing so. - * - * @method Phaser.Textures.CanvasTexture#refresh - * @since 3.7.0 - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - refresh: function () - { - this._source.update(); - - return this; - }, - - /** - * Gets the Canvas Element. - * - * @method Phaser.Textures.CanvasTexture#getCanvas - * @since 3.7.0 - * - * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. - */ - getCanvas: function () - { - return this.canvas; - }, - - /** - * Gets the 2D Canvas Rendering Context. - * - * @method Phaser.Textures.CanvasTexture#getContext - * @since 3.7.0 - * - * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. - */ - getContext: function () - { - return this.context; - }, - - /** - * Clears the given region of this Canvas Texture, resetting it back to transparent. - * If no region is given, the whole Canvas Texture is cleared. - * - * @method Phaser.Textures.CanvasTexture#clear - * @since 3.7.0 - * - * @param {number} [x=0] - The x coordinate of the top-left of the region to clear. - * @param {number} [y=0] - The y coordinate of the top-left of the region to clear. - * @param {number} [width] - The width of the region. - * @param {number} [height] - The height of the region. - * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. - */ - clear: function (x, y, width, height) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } - - this.context.clearRect(x, y, width, height); - - return this.update(); - }, - - /** - * Changes the size of this Canvas Texture. - * - * @method Phaser.Textures.CanvasTexture#setSize - * @since 3.7.0 - * - * @param {number} width - The new width of the Canvas. - * @param {number} [height] - The new height of the Canvas. If not given it will use the width as the height. - * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. - */ - setSize: function (width, height) - { - if (height === undefined) { height = width; } - - if (width !== this.width || height !== this.height) - { - // Update the Canvas - this.canvas.width = width; - this.canvas.height = height; - - // Update the Texture Source - this._source.width = width; - this._source.height = height; - this._source.isPowerOf2 = IsSizePowerOfTwo(width, height); - - // Update the Frame - this.frames['__BASE'].setSize(width, height, 0, 0); - - // Update this - this.width = width; - this.height = height; - - this.refresh(); - } - - return this; - }, - - /** - * Destroys this Texture and releases references to its sources and frames. - * - * @method Phaser.Textures.CanvasTexture#destroy - * @since 3.16.0 - */ - destroy: function () - { - Texture.prototype.destroy.call(this); - - this._source = null; - this.canvas = null; - this.context = null; - this.imageData = null; - this.data = null; - this.pixels = null; - this.buffer = null; - } - -}); - -module.exports = CanvasTexture; - - -/***/ }), -/* 402 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); -var Class = __webpack_require__(0); -var IsSizePowerOfTwo = __webpack_require__(136); -var ScaleModes = __webpack_require__(263); - -/** - * @classdesc - * A Texture Source is the encapsulation of the actual source data for a Texture. - * - * This is typically an Image Element, loaded from the file system or network, a Canvas Element or a Video Element. - * - * A Texture can contain multiple Texture Sources, which only happens when a multi-atlas is loaded. - * - * @class TextureSource - * @memberof Phaser.Textures - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture this TextureSource belongs to. - * @param {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} source - The source image data. - * @param {number} [width] - Optional width of the source image. If not given it's derived from the source itself. - * @param {number} [height] - Optional height of the source image. If not given it's derived from the source itself. - * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. - */ -var TextureSource = new Class({ - - initialize: - - function TextureSource (texture, source, width, height, flipY) - { - if (flipY === undefined) { flipY = false; } - - var game = texture.manager.game; - - /** - * The Texture this TextureSource belongs to. - * - * @name Phaser.Textures.TextureSource#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.7.0 - */ - this.renderer = game.renderer; - - /** - * The Texture this TextureSource belongs to. - * - * @name Phaser.Textures.TextureSource#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 - */ - this.texture = texture; - - /** - * The source of the image data. - * - * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. - * - * @name Phaser.Textures.TextureSource#source - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} - * @since 3.12.0 - */ - this.source = source; - - /** - * The image data. - * - * This is either an Image element, Canvas element or a Video Element. - * - * @name Phaser.Textures.TextureSource#image - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} - * @since 3.0.0 - */ - this.image = source; - - /** - * Currently un-used. - * - * @name Phaser.Textures.TextureSource#compressionAlgorithm - * @type {number} - * @default null - * @since 3.0.0 - */ - this.compressionAlgorithm = null; - - /** - * The resolution of the source image. - * - * @name Phaser.Textures.TextureSource#resolution - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.resolution = 1; - - /** - * The width of the source image. If not specified in the constructor it will check - * the `naturalWidth` and then `width` properties of the source image. - * - * @name Phaser.Textures.TextureSource#width - * @type {number} - * @since 3.0.0 - */ - this.width = width || source.naturalWidth || source.videoWidth || source.width || 0; - - /** - * The height of the source image. If not specified in the constructor it will check - * the `naturalHeight` and then `height` properties of the source image. - * - * @name Phaser.Textures.TextureSource#height - * @type {number} - * @since 3.0.0 - */ - this.height = height || source.naturalHeight || source.videoHeight || source.height || 0; - - /** - * The Scale Mode the image will use when rendering. - * Either Linear or Nearest. - * - * @name Phaser.Textures.TextureSource#scaleMode - * @type {number} - * @since 3.0.0 - */ - this.scaleMode = ScaleModes.DEFAULT; - - /** - * Is the source image a Canvas Element? - * - * @name Phaser.Textures.TextureSource#isCanvas - * @type {boolean} - * @since 3.0.0 - */ - this.isCanvas = (source instanceof HTMLCanvasElement); - - /** - * Is the source image a Video Element? - * - * @name Phaser.Textures.TextureSource#isVideo - * @type {boolean} - * @since 3.20.0 - */ - this.isVideo = (window.hasOwnProperty('HTMLVideoElement') && source instanceof HTMLVideoElement); - - /** - * Is the source image a Render Texture? - * - * @name Phaser.Textures.TextureSource#isRenderTexture - * @type {boolean} - * @since 3.12.0 - */ - this.isRenderTexture = (source.type === 'RenderTexture'); - - /** - * Is the source image a WebGLTexture? - * - * @name Phaser.Textures.TextureSource#isGLTexture - * @type {boolean} - * @since 3.19.0 - */ - this.isGLTexture = (window.hasOwnProperty('WebGLTexture') && source instanceof WebGLTexture); - - /** - * Are the source image dimensions a power of two? - * - * @name Phaser.Textures.TextureSource#isPowerOf2 - * @type {boolean} - * @since 3.0.0 - */ - this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height); - - /** - * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture - * already, then this is a reference to that WebGLTexture. - * - * @name Phaser.Textures.TextureSource#glTexture - * @type {?WebGLTexture} - * @default null - * @since 3.0.0 - */ - this.glTexture = null; - - /** - * The current texture unit index as assigned by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. - * - * @name Phaser.Textures.TextureSource#glIndex - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.glIndex = 0; - - /** - * The counter value when this texture was last assigned an index by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. - * - * @name Phaser.Textures.TextureSource#glIndexCounter - * @type {number} - * @default -1 - * @since 3.50.0 - */ - this.glIndexCounter = -1; - - /** - * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. - * - * @name Phaser.Textures.TextureSource#flipY - * @type {boolean} - * @since 3.20.0 - */ - this.flipY = flipY; - - this.init(game); - }, - - /** - * Creates a WebGL Texture, if required, and sets the Texture filter mode. - * - * @method Phaser.Textures.TextureSource#init - * @since 3.0.0 - * - * @param {Phaser.Game} game - A reference to the Phaser Game instance. - */ - init: function (game) - { - var renderer = this.renderer; - - if (renderer) - { - if (renderer.gl) - { - if (this.isCanvas) - { - this.glTexture = renderer.createCanvasTexture(this.image, false, this.flipY); - } - else if (this.isVideo) - { - this.glTexture = renderer.createVideoTexture(this.image, false, this.flipY); - } - else if (this.isRenderTexture) - { - this.image = this.source.canvas; - - this.glTexture = renderer.createTextureFromSource(null, this.width, this.height, this.scaleMode); - } - else if (this.isGLTexture) - { - this.glTexture = this.source; - } - else - { - this.glTexture = renderer.createTextureFromSource(this.image, this.width, this.height, this.scaleMode); - } - } - else if (this.isRenderTexture) - { - this.image = this.source.canvas; - } - } - - if (!game.config.antialias) - { - this.setFilter(1); - } - }, - - /** - * Sets the Filter Mode for this Texture. - * - * The mode can be either Linear, the default, or Nearest. - * - * For pixel-art you should use Nearest. - * - * @method Phaser.Textures.TextureSource#setFilter - * @since 3.0.0 - * - * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. - */ - setFilter: function (filterMode) - { - if (this.renderer.gl) - { - this.renderer.setTextureFilter(this.glTexture, filterMode); - } - - this.scaleMode = filterMode; - }, - - /** - * Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload. - * - * @method Phaser.Textures.TextureSource#setFlipY - * @since 3.20.0 - * - * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? - */ - setFlipY: function (value) - { - if (value === undefined) { value = true; } - - this.flipY = value; - - return this; - }, - - /** - * If this TextureSource is backed by a Canvas and is running under WebGL, - * it updates the WebGLTexture using the canvas data. - * - * @method Phaser.Textures.TextureSource#update - * @since 3.7.0 - */ - update: function () - { - var gl = this.renderer.gl; - - if (gl && this.isCanvas) - { - this.glTexture = this.renderer.updateCanvasTexture(this.image, this.glTexture, this.flipY); - } - else if (gl && this.isVideo) - { - this.glTexture = this.renderer.updateVideoTexture(this.image, this.glTexture, this.flipY); - } - }, - - /** - * Destroys this Texture Source and nulls the references. - * - * @method Phaser.Textures.TextureSource#destroy - * @since 3.0.0 - */ - destroy: function () - { - if (this.glTexture) - { - this.renderer.deleteTexture(this.glTexture, false); - } - - if (this.isCanvas) - { - CanvasPool.remove(this.image); - } - - this.renderer = null; - this.texture = null; - this.source = null; - this.image = null; - this.glTexture = null; - } - -}); - -module.exports = TextureSource; - - -/***/ }), -/* 403 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Textures.Parsers - */ - -module.exports = { - - AtlasXML: __webpack_require__(975), - Canvas: __webpack_require__(976), - Image: __webpack_require__(977), - JSONArray: __webpack_require__(978), - JSONHash: __webpack_require__(979), - SpriteSheet: __webpack_require__(980), - SpriteSheetFromAtlas: __webpack_require__(981), - UnityYAML: __webpack_require__(982) - -}; - - -/***/ }), -/* 404 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var HTML5AudioSoundManager = __webpack_require__(405); -var NoAudioSoundManager = __webpack_require__(408); -var WebAudioSoundManager = __webpack_require__(410); - -/** - * Creates a Web Audio, HTML5 Audio or No Audio Sound Manager based on config and device settings. - * - * Be aware of https://developers.google.com/web/updates/2017/09/autoplay-policy-changes - * - * @function Phaser.Sound.SoundManagerCreator - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - * - * @return {(Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager|Phaser.Sound.NoAudioSoundManager)} The Sound Manager instance that was created. - */ -var SoundManagerCreator = { - - create: function (game) - { - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - return new NoAudioSoundManager(game); - } - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - return new WebAudioSoundManager(game); - } - - return new HTML5AudioSoundManager(game); - } - -}; - -module.exports = SoundManagerCreator; - - -/***/ }), -/* 405 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var HTML5AudioSound = __webpack_require__(407); - -/** - * HTML5 Audio implementation of the Sound Manager. - * - * To play multiple instances of the same HTML5 Audio sound, you need to provide an `instances` value when - * loading the sound with the Loader: - * - * ```javascript - * this.load.audio('explosion', 'explosion.mp3', { - * instances: 2 - * }); - * ``` - * - * Not all browsers can play all audio formats. - * - * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). - * - * @class HTML5AudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var HTML5AudioSoundManager = new Class({ - - Extends: BaseSoundManager, - - initialize: - - function HTML5AudioSoundManager (game) - { - /** - * Flag indicating whether if there are no idle instances of HTML5 Audio tag, - * for any particular sound, if one of the used tags should be hijacked and used - * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play - * call should be ignored. - * - * @name Phaser.Sound.HTML5AudioSoundManager#override - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.override = true; - - /** - * Value representing time difference, in seconds, between calling - * play method on an audio tag and when it actually starts playing. - * It is used to achieve more accurate delayed sound playback. - * - * You might need to tweak this value to get the desired results - * since audio play delay varies depending on the browser/platform. - * - * @name Phaser.Sound.HTML5AudioSoundManager#audioPlayDelay - * @type {number} - * @default 0.1 - * @since 3.0.0 - */ - this.audioPlayDelay = 0.1; - - /** - * A value by which we should offset the loop end marker of the - * looping sound to compensate for lag, caused by changing audio - * tag playback position, in order to achieve gapless looping. - * - * You might need to tweak this value to get the desired results - * since loop lag varies depending on the browser/platform. - * - * @name Phaser.Sound.HTML5AudioSoundManager#loopEndOffset - * @type {number} - * @default 0.05 - * @since 3.0.0 - */ - this.loopEndOffset = 0.05; - - /** - * An array for keeping track of all the sounds - * that were paused when game lost focus. - * - * @name Phaser.Sound.HTML5AudioSoundManager#onBlurPausedSounds - * @type {Phaser.Sound.HTML5AudioSound[]} - * @private - * @default [] - * @since 3.0.0 - */ - this.onBlurPausedSounds = []; - - this.locked = 'ontouchstart' in window; - - /** - * A queue of all actions performed on sound objects while audio was locked. - * Once the audio gets unlocked, after an explicit user interaction, - * all actions will be performed in chronological order. - * Array of object types: { sound: Phaser.Sound.HTML5AudioSound, name: string, value?: * } - * - * @name Phaser.Sound.HTML5AudioSoundManager#lockedActionsQueue - * @type {array} - * @private - * @since 3.0.0 - */ - this.lockedActionsQueue = this.locked ? [] : null; - - /** - * Property that actually holds the value of global mute - * for HTML5 Audio sound manager implementation. - * - * @name Phaser.Sound.HTML5AudioSoundManager#_mute - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._mute = false; - - /** - * Property that actually holds the value of global volume - * for HTML5 Audio sound manager implementation. - * - * @name Phaser.Sound.HTML5AudioSoundManager#_volume - * @type {boolean} - * @private - * @default 1 - * @since 3.0.0 - */ - this._volume = 1; - - BaseSoundManager.call(this, game); - }, - - /** - * Adds a new sound into the sound manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#add - * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. - * - * @return {Phaser.Sound.HTML5AudioSound} The new sound instance. - */ - add: function (key, config) - { - var sound = new HTML5AudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - /** - * Unlocks HTML5 Audio loading and playback on mobile - * devices on the initial explicit user interaction. - * - * @method Phaser.Sound.HTML5AudioSoundManager#unlock - * @since 3.0.0 - */ - unlock: function () - { - this.locked = false; - - var _this = this; - - this.game.cache.audio.entries.each(function (key, tags) - { - for (var i = 0; i < tags.length; i++) - { - if (tags[i].dataset.locked === 'true') - { - _this.locked = true; - - return false; - } - } - - return true; - }); - - if (!this.locked) - { - return; - } - - var moved = false; - - var detectMove = function () - { - moved = true; - }; - - var unlock = function () - { - if (moved) - { - moved = false; - return; - } - - document.body.removeEventListener('touchmove', detectMove); - document.body.removeEventListener('touchend', unlock); - - var lockedTags = []; - - _this.game.cache.audio.entries.each(function (key, tags) - { - for (var i = 0; i < tags.length; i++) - { - var tag = tags[i]; - - if (tag.dataset.locked === 'true') - { - lockedTags.push(tag); - } - } - - return true; - }); - - if (lockedTags.length === 0) - { - return; - } - - var lastTag = lockedTags[lockedTags.length - 1]; - - lastTag.oncanplaythrough = function () - { - lastTag.oncanplaythrough = null; - - lockedTags.forEach(function (tag) - { - tag.dataset.locked = 'false'; - }); - - _this.unlocked = true; - }; - - lockedTags.forEach(function (tag) - { - tag.load(); - }); - }; - - this.once(Events.UNLOCKED, function () - { - this.forEachActiveSound(function (sound) - { - if (sound.currentMarker === null && sound.duration === 0) - { - sound.duration = sound.tags[0].duration; - } - - sound.totalDuration = sound.tags[0].duration; - }); - - while (this.lockedActionsQueue.length) - { - var lockedAction = this.lockedActionsQueue.shift(); - - if (lockedAction.sound[lockedAction.prop].apply) - { - lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); - } - else - { - lockedAction.sound[lockedAction.prop] = lockedAction.value; - } - } - - }, this); - - document.body.addEventListener('touchmove', detectMove, false); - document.body.addEventListener('touchend', unlock, false); - }, - - /** - * Method used internally for pausing sound manager if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onBlur - * @protected - * @since 3.0.0 - */ - onBlur: function () - { - this.forEachActiveSound(function (sound) - { - if (sound.isPlaying) - { - this.onBlurPausedSounds.push(sound); - sound.onBlur(); - } - }); - }, - - /** - * Method used internally for resuming sound manager if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onFocus - * @protected - * @since 3.0.0 - */ - onFocus: function () - { - this.onBlurPausedSounds.forEach(function (sound) - { - sound.onFocus(); - }); - - this.onBlurPausedSounds.length = 0; - }, - - /** - * Calls Phaser.Sound.BaseSoundManager#destroy method - * and cleans up all HTML5 Audio related stuff. - * - * @method Phaser.Sound.HTML5AudioSoundManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSoundManager.prototype.destroy.call(this); - - this.onBlurPausedSounds.length = 0; - this.onBlurPausedSounds = null; - }, - - /** - * Method used internally by Phaser.Sound.HTML5AudioSound class methods and property setters - * to check if sound manager is locked and then either perform action immediately or queue it - * to be performed once the sound manager gets unlocked. - * - * @method Phaser.Sound.HTML5AudioSoundManager#isLocked - * @protected - * @since 3.0.0 - * - * @param {Phaser.Sound.HTML5AudioSound} sound - Sound object on which to perform queued action. - * @param {string} prop - Name of the method to be called or property to be assigned a value to. - * @param {*} [value] - An optional parameter that either holds an array of arguments to be passed to the method call or value to be set to the property. - * - * @return {boolean} Whether the sound manager is locked. - */ - isLocked: function (sound, prop, value) - { - if (sound.tags[0].dataset.locked === 'true') - { - this.lockedActionsQueue.push({ - sound: sound, - prop: prop, - value: value - }); - - return true; - } - - return false; - }, - - /** - * Sets the muted state of all this Sound Manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 - * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. - * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * @name Phaser.Sound.HTML5AudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return this._mute; - }, - - set: function (value) - { - this._mute = value; - - this.forEachActiveSound(function (sound) - { - sound.updateMute(); - }); - - this.emit(Events.GLOBAL_MUTE, this, value); - } - - }, - - /** - * Sets the volume of this Sound Manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 - * - * @param {number} value - The global volume of this Sound Manager. - * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * @name Phaser.Sound.HTML5AudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this._volume; - }, - - set: function (value) - { - this._volume = value; - - this.forEachActiveSound(function (sound) - { - sound.updateVolume(); - }); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = HTML5AudioSoundManager; - - -/***/ }), -/* 406 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SafeRange = __webpack_require__(78); - -/** - * 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 {number} [startIndex=0] - An optional start index to search from. - * @param {number} [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; - - -/***/ }), -/* 407 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var Clamp = __webpack_require__(17); - -/** - * @classdesc - * HTML5 Audio implementation of the sound. - * - * @class HTML5AudioSound - * @extends Phaser.Sound.BaseSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.HTML5AudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var HTML5AudioSound = new Class({ - - Extends: BaseSound, - - initialize: - - function HTML5AudioSound (manager, key, config) - { - if (config === undefined) { config = {}; } - - /** - * An array containing all HTML5 Audio tags that could be used for individual - * sound's playback. Number of instances depends on the config value passed - * to the Loader#audio method call, default is 1. - * - * @name Phaser.Sound.HTML5AudioSound#tags - * @type {HTMLAudioElement[]} - * @private - * @since 3.0.0 - */ - this.tags = manager.game.cache.audio.get(key); - - if (!this.tags) - { - throw new Error('There is no audio asset with key "' + key + '" in the audio cache'); - } - - /** - * Reference to an HTML5 Audio tag used for playing sound. - * - * @name Phaser.Sound.HTML5AudioSound#audio - * @type {HTMLAudioElement} - * @private - * @default null - * @since 3.0.0 - */ - this.audio = null; - - /** - * Timestamp as generated by the Request Animation Frame or SetTimeout - * representing the time at which the delayed sound playback should start. - * Set to 0 if sound playback is not delayed. - * - * @name Phaser.Sound.HTML5AudioSound#startTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * Audio tag's playback position recorded on previous - * update method call. Set to 0 if sound is not playing. - * - * @name Phaser.Sound.HTML5AudioSound#previousTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.previousTime = 0; - - this.duration = this.tags[0].duration; - - this.totalDuration = this.tags[0].duration; - - BaseSound.call(this, manager, key, config); - }, - - /** - * Play this sound, or a marked section of it. - * It always plays the sound from the start. If you want to start playback from a specific time - * you can set 'seek' setting of the config object, provided to this call, to that value. - * - * @method Phaser.Sound.HTML5AudioSound#play - * @fires Phaser.Sound.Events#PLAY - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} Whether the sound started playing successfully. - */ - play: function (markerName, config) - { - if (this.manager.isLocked(this, 'play', [ markerName, config ])) - { - return false; - } - - if (!BaseSound.prototype.play.call(this, markerName, config)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - if (!this.pickAndPlayAudioTag()) - { - return false; - } - - this.emit(Events.PLAY, this); - - return true; - }, - - /** - * Pauses the sound. - * - * @method Phaser.Sound.HTML5AudioSound#pause - * @fires Phaser.Sound.Events#PAUSE - * @since 3.0.0 - * - * @return {boolean} Whether the sound was paused successfully. - */ - pause: function () - { - if (this.manager.isLocked(this, 'pause')) - { - return false; - } - - if (this.startTime > 0) - { - return false; - } - - if (!BaseSound.prototype.pause.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = true \/\/\/ - this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - - this.stopAndReleaseAudioTag(); - - this.emit(Events.PAUSE, this); - - return true; - }, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.HTML5AudioSound#resume - * @fires Phaser.Sound.Events#RESUME - * @since 3.0.0 - * - * @return {boolean} Whether the sound was resumed successfully. - */ - resume: function () - { - if (this.manager.isLocked(this, 'resume')) - { - return false; - } - - if (this.startTime > 0) - { - return false; - } - - if (!BaseSound.prototype.resume.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - if (!this.pickAndPlayAudioTag()) - { - return false; - } - - this.emit(Events.RESUME, this); - - return true; - }, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.HTML5AudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 - * - * @return {boolean} Whether the sound was stopped successfully. - */ - stop: function () - { - if (this.manager.isLocked(this, 'stop')) - { - return false; - } - - if (!BaseSound.prototype.stop.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndReleaseAudioTag(); - - this.emit(Events.STOP, this); - - return true; - }, - - /** - * Used internally to do what the name says. - * - * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag - * @private - * @since 3.0.0 - * - * @return {boolean} Whether the sound was assigned an audio tag successfully. - */ - pickAndPlayAudioTag: function () - { - if (!this.pickAudioTag()) - { - this.reset(); - return false; - } - - var seek = this.currentConfig.seek; - var delay = this.currentConfig.delay; - var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; - - this.previousTime = offset; - this.audio.currentTime = offset; - this.applyConfig(); - - if (delay === 0) - { - this.startTime = 0; - - if (this.audio.paused) - { - this.playCatchPromise(); - } - } - else - { - this.startTime = window.performance.now() + delay * 1000; - - if (!this.audio.paused) - { - this.audio.pause(); - } - } - - this.resetConfig(); - - return true; - }, - - /** - * This method performs the audio tag pooling logic. It first looks for - * unused audio tag to assign to this sound object. If there are no unused - * audio tags, based on HTML5AudioSoundManager#override property value, it - * looks for sound with most advanced playback and hijacks its audio tag or - * does nothing. - * - * @method Phaser.Sound.HTML5AudioSound#pickAudioTag - * @private - * @since 3.0.0 - * - * @return {boolean} Whether the sound was assigned an audio tag successfully. - */ - pickAudioTag: function () - { - if (this.audio) - { - return true; - } - - for (var i = 0; i < this.tags.length; i++) - { - var audio = this.tags[i]; - - if (audio.dataset.used === 'false') - { - audio.dataset.used = 'true'; - this.audio = audio; - return true; - } - } - - if (!this.manager.override) - { - return false; - } - - var otherSounds = []; - - this.manager.forEachActiveSound(function (sound) - { - if (sound.key === this.key && sound.audio) - { - otherSounds.push(sound); - } - }, this); - - otherSounds.sort(function (a1, a2) - { - if (a1.loop === a2.loop) - { - // sort by progress - return (a2.seek / a2.duration) - (a1.seek / a1.duration); - } - return a1.loop ? 1 : -1; - }); - - var selectedSound = otherSounds[0]; - - this.audio = selectedSound.audio; - - selectedSound.reset(); - selectedSound.audio = null; - selectedSound.startTime = 0; - selectedSound.previousTime = 0; - - return true; - }, - - /** - * Method used for playing audio tag and catching possible exceptions - * thrown from rejected Promise returned from play method call. - * - * @method Phaser.Sound.HTML5AudioSound#playCatchPromise - * @private - * @since 3.0.0 - */ - playCatchPromise: function () - { - var playPromise = this.audio.play(); - - if (playPromise) - { - // eslint-disable-next-line no-unused-vars - playPromise.catch(function (reason) - { - console.warn(reason); - }); - } - }, - - /** - * Used internally to do what the name says. - * - * @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag - * @private - * @since 3.0.0 - */ - stopAndReleaseAudioTag: function () - { - this.startTime = 0; - this.previousTime = 0; - - if (this.audio) - { - this.audio.pause(); - this.audio.dataset.used = 'false'; - this.audio = null; - } - }, - - /** - * Method used internally to reset sound state, usually when stopping sound - * or when hijacking audio tag from another sound. - * - * @method Phaser.Sound.HTML5AudioSound#reset - * @private - * @since 3.0.0 - */ - reset: function () - { - BaseSound.prototype.stop.call(this); - }, - - /** - * Method used internally by sound manager for pausing sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onBlur - * @private - * @since 3.0.0 - */ - onBlur: function () - { - this.isPlaying = false; - this.isPaused = true; - - this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - - this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); - - this.stopAndReleaseAudioTag(); - }, - - /** - * Method used internally by sound manager for resuming sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSound#onFocus - * @private - * @since 3.0.0 - */ - onFocus: function () - { - this.isPlaying = true; - this.isPaused = false; - this.pickAndPlayAudioTag(); - }, - - /** - * Update method called automatically by sound manager on every game step. - * - * @method Phaser.Sound.HTML5AudioSound#update - * @fires Phaser.Sound.Events#COMPLETE - * @fires Phaser.Sound.Events#LOOPED - * @protected - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - */ - update: function (time) - { - if (!this.isPlaying) - { - return; - } - - // handling delayed playback - if (this.startTime > 0) - { - if (this.startTime < time - this.manager.audioPlayDelay) - { - this.audio.currentTime += Math.max(0, time - this.startTime) / 1000; - this.startTime = 0; - this.previousTime = this.audio.currentTime; - this.playCatchPromise(); - } - - return; - } - - // handle looping and ending - var startTime = this.currentMarker ? this.currentMarker.start : 0; - var endTime = startTime + this.duration; - var currentTime = this.audio.currentTime; - - if (this.currentConfig.loop) - { - if (currentTime >= endTime - this.manager.loopEndOffset) - { - this.audio.currentTime = startTime + Math.max(0, currentTime - endTime); - currentTime = this.audio.currentTime; - } - else if (currentTime < startTime) - { - this.audio.currentTime += startTime; - currentTime = this.audio.currentTime; - } - - if (currentTime < this.previousTime) - { - this.emit(Events.LOOPED, this); - } - } - else if (currentTime >= endTime) - { - this.reset(); - - this.stopAndReleaseAudioTag(); - - this.emit(Events.COMPLETE, this); - - return; - } - - this.previousTime = currentTime; - }, - - /** - * Calls Phaser.Sound.BaseSound#destroy method - * and cleans up all HTML5 Audio related stuff. - * - * @method Phaser.Sound.HTML5AudioSound#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - - this.tags = null; - - if (this.audio) - { - this.stopAndReleaseAudioTag(); - } - }, - - /** - * Method used internally to determine mute setting of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#updateMute - * @private - * @since 3.0.0 - */ - updateMute: function () - { - if (this.audio) - { - this.audio.muted = this.currentConfig.mute || this.manager.mute; - } - }, - - /** - * Method used internally to calculate total volume of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#updateVolume - * @private - * @since 3.0.0 - */ - updateVolume: function () - { - if (this.audio) - { - this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1); - } - }, - - /** - * Method used internally to calculate total playback rate of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#calculateRate - * @protected - * @since 3.0.0 - */ - calculateRate: function () - { - BaseSound.prototype.calculateRate.call(this); - - if (this.audio) - { - this.audio.playbackRate = this.totalRate; - } - }, - - /** - * Boolean indicating whether the sound is muted or not. - * Gets or sets the muted state of this sound. - * - * @name Phaser.Sound.HTML5AudioSound#mute - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return this.currentConfig.mute; - }, - - set: function (value) - { - this.currentConfig.mute = value; - - if (this.manager.isLocked(this, 'mute', value)) - { - return; - } - - this.updateMute(); - - this.emit(Events.MUTE, this, value); - } - }, - - /** - * Sets the muted state of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setMute - * @fires Phaser.Sound.Events#MUTE - * @since 3.4.0 - * - * @param {boolean} value - `true` to mute this sound, `false` to unmute it. - * - * @return {this} This Sound instance. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). - * - * @name Phaser.Sound.HTML5AudioSound#volume - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.currentConfig.volume; - }, - - set: function (value) - { - this.currentConfig.volume = value; - - if (this.manager.isLocked(this, 'volume', value)) - { - return; - } - - this.updateVolume(); - - this.emit(Events.VOLUME, this, value); - } - }, - - /** - * Sets the volume of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setVolume - * @fires Phaser.Sound.Events#VOLUME - * @since 3.4.0 - * - * @param {number} value - The volume of the sound. - * - * @return {this} This Sound instance. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * Rate at which this Sound will be played. - * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @name Phaser.Sound.HTML5AudioSound#rate - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#RATE - * @since 3.0.0 - */ - rate: { - - get: function () - { - return this.currentConfig.rate; - }, - - set: function (value) - { - this.currentConfig.rate = value; - - if (this.manager.isLocked(this, Events.RATE, value)) - { - return; - } - else - { - this.calculateRate(); - - this.emit(Events.RATE, this, value); - } - } - - }, - - /** - * Sets the playback rate of this Sound. - * - * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @method Phaser.Sound.HTML5AudioSound#setRate - * @fires Phaser.Sound.Events#RATE - * @since 3.3.0 - * - * @param {number} value - The playback rate at of this Sound. - * - * @return {this} This Sound instance. - */ - setRate: function (value) - { - this.rate = value; - - return this; - }, - - /** - * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @name Phaser.Sound.HTML5AudioSound#detune - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#DETUNE - * @since 3.0.0 - */ - detune: { - - get: function () - { - return this.currentConfig.detune; - }, - - set: function (value) - { - this.currentConfig.detune = value; - - if (this.manager.isLocked(this, Events.DETUNE, value)) - { - return; - } - else - { - this.calculateRate(); - - this.emit(Events.DETUNE, this, value); - } - } - - }, - - /** - * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @method Phaser.Sound.HTML5AudioSound#setDetune - * @fires Phaser.Sound.Events#DETUNE - * @since 3.3.0 - * - * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @return {this} This Sound instance. - */ - setDetune: function (value) - { - this.detune = value; - - return this; - }, - - /** - * Property representing the position of playback for this sound, in seconds. - * Setting it to a specific value moves current playback to that position. - * The value given is clamped to the range 0 to current marker duration. - * Setting seek of a stopped sound has no effect. - * - * @name Phaser.Sound.HTML5AudioSound#seek - * @type {number} - * @fires Phaser.Sound.Events#SEEK - * @since 3.0.0 - */ - seek: { - - get: function () - { - if (this.isPlaying) - { - return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - } - else if (this.isPaused) - { - return this.currentConfig.seek; - } - else - { - return 0; - } - }, - - set: function (value) - { - if (this.manager.isLocked(this, 'seek', value)) - { - return; - } - - if (this.startTime > 0) - { - return; - } - - if (this.isPlaying || this.isPaused) - { - value = Math.min(Math.max(0, value), this.duration); - - if (this.isPlaying) - { - this.previousTime = value; - this.audio.currentTime = value; - } - else if (this.isPaused) - { - this.currentConfig.seek = value; - } - - this.emit(Events.SEEK, this, value); - } - } - }, - - /** - * Seeks to a specific point in this sound. - * - * @method Phaser.Sound.HTML5AudioSound#setSeek - * @fires Phaser.Sound.Events#SEEK - * @since 3.4.0 - * - * @param {number} value - The point in the sound to seek to. - * - * @return {this} This Sound instance. - */ - setSeek: function (value) - { - this.seek = value; - - return this; - }, - - /** - * Flag indicating whether or not the sound or current sound marker will loop. - * - * @name Phaser.Sound.HTML5AudioSound#loop - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#LOOP - * @since 3.0.0 - */ - loop: { - - get: function () - { - return this.currentConfig.loop; - }, - - set: function (value) - { - this.currentConfig.loop = value; - - if (this.manager.isLocked(this, 'loop', value)) - { - return; - } - - if (this.audio) - { - this.audio.loop = value; - } - - this.emit(Events.LOOP, this, value); - } - - }, - - /** - * Sets the loop state of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setLoop - * @fires Phaser.Sound.Events#LOOP - * @since 3.4.0 - * - * @param {boolean} value - `true` to loop this sound, `false` to not loop it. - * - * @return {Phaser.Sound.HTML5AudioSound} This Sound instance. - */ - setLoop: function (value) - { - this.loop = value; - - return this; - }, - - /** - * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. - * - * @name Phaser.Sound.HTML5AudioSound#pan - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - */ - pan: { - - get: function () - { - return this.currentConfig.pan; - }, - - set: function (value) - { - this.currentConfig.pan = value; - - this.emit(Events.PAN, this, value); - } - }, - - /** - * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. - * - * @method Phaser.Sound.HTML5AudioSound#setPan - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - * - * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). - * - * @return {this} This Sound instance. - */ - setPan: function (value) - { - this.pan = value; - - return this; - } - -}); - -module.exports = HTML5AudioSound; - - -/***/ }), -/* 408 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var NoAudioSound = __webpack_require__(409); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * No-audio implementation of the Sound Manager. It is used if audio has been - * disabled in the game config or the device doesn't support any audio. - * - * It represents a graceful degradation of Sound Manager logic that provides - * minimal functionality and prevents Phaser projects that use audio from - * breaking on devices that don't support any audio playback technologies. - * - * @class NoAudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var NoAudioSoundManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function NoAudioSoundManager (game) - { - EventEmitter.call(this); - - this.game = game; - this.sounds = []; - this.mute = false; - this.volume = 1; - this.rate = 1; - this.detune = 0; - this.pauseOnBlur = true; - this.locked = false; - }, - - add: function (key, config) - { - var sound = new NoAudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - addAudioSprite: function (key, config) - { - var sound = this.add(key, config); - - sound.spritemap = {}; - - return sound; - }, - - // eslint-disable-next-line no-unused-vars - play: function (key, extra) - { - return false; - }, - - // eslint-disable-next-line no-unused-vars - playAudioSprite: function (key, spriteName, config) - { - return false; - }, - - remove: function (sound) - { - return BaseSoundManager.prototype.remove.call(this, sound); - }, - - removeByKey: function (key) - { - return BaseSoundManager.prototype.removeByKey.call(this, key); - }, - - pauseAll: NOOP, - resumeAll: NOOP, - stopAll: NOOP, - update: NOOP, - setRate: NOOP, - setDetune: NOOP, - setMute: NOOP, - setVolume: NOOP, - - forEachActiveSound: function (callbackfn, scope) - { - BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); - }, - - destroy: function () - { - BaseSoundManager.prototype.destroy.call(this); - } - -}); - -module.exports = NoAudioSoundManager; - - -/***/ }), -/* 409 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Extend = __webpack_require__(19); - -var returnFalse = function () -{ - return false; -}; - -var returnNull = function () -{ - return null; -}; - -var returnThis = function () -{ - return this; -}; - -/** - * @classdesc - * No audio implementation of the sound. It is used if audio has been - * disabled in the game config or the device doesn't support any audio. - * - * It represents a graceful degradation of sound logic that provides - * minimal functionality and prevents Phaser projects that use audio from - * breaking on devices that don't support any audio playback technologies. - * - * @class NoAudioSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.NoAudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var NoAudioSound = new Class({ - - Extends: EventEmitter, - - initialize: - - function NoAudioSound (manager, key, config) - { - if (config === void 0) { config = {}; } - - EventEmitter.call(this); - - this.manager = manager; - this.key = key; - this.isPlaying = false; - this.isPaused = false; - this.totalRate = 1; - this.duration = 0; - this.totalDuration = 0; - - this.config = Extend({ - mute: false, - volume: 1, - rate: 1, - detune: 0, - seek: 0, - loop: false, - delay: 0, - pan: 0 - }, config); - - this.currentConfig = this.config; - this.mute = false; - this.volume = 1; - this.rate = 1; - this.detune = 0; - this.seek = 0; - this.loop = false; - this.pan = 0; - this.markers = {}; - this.currentMarker = null; - this.pendingRemove = false; - }, - - /** - * @method Phaser.Sound.NoAudioSound#addMarker - * @since 3.0.0 - * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. - * - * @return {boolean} false - */ - addMarker: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#updateMarker - * @since 3.0.0 - * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. - * - * @return {boolean} false - */ - updateMarker: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#removeMarker - * @since 3.0.0 - * - * @param {string} markerName - The name of the marker to remove. - * - * @return {null} null - */ - removeMarker: returnNull, - - /** - * @method Phaser.Sound.NoAudioSound#play - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} false - */ - play: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#pause - * @since 3.0.0 - * - * @return {boolean} false - */ - pause: returnFalse, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.NoAudioSound#resume - * @since 3.0.0 - * - * @return {boolean} false - */ - resume: returnFalse, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.NoAudioSound#stop - * @since 3.0.0 - * - * @return {boolean} false - */ - stop: returnFalse, - - /** - * Destroys this sound and all associated events and marks it for removal from the sound manager. - * - * @method Phaser.Sound.NoAudioSound#destroy - * @fires Phaser.Sound.Events#DESTROY - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - }, - - setMute: returnThis, - - setVolume: returnThis, - - setRate: returnThis, - - setDetune: returnThis, - - setSeek: returnThis, - - setLoop: returnThis, - - setPan: returnThis - -}); - -module.exports = NoAudioSound; - - -/***/ }), -/* 410 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Base64ToArrayBuffer = __webpack_require__(411); -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var GameEvents = __webpack_require__(22); -var WebAudioSound = __webpack_require__(412); - -/** - * @classdesc - * Web Audio API implementation of the Sound Manager. - * - * Not all browsers can play all audio formats. - * - * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). - * - * @class WebAudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var WebAudioSoundManager = new Class({ - - Extends: BaseSoundManager, - - initialize: - - function WebAudioSoundManager (game) - { - /** - * The AudioContext being used for playback. - * - * @name Phaser.Sound.WebAudioSoundManager#context - * @type {AudioContext} - * @private - * @since 3.0.0 - */ - this.context = this.createAudioContext(game); - - /** - * Gain node responsible for controlling global muting. - * - * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.masterMuteNode = this.context.createGain(); - - /** - * Gain node responsible for controlling global volume. - * - * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.masterVolumeNode = this.context.createGain(); - - this.masterMuteNode.connect(this.masterVolumeNode); - - this.masterVolumeNode.connect(this.context.destination); - - /** - * Destination node for connecting individual sounds to. - * - * @name Phaser.Sound.WebAudioSoundManager#destination - * @type {AudioNode} - * @private - * @since 3.0.0 - */ - this.destination = this.masterMuteNode; - - this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); - - BaseSoundManager.call(this, game); - - if (this.locked && game.isBooted) - { - this.unlock(); - } - else - { - game.events.once(GameEvents.BOOT, this.unlock, this); - } - }, - - /** - * Method responsible for instantiating and returning AudioContext instance. - * If an instance of an AudioContext class was provided through the game config, - * that instance will be returned instead. This can come in handy if you are reloading - * a Phaser game on a page that never properly refreshes (such as in an SPA project) - * and you want to reuse already instantiated AudioContext. - * - * @method Phaser.Sound.WebAudioSoundManager#createAudioContext - * @private - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - * - * @return {AudioContext} The AudioContext instance to be used for playback. - */ - createAudioContext: function (game) - { - var audioConfig = game.config.audio; - - if (audioConfig.context) - { - audioConfig.context.resume(); - - return audioConfig.context; - } - - return new AudioContext(); - }, - - /** - * This method takes a new AudioContext reference and then sets - * this Sound Manager to use that context for all playback. - * - * As part of this call it also disconnects the master mute and volume - * nodes and then re-creates them on the new given context. - * - * @method Phaser.Sound.WebAudioSoundManager#setAudioContext - * @since 3.21.0 - * - * @param {AudioContext} context - Reference to an already created AudioContext instance. - * - * @return {this} The WebAudioSoundManager instance. - */ - setAudioContext: function (context) - { - if (this.context) - { - this.context.close(); - } - - if (this.masterMuteNode) - { - this.masterMuteNode.disconnect(); - } - - if (this.masterVolumeNode) - { - this.masterVolumeNode.disconnect(); - } - - this.context = context; - - this.masterMuteNode = context.createGain(); - this.masterVolumeNode = context.createGain(); - - this.masterMuteNode.connect(this.masterVolumeNode); - this.masterVolumeNode.connect(context.destination); - - this.destination = this.masterMuteNode; - - return this; - }, - - /** - * Adds a new sound into the sound manager. - * - * @method Phaser.Sound.WebAudioSoundManager#add - * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. - * - * @return {Phaser.Sound.WebAudioSound} The new sound instance. - */ - add: function (key, config) - { - var sound = new WebAudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - /** - * Decode audio data into a format ready for playback via Web Audio. - * - * The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. - * - * The `audioKey` is the key that will be used to save the decoded audio to the audio cache. - * - * Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig` - * objects as the first and only argument. - * - * Decoding is an async process, so be sure to listen for the events to know when decoding has completed. - * - * Once the audio has decoded it can be added to the Sound Manager or played via its key. - * - * @method Phaser.Sound.WebAudioSoundManager#decodeAudio - * @fires Phaser.Sound.Events#DECODED - * @fires Phaser.Sound.Events#DECODED_ALL - * @since 3.18.0 - * - * @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects. - * @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. - */ - decodeAudio: function (audioKey, audioData) - { - var audioFiles; - - if (!Array.isArray(audioKey)) - { - audioFiles = [ { key: audioKey, data: audioData } ]; - } - else - { - audioFiles = audioKey; - } - - var cache = this.game.cache.audio; - var remaining = audioFiles.length; - - for (var i = 0; i < audioFiles.length; i++) - { - var entry = audioFiles[i]; - - var key = entry.key; - var data = entry.data; - - if (typeof data === 'string') - { - data = Base64ToArrayBuffer(data); - } - - var success = function (key, audioBuffer) - { - cache.add(key, audioBuffer); - - this.emit(Events.DECODED, key); - - remaining--; - - if (remaining === 0) - { - this.emit(Events.DECODED_ALL); - } - }.bind(this, key); - - var failure = function (key, error) - { - // eslint-disable-next-line no-console - console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); - - remaining--; - - if (remaining === 0) - { - this.emit(Events.DECODED_ALL); - } - }.bind(this, key); - - this.context.decodeAudioData(data, success, failure); - } - }, - - /** - * Unlocks Web Audio API on the initial input event. - * - * Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09). - * - * @method Phaser.Sound.WebAudioSoundManager#unlock - * @since 3.0.0 - */ - unlock: function () - { - var _this = this; - - var body = document.body; - - var unlockHandler = function unlockHandler () - { - if (_this.context) - { - _this.context.resume().then(function () - { - body.removeEventListener('touchstart', unlockHandler); - body.removeEventListener('touchend', unlockHandler); - body.removeEventListener('click', unlockHandler); - body.removeEventListener('keydown', unlockHandler); - - _this.unlocked = true; - }, function () - { - body.removeEventListener('touchstart', unlockHandler); - body.removeEventListener('touchend', unlockHandler); - body.removeEventListener('click', unlockHandler); - body.removeEventListener('keydown', unlockHandler); - }); - } - }; - - if (body) - { - body.addEventListener('touchstart', unlockHandler, false); - body.addEventListener('touchend', unlockHandler, false); - body.addEventListener('click', unlockHandler, false); - body.addEventListener('keydown', unlockHandler, false); - } - }, - - /** - * Method used internally for pausing sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.WebAudioSoundManager#onBlur - * @protected - * @since 3.0.0 - */ - onBlur: function () - { - if (!this.locked) - { - this.context.suspend(); - } - }, - - /** - * Method used internally for resuming sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.WebAudioSoundManager#onFocus - * @protected - * @since 3.0.0 - */ - onFocus: function () - { - if (!this.locked) - { - this.context.resume(); - } - }, - - /** - * Calls Phaser.Sound.BaseSoundManager#destroy method - * and cleans up all Web Audio API related stuff. - * - * @method Phaser.Sound.WebAudioSoundManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.destination = null; - this.masterVolumeNode.disconnect(); - this.masterVolumeNode = null; - this.masterMuteNode.disconnect(); - this.masterMuteNode = null; - - if (this.game.config.audio.context) - { - this.context.suspend(); - } - else - { - var _this = this; - - this.context.close().then(function () - { - _this.context = null; - }); - } - - BaseSoundManager.prototype.destroy.call(this); - }, - - /** - * Sets the muted state of all this Sound Manager. - * - * @method Phaser.Sound.WebAudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 - * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. - * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * @name Phaser.Sound.WebAudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return (this.masterMuteNode.gain.value === 0); - }, - - set: function (value) - { - this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0); - - this.emit(Events.GLOBAL_MUTE, this, value); - } - - }, - - /** - * Sets the volume of this Sound Manager. - * - * @method Phaser.Sound.WebAudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 - * - * @param {number} value - The global volume of this Sound Manager. - * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * @name Phaser.Sound.WebAudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.masterVolumeNode.gain.value; - }, - - set: function (value) - { - this.masterVolumeNode.gain.setValueAtTime(value, 0); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = WebAudioSoundManager; - - -/***/ }), -/* 411 */ -/***/ (function(module, exports) { - -/** - * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -// Use a lookup table to find the index. -var lookup = new Uint8Array(256); - -for (var i = 0; i < chars.length; i++) -{ - lookup[chars.charCodeAt(i)] = i; -} - -/** - * Converts a base64 string, either with or without a data uri, into an Array Buffer. - * - * @function Phaser.Utils.Base64.Base64ToArrayBuffer - * @since 3.18.0 - * - * @param {string} base64 - The base64 string to be decoded. Can optionally contain a data URI header, which will be stripped out prior to decoding. - * - * @return {ArrayBuffer} An ArrayBuffer decoded from the base64 data. - */ -var Base64ToArrayBuffer = function (base64) -{ - // Is it a data uri? if so, strip the header away - base64 = base64.substr(base64.indexOf(',') + 1); - - var len = base64.length; - var bufferLength = len * 0.75; - var p = 0; - var encoded1; - var encoded2; - var encoded3; - var encoded4; - - if (base64[len - 1] === '=') - { - bufferLength--; - - if (base64[len - 2] === '=') - { - bufferLength--; - } - } - - var arrayBuffer = new ArrayBuffer(bufferLength); - var bytes = new Uint8Array(arrayBuffer); - - for (var i = 0; i < len; i += 4) - { - encoded1 = lookup[base64.charCodeAt(i)]; - encoded2 = lookup[base64.charCodeAt(i + 1)]; - encoded3 = lookup[base64.charCodeAt(i + 2)]; - encoded4 = lookup[base64.charCodeAt(i + 3)]; - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } - - return arrayBuffer; -}; - -module.exports = Base64ToArrayBuffer; - - -/***/ }), -/* 412 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); - -/** - * @classdesc - * Web Audio API implementation of the sound. - * - * @class WebAudioSound - * @extends Phaser.Sound.BaseSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.WebAudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var WebAudioSound = new Class({ - - Extends: BaseSound, - - initialize: - - function WebAudioSound (manager, key, config) - { - if (config === undefined) { config = {}; } - - /** - * Audio buffer containing decoded data of the audio asset to be played. - * - * @name Phaser.Sound.WebAudioSound#audioBuffer - * @type {AudioBuffer} - * @private - * @since 3.0.0 - */ - this.audioBuffer = manager.game.cache.audio.get(key); - - if (!this.audioBuffer) - { - throw new Error('Audio key "' + key + '" missing from cache'); - } - - /** - * A reference to an audio source node used for playing back audio from - * audio data stored in Phaser.Sound.WebAudioSound#audioBuffer. - * - * @name Phaser.Sound.WebAudioSound#source - * @type {AudioBufferSourceNode} - * @private - * @default null - * @since 3.0.0 - */ - this.source = null; - - /** - * A reference to a second audio source used for gapless looped playback. - * - * @name Phaser.Sound.WebAudioSound#loopSource - * @type {AudioBufferSourceNode} - * @private - * @default null - * @since 3.0.0 - */ - this.loopSource = null; - - /** - * Gain node responsible for controlling this sound's muting. - * - * @name Phaser.Sound.WebAudioSound#muteNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.muteNode = manager.context.createGain(); - - /** - * Gain node responsible for controlling this sound's volume. - * - * @name Phaser.Sound.WebAudioSound#volumeNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.volumeNode = manager.context.createGain(); - - /** - * Panner node responsible for controlling this sound's pan. - * - * @name Phaser.Sound.WebAudioSound#pannerNode - * @type {StereoPannerNode} - * @private - * @since 3.50.0 - */ - this.pannerNode = manager.context.createStereoPanner(); - - /** - * The time at which the sound should have started playback from the beginning. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#playTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.playTime = 0; - - /** - * The time at which the sound source should have actually started playback. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#startTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * The time at which the sound loop source should actually start playback. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#loopTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.loopTime = 0; - - /** - * An array where we keep track of all rate updates during playback. - * Array of object types: { time: number, rate: number } - * - * @name Phaser.Sound.WebAudioSound#rateUpdates - * @type {array} - * @private - * @default [] - * @since 3.0.0 - */ - this.rateUpdates = []; - - /** - * Used for keeping track when sound source playback has ended - * so its state can be updated accordingly. - * - * @name Phaser.Sound.WebAudioSound#hasEnded - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this.hasEnded = false; - - /** - * Used for keeping track when sound source has looped - * so its state can be updated accordingly. - * - * @name Phaser.Sound.WebAudioSound#hasLooped - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this.hasLooped = false; - - this.muteNode.connect(this.volumeNode); - - this.volumeNode.connect(this.pannerNode); - - this.pannerNode.connect(manager.destination); - - this.duration = this.audioBuffer.duration; - - this.totalDuration = this.audioBuffer.duration; - - BaseSound.call(this, manager, key, config); - }, - - /** - * Play this sound, or a marked section of it. - * - * It always plays the sound from the start. If you want to start playback from a specific time - * you can set 'seek' setting of the config object, provided to this call, to that value. - * - * @method Phaser.Sound.WebAudioSound#play - * @fires Phaser.Sound.Events#PLAY - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} Whether the sound started playing successfully. - */ - play: function (markerName, config) - { - if (!BaseSound.prototype.play.call(this, markerName, config)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - this.stopAndRemoveBufferSource(); - this.createAndStartBufferSource(); - - this.emit(Events.PLAY, this); - - return true; - }, - - /** - * Pauses the sound. - * - * @method Phaser.Sound.WebAudioSound#pause - * @fires Phaser.Sound.Events#PAUSE - * @since 3.0.0 - * - * @return {boolean} Whether the sound was paused successfully. - */ - pause: function () - { - if (this.manager.context.currentTime < this.startTime) - { - return false; - } - - if (!BaseSound.prototype.pause.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = true \/\/\/ - this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time - this.stopAndRemoveBufferSource(); - - this.emit(Events.PAUSE, this); - - return true; - }, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.WebAudioSound#resume - * @fires Phaser.Sound.Events#RESUME - * @since 3.0.0 - * - * @return {boolean} Whether the sound was resumed successfully. - */ - resume: function () - { - if (this.manager.context.currentTime < this.startTime) - { - return false; - } - - if (!BaseSound.prototype.resume.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - this.createAndStartBufferSource(); - - this.emit(Events.RESUME, this); - - return true; - }, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.WebAudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 - * - * @return {boolean} Whether the sound was stopped successfully. - */ - stop: function () - { - if (!BaseSound.prototype.stop.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndRemoveBufferSource(); - - this.emit(Events.STOP, this); - - return true; - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createAndStartBufferSource - * @private - * @since 3.0.0 - */ - createAndStartBufferSource: function () - { - var seek = this.currentConfig.seek; - var delay = this.currentConfig.delay; - var when = this.manager.context.currentTime + delay; - var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; - var duration = this.duration - seek; - - this.playTime = when - seek; - this.startTime = when; - this.source = this.createBufferSource(); - - this.applyConfig(); - - this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); - - this.resetConfig(); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource - * @private - * @since 3.0.0 - */ - createAndStartLoopBufferSource: function () - { - var when = this.getLoopTime(); - var offset = this.currentMarker ? this.currentMarker.start : 0; - var duration = this.duration; - - this.loopTime = when; - this.loopSource = this.createBufferSource(); - this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0); - this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createBufferSource - * @private - * @since 3.0.0 - * - * @return {AudioBufferSourceNode} - */ - createBufferSource: function () - { - var _this = this; - var source = this.manager.context.createBufferSource(); - - source.buffer = this.audioBuffer; - - source.connect(this.muteNode); - - source.onended = function (ev) - { - if (ev.target === _this.source) - { - // sound ended - if (_this.currentConfig.loop) - { - _this.hasLooped = true; - } - else - { - _this.hasEnded = true; - } - } - - // else was stopped - }; - - return source; - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource - * @private - * @since 3.0.0 - */ - stopAndRemoveBufferSource: function () - { - if (this.source) - { - this.source.stop(); - this.source.disconnect(); - this.source = null; - } - - this.playTime = 0; - this.startTime = 0; - - this.stopAndRemoveLoopBufferSource(); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource - * @private - * @since 3.0.0 - */ - stopAndRemoveLoopBufferSource: function () - { - if (this.loopSource) - { - this.loopSource.stop(); - this.loopSource.disconnect(); - this.loopSource = null; - } - - this.loopTime = 0; - }, - - /** - * Method used internally for applying config values to some of the sound properties. - * - * @method Phaser.Sound.WebAudioSound#applyConfig - * @protected - * @since 3.0.0 - */ - applyConfig: function () - { - this.rateUpdates.length = 0; - - this.rateUpdates.push({ - time: 0, - rate: 1 - }); - - BaseSound.prototype.applyConfig.call(this); - }, - - /** - * Update method called automatically by sound manager on every game step. - * - * @method Phaser.Sound.WebAudioSound#update - * @fires Phaser.Sound.Events#COMPLETE - * @fires Phaser.Sound.Events#LOOPED - * @protected - * @since 3.0.0 - */ - update: function () - { - if (this.hasEnded) - { - this.hasEnded = false; - - BaseSound.prototype.stop.call(this); - - this.stopAndRemoveBufferSource(); - - this.emit(Events.COMPLETE, this); - } - else if (this.hasLooped) - { - this.hasLooped = false; - this.source = this.loopSource; - this.loopSource = null; - this.playTime = this.startTime = this.loopTime; - this.rateUpdates.length = 0; - - this.rateUpdates.push({ - time: 0, - rate: this.totalRate - }); - - this.createAndStartLoopBufferSource(); - - this.emit(Events.LOOPED, this); - } - }, - - /** - * Calls Phaser.Sound.BaseSound#destroy method - * and cleans up all Web Audio API related stuff. - * - * @method Phaser.Sound.WebAudioSound#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - - this.audioBuffer = null; - this.stopAndRemoveBufferSource(); - this.muteNode.disconnect(); - this.muteNode = null; - this.volumeNode.disconnect(); - this.volumeNode = null; - this.pannerNode.disconnect(); - this.pannerNode = null; - this.rateUpdates.length = 0; - this.rateUpdates = null; - }, - - /** - * Method used internally to calculate total playback rate of the sound. - * - * @method Phaser.Sound.WebAudioSound#calculateRate - * @protected - * @since 3.0.0 - */ - calculateRate: function () - { - BaseSound.prototype.calculateRate.call(this); - - var now = this.manager.context.currentTime; - - if (this.source && typeof this.totalRate === 'number') - { - this.source.playbackRate.setValueAtTime(this.totalRate, now); - } - - if (this.isPlaying) - { - this.rateUpdates.push({ - time: Math.max(this.startTime, now) - this.playTime, - rate: this.totalRate - }); - - if (this.loopSource) - { - this.stopAndRemoveLoopBufferSource(); - this.createAndStartLoopBufferSource(); - } - } - }, - - /** - * Method used internally for calculating current playback time of a playing sound. - * - * @method Phaser.Sound.WebAudioSound#getCurrentTime - * @private - * @since 3.0.0 - */ - getCurrentTime: function () - { - var currentTime = 0; - - for (var i = 0; i < this.rateUpdates.length; i++) - { - var nextTime = 0; - - if (i < this.rateUpdates.length - 1) - { - nextTime = this.rateUpdates[i + 1].time; - } - else - { - nextTime = this.manager.context.currentTime - this.playTime; - } - - currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate; - } - - return currentTime; - }, - - /** - * Method used internally for calculating the time - * at witch the loop source should start playing. - * - * @method Phaser.Sound.WebAudioSound#getLoopTime - * @private - * @since 3.0.0 - */ - getLoopTime: function () - { - var lastRateUpdateCurrentTime = 0; - - for (var i = 0; i < this.rateUpdates.length - 1; i++) - { - lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; - } - - var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1]; - - return this.playTime + lastRateUpdate.time + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate; - }, - - /** - * Rate at which this Sound will be played. - * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @name Phaser.Sound.WebAudioSound#rate - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#RATE - * @since 3.0.0 - */ - rate: { - - get: function () - { - return this.currentConfig.rate; - }, - - set: function (value) - { - this.currentConfig.rate = value; - - this.calculateRate(); - - this.emit(Events.RATE, this, value); - } - - }, - - /** - * Sets the playback rate of this Sound. - * - * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @method Phaser.Sound.WebAudioSound#setRate - * @fires Phaser.Sound.Events#RATE - * @since 3.3.0 - * - * @param {number} value - The playback rate at of this Sound. - * - * @return {this} This Sound instance. - */ - setRate: function (value) - { - this.rate = value; - - return this; - }, - - /** - * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @name Phaser.Sound.WebAudioSound#detune - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#DETUNE - * @since 3.0.0 - */ - detune: { - - get: function () - { - return this.currentConfig.detune; - }, - - set: function (value) - { - this.currentConfig.detune = value; - - this.calculateRate(); - - this.emit(Events.DETUNE, this, value); - } - - }, - - /** - * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @method Phaser.Sound.WebAudioSound#setDetune - * @fires Phaser.Sound.Events#DETUNE - * @since 3.3.0 - * - * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @return {this} This Sound instance. - */ - setDetune: function (value) - { - this.detune = value; - - return this; - }, - - /** - * Boolean indicating whether the sound is muted or not. - * Gets or sets the muted state of this sound. - * - * @name Phaser.Sound.WebAudioSound#mute - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return (this.muteNode.gain.value === 0); - }, - - set: function (value) - { - this.currentConfig.mute = value; - this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0); - - this.emit(Events.MUTE, this, value); - } - - }, - - /** - * Sets the muted state of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setMute - * @fires Phaser.Sound.Events#MUTE - * @since 3.4.0 - * - * @param {boolean} value - `true` to mute this sound, `false` to unmute it. - * - * @return {this} This Sound instance. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). - * - * @name Phaser.Sound.WebAudioSound#volume - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.volumeNode.gain.value; - }, - - set: function (value) - { - this.currentConfig.volume = value; - this.volumeNode.gain.setValueAtTime(value, 0); - - this.emit(Events.VOLUME, this, value); - } - }, - - /** - * Sets the volume of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setVolume - * @fires Phaser.Sound.Events#VOLUME - * @since 3.4.0 - * - * @param {number} value - The volume of the sound. - * - * @return {this} This Sound instance. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * Property representing the position of playback for this sound, in seconds. - * Setting it to a specific value moves current playback to that position. - * The value given is clamped to the range 0 to current marker duration. - * Setting seek of a stopped sound has no effect. - * - * @name Phaser.Sound.WebAudioSound#seek - * @type {number} - * @fires Phaser.Sound.Events#SEEK - * @since 3.0.0 - */ - seek: { - - get: function () - { - if (this.isPlaying) - { - if (this.manager.context.currentTime < this.startTime) - { - return this.startTime - this.playTime; - } - - return this.getCurrentTime(); - } - else if (this.isPaused) - { - return this.currentConfig.seek; - } - else - { - return 0; - } - }, - - set: function (value) - { - if (this.manager.context.currentTime < this.startTime) - { - return; - } - - if (this.isPlaying || this.isPaused) - { - value = Math.min(Math.max(0, value), this.duration); - - this.currentConfig.seek = value; - - if (this.isPlaying) - { - this.stopAndRemoveBufferSource(); - this.createAndStartBufferSource(); - } - - this.emit(Events.SEEK, this, value); - } - } - }, - - /** - * Seeks to a specific point in this sound. - * - * @method Phaser.Sound.WebAudioSound#setSeek - * @fires Phaser.Sound.Events#SEEK - * @since 3.4.0 - * - * @param {number} value - The point in the sound to seek to. - * - * @return {this} This Sound instance. - */ - setSeek: function (value) - { - this.seek = value; - - return this; - }, - - /** - * Flag indicating whether or not the sound or current sound marker will loop. - * - * @name Phaser.Sound.WebAudioSound#loop - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#LOOP - * @since 3.0.0 - */ - loop: { - - get: function () - { - return this.currentConfig.loop; - }, - - set: function (value) - { - this.currentConfig.loop = value; - - if (this.isPlaying) - { - this.stopAndRemoveLoopBufferSource(); - - if (value) - { - this.createAndStartLoopBufferSource(); - } - } - - this.emit(Events.LOOP, this, value); - } - }, - - /** - * Sets the loop state of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setLoop - * @fires Phaser.Sound.Events#LOOP - * @since 3.4.0 - * - * @param {boolean} value - `true` to loop this sound, `false` to not loop it. - * - * @return {this} This Sound instance. - */ - setLoop: function (value) - { - this.loop = value; - - return this; - }, - - /** - * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * @name Phaser.Sound.WebAudioSound#pan - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - */ - pan: { - - get: function () - { - return this.pannerNode.pan.value; - }, - - set: function (value) - { - this.currentConfig.pan = value; - this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime); - - this.emit(Events.PAN, this, value); - } - }, - - /** - * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * @method Phaser.Sound.WebAudioSound#setPan - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - * - * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). - * - * @return {this} This Sound instance. - */ - setPan: function (value) - { - this.pan = value; - - return this; - } - -}); - -module.exports = WebAudioSound; - - -/***/ }), -/* 413 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 414 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 {number} k - The k-th element index. - * @param {number} [left=0] - The index of the left part of the range. - * @param {number} [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; - - -/***/ }), -/* 415 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetValue = __webpack_require__(6); -var Shuffle = __webpack_require__(129); - -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; - - -/***/ }), -/* 416 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Structs.Events - */ - -module.exports = { - - PROCESS_QUEUE_ADD: __webpack_require__(1035), - PROCESS_QUEUE_REMOVE: __webpack_require__(1036) - -}; - - -/***/ }), -/* 417 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetAdvancedValue = __webpack_require__(13); - -/** - * Adds an Animation component to a Sprite and populates it based on the given config. - * - * @function Phaser.GameObjects.BuildGameObjectAnimation - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. - * @param {object} config - The animation config. - * - * @return {Phaser.GameObjects.Sprite} The updated Sprite. - */ -var BuildGameObjectAnimation = function (sprite, config) -{ - var animConfig = GetAdvancedValue(config, 'anims', null); - - if (animConfig === null) - { - return sprite; - } - - if (typeof animConfig === 'string') - { - // { anims: 'key' } - sprite.anims.play(animConfig); - } - else if (typeof animConfig === 'object') - { - // { anims: { - // key: string - // startFrame: [string|number] - // delay: [float] - // repeat: [integer] - // repeatDelay: [float] - // yoyo: [boolean] - // play: [boolean] - // delayedPlay: [boolean] - // } - // } - - var anims = sprite.anims; - - var key = GetAdvancedValue(animConfig, 'key', undefined); - - if (key) - { - var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); - - var delay = GetAdvancedValue(animConfig, 'delay', 0); - var repeat = GetAdvancedValue(animConfig, 'repeat', 0); - var repeatDelay = GetAdvancedValue(animConfig, 'repeatDelay', 0); - var yoyo = GetAdvancedValue(animConfig, 'yoyo', false); - - var play = GetAdvancedValue(animConfig, 'play', false); - var delayedPlay = GetAdvancedValue(animConfig, 'delayedPlay', 0); - - var playConfig = { - key: key, - delay: delay, - repeat: repeat, - repeatDelay: repeatDelay, - yoyo: yoyo, - startFrame: startFrame - }; - - if (play) - { - anims.play(playConfig); - } - else if (delayedPlay > 0) - { - anims.playAfterDelay(playConfig, delayedPlay); - } - else - { - anims.load(playConfig); - } - } - } - - return sprite; -}; - -module.exports = BuildGameObjectAnimation; - - -/***/ }), -/* 418 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Frame = __webpack_require__(104); - -/** - * @classdesc - * A Bob Game Object. - * - * A Bob belongs to a Blitter Game Object. The Blitter is responsible for managing and rendering this object. - * - * A Bob has a position, alpha value and a frame from a texture that it uses to render with. You can also toggle - * the flipped and visible state of the Bob. The Frame the Bob uses to render can be changed dynamically, but it - * must be a Frame within the Texture used by the parent Blitter. - * - * Bob positions are relative to the Blitter parent. So if you move the Blitter parent, all Bob children will - * have their positions impacted by this change as well. - * - * You can manipulate Bob objects directly from your game code, but the creation and destruction of them should be - * handled via the Blitter parent. - * - * @class Bob - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Blitter} blitter - The parent Blitter object is responsible for updating this Bob. - * @param {number} x - The horizontal position of this Game Object in the world, relative to the parent Blitter position. - * @param {number} y - The vertical position of this Game Object in the world, relative to the parent Blitter position. - * @param {(string|number)} frame - The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. - * @param {boolean} visible - Should the Bob render visible or not to start with? - */ -var Bob = new Class({ - - initialize: - - function Bob (blitter, x, y, frame, visible) - { - /** - * The Blitter object that this Bob belongs to. - * - * @name Phaser.GameObjects.Bob#parent - * @type {Phaser.GameObjects.Blitter} - * @since 3.0.0 - */ - this.parent = blitter; - - /** - * The x position of this Bob, relative to the x position of the Blitter. - * - * @name Phaser.GameObjects.Bob#x - * @type {number} - * @since 3.0.0 - */ - this.x = x; - - /** - * The y position of this Bob, relative to the y position of the Blitter. - * - * @name Phaser.GameObjects.Bob#y - * @type {number} - * @since 3.0.0 - */ - this.y = y; - - /** - * The frame that the Bob uses to render with. - * To change the frame use the `Bob.setFrame` method. - * - * @name Phaser.GameObjects.Bob#frame - * @type {Phaser.Textures.Frame} - * @protected - * @since 3.0.0 - */ - this.frame = frame; - - /** - * A blank object which can be used to store data related to this Bob in. - * - * @name Phaser.GameObjects.Bob#data - * @type {object} - * @default {} - * @since 3.0.0 - */ - this.data = {}; - - /** - * The tint value of this Bob. - * - * @name Phaser.GameObjects.Bob#tint - * @type {number} - * @default 0xffffff - * @since 3.20.0 - */ - this.tint = 0xffffff; - - /** - * The visible state of this Bob. - * - * @name Phaser.GameObjects.Bob#_visible - * @type {boolean} - * @private - * @since 3.0.0 - */ - this._visible = visible; - - /** - * The alpha value of this Bob. - * - * @name Phaser.GameObjects.Bob#_alpha - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - this._alpha = 1; - - /** - * The horizontally flipped state of the Bob. - * A Bob that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture. - * - * @name Phaser.GameObjects.Bob#flipX - * @type {boolean} - * @since 3.0.0 - */ - this.flipX = false; - - /** - * The vertically flipped state of the Bob. - * A Bob 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. - * - * @name Phaser.GameObjects.Bob#flipY - * @type {boolean} - * @since 3.0.0 - */ - this.flipY = false; - }, - - /** - * Changes the Texture Frame being used by this Bob. - * The frame must be part of the Texture the parent Blitter is using. - * If no value is given it will use the default frame of the Blitter parent. - * - * @method Phaser.GameObjects.Bob#setFrame - * @since 3.0.0 - * - * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. - * - * @return {this} This Bob Game Object. - */ - setFrame: function (frame) - { - if (frame === undefined) - { - this.frame = this.parent.frame; - } - else if (frame instanceof Frame && frame.texture === this.parent.texture) - { - this.frame = frame; - } - else - { - this.frame = this.parent.texture.get(frame); - } - - return this; - }, - - /** - * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. - * - * @method Phaser.GameObjects.Bob#resetFlip - * @since 3.0.0 - * - * @return {this} This Bob Game Object. - */ - resetFlip: function () - { - this.flipX = false; - this.flipY = false; - - return this; - }, - - /** - * Resets this Bob. - * - * Changes the position to the values given, and optionally changes the frame. - * - * Also resets the flipX and flipY values, sets alpha back to 1 and visible to true. - * - * @method Phaser.GameObjects.Bob#reset - * @since 3.0.0 - * - * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. - * - * @return {this} This Bob Game Object. - */ - reset: function (x, y, frame) - { - this.x = x; - this.y = y; - - this.flipX = false; - this.flipY = false; - - this._alpha = 1; - this._visible = true; - - this.parent.dirty = true; - - if (frame) - { - this.setFrame(frame); - } - - return this; - }, - - /** - * Changes the position of this Bob to the values given. - * - * @method Phaser.GameObjects.Bob#setPosition - * @since 3.20.0 - * - * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * - * @return {this} This Bob Game Object. - */ - setPosition: function (x, y) - { - this.x = x; - this.y = y; - - return this; - }, - - /** - * Sets the horizontal flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#setFlipX - * @since 3.0.0 - * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Bob Game Object. - */ - setFlipX: function (value) - { - this.flipX = value; - - return this; - }, - - /** - * Sets the vertical flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#setFlipY - * @since 3.0.0 - * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Bob Game Object. - */ - setFlipY: function (value) - { - this.flipY = value; - - return this; - }, - - /** - * Sets the horizontal and vertical flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#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 Bob Game Object. - */ - setFlip: function (x, y) - { - this.flipX = x; - this.flipY = y; - - return this; - }, - - /** - * Sets the visibility of this Bob. - * - * An invisible Bob will skip rendering. - * - * @method Phaser.GameObjects.Bob#setVisible - * @since 3.0.0 - * - * @param {boolean} value - The visible state of the Game Object. - * - * @return {this} This Bob Game Object. - */ - setVisible: function (value) - { - this.visible = value; - - return this; - }, - - /** - * Set the Alpha level of this Bob. 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. - * - * A Bob with alpha 0 will skip rendering. - * - * @method Phaser.GameObjects.Bob#setAlpha - * @since 3.0.0 - * - * @param {number} value - The alpha value used for this Bob. Between 0 and 1. - * - * @return {this} This Bob Game Object. - */ - setAlpha: function (value) - { - this.alpha = value; - - return this; - }, - - /** - * Sets the tint of this Bob. - * - * @method Phaser.GameObjects.Bob#setTint - * @since 3.20.0 - * - * @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff. - * - * @return {this} This Bob Game Object. - */ - setTint: function (value) - { - this.tint = value; - - return this; - }, - - /** - * Destroys this Bob instance. - * Removes itself from the Blitter and clears the parent, frame and data properties. - * - * @method Phaser.GameObjects.Bob#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.parent.dirty = true; - - this.parent.children.remove(this); - - this.parent = undefined; - this.frame = undefined; - this.data = undefined; - }, - - /** - * The visible state of the Bob. - * - * An invisible Bob will skip rendering. - * - * @name Phaser.GameObjects.Bob#visible - * @type {boolean} - * @since 3.0.0 - */ - visible: { - - get: function () - { - return this._visible; - }, - - set: function (value) - { - this.parent.dirty |= (this._visible !== value); - this._visible = value; - } - - }, - - /** - * The alpha value of the Bob, between 0 and 1. - * - * A Bob with alpha 0 will skip rendering. - * - * @name Phaser.GameObjects.Bob#alpha - * @type {number} - * @since 3.0.0 - */ - alpha: { - - get: function () - { - return this._alpha; - }, - - set: function (value) - { - this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); - this._alpha = value; - } - - } - -}); - -module.exports = Bob; - - -/***/ }), -/* 419 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -/** - * 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; - - -/***/ }), -/* 420 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DOMElementRender = __webpack_require__(1049); -var GameObject = __webpack_require__(15); -var IsPlainObject = __webpack_require__(7); -var RemoveFromDOM = __webpack_require__(197); -var SCENE_EVENTS = __webpack_require__(21); -var Vector4 = __webpack_require__(138); - -/** - * @classdesc - * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. - * - * In order for DOM Elements to display you have to enable them by adding the following to your game - * configuration object: - * - * ```javascript - * dom { - * createContainer: true - * } - * ``` - * - * When this is added, Phaser will automatically create a DOM Container div that is positioned over the top - * of the game canvas. This div is sized to match the canvas, and if the canvas size changes, as a result of - * settings within the Scale Manager, the dom container is resized accordingly. - * - * If you have not already done so, you have to provide a `parent` in the Game Configuration, or the DOM - * Container will fail to be created. - * - * You can create a DOM Element by either passing in DOMStrings, or by passing in a reference to an existing - * Element that you wish to be placed under the control of Phaser. For example: - * - * ```javascript - * this.add.dom(x, y, 'div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * The above code will insert a div element into the DOM Container at the given x/y coordinate. The DOMString in - * the 4th argument sets the initial CSS style of the div and the final argument is the inner text. In this case, - * it will create a lime colored div that is 220px by 100px in size with the text Phaser in it, in an Arial font. - * - * You should nearly always, without exception, use explicitly sized HTML Elements, in order to fully control - * alignment and positioning of the elements next to regular game content. - * - * Rather than specify the CSS and HTML directly you can use the `load.html` File Loader to load it into the - * cache and then use the `createFromCache` method instead. You can also use `createFromHTML` and various other - * methods available in this class to help construct your elements. - * - * Once the element has been created you can then control it like you would any other Game Object. You can set its - * position, scale, rotation, alpha and other properties. It will move as the main Scene Camera moves and be clipped - * at the edge of the canvas. It's important to remember some limitations of DOM Elements: The obvious one is that - * they appear above or below your game canvas. You cannot blend them into the display list, meaning you cannot have - * a DOM Element, then a Sprite, then another DOM Element behind it. - * - * They also cannot be enabled for input. To do that, you have to use the `addListener` method to add native event - * listeners directly. The final limitation is to do with cameras. The DOM Container is sized to match the game canvas - * entirely and clipped accordingly. DOM Elements respect camera scrolling and scrollFactor settings, but if you - * change the size of the camera so it no longer matches the size of the canvas, they won't be clipped accordingly. - * - * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. - * - * Note that you should only have DOM Elements in a Scene with a _single_ Camera. If you require multiple cameras, - * use parallel scenes to achieve this. - * - * DOM Elements are a powerful way to align native HTML with your Phaser Game Objects. For example, you can insert - * a login form for a multiplayer game directly into your title screen. Or a text input box for a highscore table. - * Or a banner ad from a 3rd party service. Or perhaps you'd like to use them for high resolution text display and - * UI. The choice is up to you, just remember that you're dealing with standard HTML and CSS floating over the top - * of your game, and should treat it accordingly. - * - * @class DOMElement - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.17.0 - * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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 DOM Element in the world. - * @param {number} [y=0] - The vertical position of this DOM Element in the world. - * @param {(Element|string)} [element] - An existing DOM element, or a string. If a string starting with a # it will do a `getElementById` look-up on the string (minus the hash). Without a hash, it represents the type of element to create, i.e. 'div'. - * @param {(string|any)} [style] - If a string, will be set directly as the elements `style` property value. If a plain object, will be iterated and the values transferred. In both cases the values replacing whatever CSS styles may have been previously set. - * @param {string} [innerText] - If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. - */ -var DOMElement = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Origin, - Components.ScrollFactor, - Components.Transform, - Components.Visible, - DOMElementRender - ], - - initialize: - - function DOMElement (scene, x, y, element, style, innerText) - { - GameObject.call(this, scene, 'DOMElement'); - - /** - * A reference to the parent DOM Container that the Game instance created when it started. - * - * @name Phaser.GameObjects.DOMElement#parent - * @type {Element} - * @since 3.17.0 - */ - this.parent = scene.sys.game.domContainer; - - /** - * A reference to the HTML Cache. - * - * @name Phaser.GameObjects.DOMElement#cache - * @type {Phaser.Cache.BaseCache} - * @since 3.17.0 - */ - this.cache = scene.sys.cache.html; - - /** - * The actual DOM Element that this Game Object is bound to. For example, if you've created a `
` - * then this property is a direct reference to that element within the dom. - * - * @name Phaser.GameObjects.DOMElement#node - * @type {Element} - * @since 3.17.0 - */ - this.node; - - /** - * By default a DOM Element will have its transform, display, opacity, zIndex and blend mode properties - * updated when its rendered. If, for some reason, you don't want any of these changed other than the - * CSS transform, then set this flag to `true`. When `true` only the CSS Transform is applied and it's - * up to you to keep track of and set the other properties as required. - * - * This can be handy if, for example, you've a nested DOM Element and you don't want the opacity to be - * picked-up by any of its children. - * - * @name Phaser.GameObjects.DOMElement#transformOnly - * @type {boolean} - * @since 3.17.0 - */ - this.transformOnly = false; - - /** - * The angle, in radians, by which to skew the DOM Element on the horizontal axis. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @name Phaser.GameObjects.DOMElement#skewX - * @type {number} - * @since 3.17.0 - */ - this.skewX = 0; - - /** - * The angle, in radians, by which to skew the DOM Element on the vertical axis. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @name Phaser.GameObjects.DOMElement#skewY - * @type {number} - * @since 3.17.0 - */ - this.skewY = 0; - - /** - * A Vector4 that contains the 3D rotation of this DOM Element around a fixed axis in 3D space. - * - * All values in the Vector4 are treated as degrees, unless the `rotate3dAngle` property is changed. - * - * For more details see the following MDN page: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d - * - * @name Phaser.GameObjects.DOMElement#rotate3d - * @type {Phaser.Math.Vector4} - * @since 3.17.0 - */ - this.rotate3d = new Vector4(); - - /** - * The unit that represents the 3D rotation values. By default this is `deg` for degrees, but can - * be changed to any supported unit. See this page for further details: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d - * - * @name Phaser.GameObjects.DOMElement#rotate3dAngle - * @type {string} - * @since 3.17.0 - */ - this.rotate3dAngle = 'deg'; - - /** - * The native (un-scaled) width of this Game Object. - * - * For a DOM Element this property is read-only. - * - * The property `displayWidth` holds the computed bounds of this DOM Element, factoring in scaling. - * - * @name Phaser.GameObjects.DOMElement#width - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.width = 0; - - /** - * The native (un-scaled) height of this Game Object. - * - * For a DOM Element this property is read-only. - * - * The property `displayHeight` holds the computed bounds of this DOM Element, factoring in scaling. - * - * @name Phaser.GameObjects.DOMElement#height - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.height = 0; - - /** - * The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call. - * - * The property `width` holds the un-scaled width of this DOM Element. - * - * @name Phaser.GameObjects.DOMElement#displayWidth - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.displayWidth = 0; - - /** - * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. - * - * The property `height` holds the un-scaled height of this DOM Element. - * - * @name Phaser.GameObjects.DOMElement#displayHeight - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.displayHeight = 0; - - /** - * Internal native event handler. - * - * @name Phaser.GameObjects.DOMElement#handler - * @type {number} - * @private - * @since 3.17.0 - */ - this.handler = this.dispatchNativeEvent.bind(this); - - this.setPosition(x, y); - - if (typeof element === 'string') - { - // hash? - if (element[0] === '#') - { - this.setElement(element.substr(1), style, innerText); - } - else - { - this.createElement(element, style, innerText); - } - } - else if (element) - { - this.setElement(element, style, innerText); - } - - scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); - }, - - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, - - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); - }, - - /** - * Handles a Scene Sleep and Wake event. - * - * @method Phaser.GameObjects.DOMElement#handleSceneEvent - * @private - * @since 3.22.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems. - */ - handleSceneEvent: function (sys) - { - var node = this.node; - var style = node.style; - - if (node) - { - style.display = (sys.settings.visible) ? 'block' : 'none'; - } - }, - - /** - * Sets the horizontal and vertical skew values of this DOM Element. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @method Phaser.GameObjects.DOMElement#setSkew - * @since 3.17.0 - * - * @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis. - * @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis. - * - * @return {this} This DOM Element instance. - */ - setSkew: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.skewX = x; - this.skewY = y; - - return this; - }, - - /** - * Sets the perspective CSS property of the _parent DOM Container_. This determines the distance between the z=0 - * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with - * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined - * by the value of this property. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective - * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** - * - * @method Phaser.GameObjects.DOMElement#setPerspective - * @since 3.17.0 - * - * @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user. - * - * @return {this} This DOM Element instance. - */ - setPerspective: function (value) - { - this.parent.style.perspective = value + 'px'; - - return this; - }, - - /** - * The perspective CSS property value of the _parent DOM Container_. This determines the distance between the z=0 - * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with - * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined - * by the value of this property. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective - * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** - * - * @name Phaser.GameObjects.DOMElement#perspective - * @type {number} - * @since 3.17.0 - */ - perspective: { - - get: function () - { - return parseFloat(this.parent.style.perspective); - }, - - set: function (value) - { - this.parent.style.perspective = value + 'px'; - } - - }, - - /** - * Adds one or more native DOM event listeners onto the underlying Element of this Game Object. - * The event is then dispatched via this Game Objects standard event emitter. - * - * For example: - * - * ```javascript - * var div = this.add.dom(x, y, element); - * - * div.addListener('click'); - * - * div.on('click', handler); - * ``` - * - * @method Phaser.GameObjects.DOMElement#addListener - * @since 3.17.0 - * - * @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces. - * - * @return {this} This DOM Element instance. - */ - addListener: function (events) - { - if (this.node) - { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.addEventListener(events[i], this.handler, false); - } - } - - return this; - }, - - /** - * Removes one or more native DOM event listeners from the underlying Element of this Game Object. - * - * @method Phaser.GameObjects.DOMElement#removeListener - * @since 3.17.0 - * - * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. - * - * @return {this} This DOM Element instance. - */ - removeListener: function (events) - { - if (this.node) - { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.removeEventListener(events[i], this.handler); - } - } - - return this; - }, - - /** - * Internal event proxy to dispatch native DOM Events via this Game Object. - * - * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent - * @private - * @since 3.17.0 - * - * @param {any} event - The native DOM event. - */ - dispatchNativeEvent: function (event) - { - this.emit(event.type, event); - }, - - /** - * Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object, - * so you can control it. The `tagName` should be a string and is passed to `document.createElement`: - * - * ```javascript - * this.add.dom().createElement('div'); - * ``` - * - * For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement - * - * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` - * value as well. Here is an example of a DOMString: - * - * ```javascript - * this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * And using a style object: - * - * ```javascript - * var style = { - * 'background-color': 'lime'; - * 'width': '200px'; - * 'height': '100px'; - * 'font': '48px Arial'; - * }; - * - * this.add.dom().createElement('div', style, 'Phaser'); - * ``` - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createElement - * @since 3.17.0 - * - * @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method. - * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. - * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. - * - * @return {this} This DOM Element instance. - */ - createElement: function (tagName, style, innerText) - { - return this.setElement(document.createElement(tagName), style, innerText); - }, - - /** - * Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM - * entirely first. Any event listeners you may have previously created will need to be re-created on the new element. - * - * The `element` argument you pass to this method can be either a string tagName: - * - * ```javascript - *

Phaser

- * - * this.add.dom().setElement('heading'); - * ``` - * - * Or a reference to an Element instance: - * - * ```javascript - *

Phaser

- * - * var h1 = document.getElementById('heading'); - * - * this.add.dom().setElement(h1); - * ``` - * - * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` - * value as well. Here is an example of a DOMString: - * - * ```javascript - * this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * And using a style object: - * - * ```javascript - * var style = { - * 'background-color': 'lime'; - * 'width': '200px'; - * 'height': '100px'; - * 'font': '48px Arial'; - * }; - * - * this.add.dom().setElement(h1, style, 'Phaser'); - * ``` - * - * @method Phaser.GameObjects.DOMElement#setElement - * @since 3.17.0 - * - * @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. - * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. - * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. - * - * @return {this} This DOM Element instance. - */ - setElement: function (element, style, innerText) - { - // Already got an element? Remove it first - this.removeElement(); - - var target; - - if (typeof element === 'string') - { - // hash? - if (element[0] === '#') - { - element = element.substr(1); - } - - target = document.getElementById(element); - } - else if (typeof element === 'object' && element.nodeType === 1) - { - target = element; - } - - if (!target) - { - return this; - } - - this.node = target; - - // style can be empty, a string or a plain object - if (style && IsPlainObject(style)) - { - for (var key in style) - { - target.style[key] = style[key]; - } - } - else if (typeof style === 'string') - { - target.style = style; - } - - // Add / Override the values we need - - target.style.zIndex = '0'; - target.style.display = 'inline'; - target.style.position = 'absolute'; - - // Node handler - - target.phaser = this; - - if (this.parent) - { - this.parent.appendChild(target); - } - - // InnerText - - if (innerText) - { - target.innerText = innerText; - } - - return this.updateSize(); - }, - - /** - * Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then - * creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created - * element. - * - * Assume the following html is stored in a file called `loginform.html`: - * - * ```html - * - * - * ``` - * - * Which is loaded into your game using the cache key 'login': - * - * ```javascript - * this.load.html('login', 'assets/loginform.html'); - * ``` - * - * You can create a DOM Element from it using the cache key: - * - * ```javascript - * this.add.dom().createFromCache('login'); - * ``` - * - * The optional `elementType` argument controls the container that is created, into which the loaded html is inserted. - * The default is a plain `div` object, but any valid tagName can be given. - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createFromCache - * @since 3.17.0 - * - * @param {string} The key of the html cache entry to use for this DOM Element. - * @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. - * - * @return {this} This DOM Element instance. - */ - createFromCache: function (key, tagName) - { - var html = this.cache.get(key); - - if (html) - { - this.createFromHTML(html, tagName); - } - - return this; - }, - - /** - * Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML` - * property of the created element. - * - * ```javascript - * let form = ` - * - * - * `; - * ``` - * - * You can create a DOM Element from it using the string: - * - * ```javascript - * this.add.dom().createFromHTML(form); - * ``` - * - * The optional `elementType` argument controls the type of container that is created, into which the html is inserted. - * The default is a plain `div` object, but any valid tagName can be given. - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createFromHTML - * @since 3.17.0 - * - * @param {string} A string of html to be set as the `innerHTML` property of the created element. - * @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. - * - * @return {this} This DOM Element instance. - */ - createFromHTML: function (html, tagName) - { - if (tagName === undefined) { tagName = 'div'; } - - // Already got an element? Remove it first - this.removeElement(); - - var element = document.createElement(tagName); - - this.node = element; - - element.style.zIndex = '0'; - element.style.display = 'inline'; - element.style.position = 'absolute'; - - // Node handler - - element.phaser = this; - - if (this.parent) - { - this.parent.appendChild(element); - } - - element.innerHTML = html; - - return this.updateSize(); - }, - - /** - * Removes the current DOM Element bound to this Game Object from the DOM entirely and resets the - * `node` property of this Game Object to be `null`. - * - * @method Phaser.GameObjects.DOMElement#removeElement - * @since 3.17.0 - * - * @return {this} This DOM Element instance. - */ - removeElement: function () - { - if (this.node) - { - RemoveFromDOM(this.node); - - this.node = null; - } - - return this; - }, - - /** - * Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width - * and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight` - * values into the `width` and `height` properties respectively. - * - * This is called automatically whenever a new element is created or set. - * - * @method Phaser.GameObjects.DOMElement#updateSize - * @since 3.17.0 - * - * @return {this} This DOM Element instance. - */ - updateSize: function () - { - var node = this.node; - - var nodeBounds = node.getBoundingClientRect(); - - this.width = node.clientWidth; - this.height = node.clientHeight; - - this.displayWidth = nodeBounds.width || 0; - this.displayHeight = nodeBounds.height || 0; - - return this; - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a property matching the given key and value. It then returns this child - * if found, or `null` if not. - * - * @method Phaser.GameObjects.DOMElement#getChildByProperty - * @since 3.17.0 - * - * @param {string} property - The property to search the children for. - * @param {string} value - The value the property must strictly equal. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByProperty: function (property, value) - { - if (this.node) - { - var children = this.node.querySelectorAll('*'); - - for (var i = 0; i < children.length; i++) - { - if (children[i][property] === value) - { - return children[i]; - } - } - } - - return null; - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not. - * - * Be aware that class and id names are case-sensitive. - * - * @method Phaser.GameObjects.DOMElement#getChildByID - * @since 3.17.0 - * - * @param {string} id - The id to search the children for. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByID: function (id) - { - return this.getChildByProperty('id', id); - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not. - * - * Be aware that class and id names are case-sensitive. - * - * @method Phaser.GameObjects.DOMElement#getChildByName - * @since 3.17.0 - * - * @param {string} name - The name to search the children for. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByName: function (name) - { - return this.getChildByProperty('name', name); - }, - - /** - * Sets the `className` property of the DOM Element node and updates the internal sizes. - * - * @method Phaser.GameObjects.DOMElement#setClassName - * @since 3.17.0 - * - * @param {string} className - A string representing the class or space-separated classes of the element. - * - * @return {this} This DOM Element instance. - */ - setClassName: function (className) - { - if (this.node) - { - this.node.className = className; - - this.updateSize(); - } - - return this; - }, - - /** - * Sets the `innerText` property of the DOM Element node and updates the internal sizes. - * - * Note that only certain types of Elements can have `innerText` set on them. - * - * @method Phaser.GameObjects.DOMElement#setText - * @since 3.17.0 - * - * @param {string} text - A DOMString representing the rendered text content of the element. - * - * @return {this} This DOM Element instance. - */ - setText: function (text) - { - if (this.node) - { - this.node.innerText = text; - - this.updateSize(); - } - - return this; - }, - - /** - * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. - * - * @method Phaser.GameObjects.DOMElement#setHTML - * @since 3.17.0 - * - * @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element. - * - * @return {this} This DOM Element instance. - */ - setHTML: function (html) - { - if (this.node) - { - this.node.innerHTML = html; - - this.updateSize(); - } - - return this; - }, - - /** - * Runs internal update tasks. - * - * @method Phaser.GameObjects.DOMElement#preUpdate - * @private - * @since 3.17.0 - */ - preUpdate: function () - { - var parent = this.parentContainer; - var node = this.node; - - if (node && parent && !parent.willRender()) - { - node.style.display = 'none'; - } - }, - - /** - * Compares the renderMask with the renderFlags to see if this Game Object will render or not. - * - * DOMElements always return `true` as they need to still set values during the render pass, even if not visible. - * - * @method Phaser.GameObjects.DOMElement#willRender - * @since 3.17.0 - * - * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. - */ - willRender: function () - { - return true; - }, - - /** - * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. - * - * @method Phaser.GameObjects.DOMElement#preDestroy - * @private - * @since 3.17.0 - */ - preDestroy: function () - { - this.removeElement(); - - this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); - } - -}); - -module.exports = DOMElement; - - -/***/ }), -/* 421 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CSSBlendModes = __webpack_require__(1050); -var GameObject = __webpack_require__(15); -var TransformMatrix = __webpack_require__(25); - -var tempMatrix1 = new TransformMatrix(); -var tempMatrix2 = new TransformMatrix(); -var tempMatrix3 = new TransformMatrix(); - -/** - * 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.DOMElement#renderWebGL - * @since 3.17.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active renderer. - * @param {Phaser.GameObjects.DOMElement} 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 DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) -{ - var node = src.node; - var style = node.style; - var settings = src.scene.sys.settings; - - if (!node || !style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) - { - if (node) - { - style.display = 'none'; - } - - return; - } - - var parent = src.parentContainer; - var alpha = camera.alpha * src.alpha; - - if (parent) - { - alpha *= parent.alpha; - } - - var camMatrix = tempMatrix1; - var srcMatrix = tempMatrix2; - var calcMatrix = tempMatrix3; - - var dx = 0; - var dy = 0; - - var tx = '0%'; - var ty = '0%'; - - if (parentMatrix) - { - dx = (src.width * src.scaleX) * src.originX; - dy = (src.height * src.scaleY) * src.originY; - - srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); - - camMatrix.copyFrom(camera.matrix); - - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); - - // Undo the camera scroll - srcMatrix.e = src.x - dx; - srcMatrix.f = src.y - dy; - - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } - else - { - dx = (src.width) * src.originX; - dy = (src.height) * src.originY; - - srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); - - camMatrix.copyFrom(camera.matrix); - - tx = (100 * src.originX) + '%'; - ty = (100 * src.originY) + '%'; - - srcMatrix.e -= camera.scrollX * src.scrollFactorX; - srcMatrix.f -= camera.scrollY * src.scrollFactorY; - - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } - - if (!src.transformOnly) - { - style.display = 'block'; - style.opacity = alpha; - style.zIndex = src._depth; - style.pointerEvents = 'auto'; - style.mixBlendMode = CSSBlendModes[src._blendMode]; - } - - // https://developer.mozilla.org/en-US/docs/Web/CSS/transform - - style.transform = - calcMatrix.getCSSMatrix() + - ' skew(' + src.skewX + 'rad, ' + src.skewY + 'rad)' + - ' rotate3d(' + src.rotate3d.x + ',' + src.rotate3d.y + ',' + src.rotate3d.z + ',' + src.rotate3d.w + src.rotate3dAngle + ')'; - - style.transformOrigin = tx + ' ' + ty; -}; - -module.exports = DOMElementCSSRenderer; - - -/***/ }), -/* 422 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var ExternRender = __webpack_require__(1054); - -/** - * @classdesc - * An Extern Game Object is a special type of Game Object that allows you to pass - * rendering off to a 3rd party. - * - * When you create an Extern and place it in the display list of a Scene, the renderer will - * process the list as usual. When it finds an Extern it will flush the current batch, - * clear down the pipeline and prepare a transform matrix which your render function can - * take advantage of, if required. - * - * The WebGL context is then left is a 'clean' state, ready for you to bind your own shaders, - * or draw to it, whatever you wish to do. Once you've finished, you should free-up any - * of your resources. The Extern will then rebind the Phaser pipeline and carry on - * rendering the display list. - * - * Although this object has lots of properties such as Alpha, Blend Mode and Tint, none of - * them are used during rendering unless you take advantage of them in your own render code. - * - * @class Extern - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.16.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Tint - * @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. - */ -var Extern = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Flip, - Components.Origin, - Components.ScrollFactor, - Components.Size, - Components.Texture, - Components.Tint, - Components.Transform, - Components.Visible, - ExternRender - ], - - initialize: - - function Extern (scene) - { - GameObject.call(this, scene, 'Extern'); - }, - - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, - - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); - }, - - preUpdate: function () - { - // override this! - // Arguments: time, delta - }, - - render: function () - { - // override this! - // Arguments: renderer, camera, calcMatrix - } - -}); - -module.exports = Extern; - - -/***/ }), -/* 423 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircumferencePoint = __webpack_require__(213); -var FromPercent = __webpack_require__(95); -var MATH_CONST = __webpack_require__(14); -var Point = __webpack_require__(4); - -/** - * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse - * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point - * at 180 degrees around the circle. - * - * @function Phaser.Geom.Ellipse.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. - * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the ellipse. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. - */ -var GetPoint = function (ellipse, position, out) -{ - if (out === undefined) { out = new Point(); } - - var angle = FromPercent(position, 0, MATH_CONST.PI2); - - return CircumferencePoint(ellipse, angle, out); -}; - -module.exports = GetPoint; - - -/***/ }), -/* 424 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Circumference = __webpack_require__(425); -var CircumferencePoint = __webpack_require__(213); -var FromPercent = __webpack_require__(95); -var MATH_CONST = __webpack_require__(14); - -/** - * Returns an array of Point objects containing the coordinates of the points around the circumference of the Ellipse, - * based on the given quantity or stepRate values. - * - * @function Phaser.Geom.Ellipse.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the points from. - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the circumference of the ellipse and dividing it by the stepRate. - * @param {(array|Phaser.Geom.Point[])} [out] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse. - */ -var GetPoints = function (ellipse, 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 = Circumference(ellipse) / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); - - out.push(CircumferencePoint(ellipse, angle)); - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 425 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns the circumference of the given Ellipse. - * - * @function Phaser.Geom.Ellipse.Circumference - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference of. - * - * @return {number} The circumference of th Ellipse. - */ -var Circumference = function (ellipse) -{ - var rx = ellipse.width / 2; - var ry = ellipse.height / 2; - var h = Math.pow((rx - ry), 2) / Math.pow((rx + ry), 2); - - return (Math.PI * (rx + ry)) * (1 + ((3 * h) / (10 + Math.sqrt(4 - (3 * h))))); -}; - -module.exports = Circumference; - - -/***/ }), -/* 426 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Commands = __webpack_require__(212); -var SetTransform = __webpack_require__(30); - -/** - * 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.Graphics#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Graphics} 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 - * @param {CanvasRenderingContext2D} [renderTargetCtx] - The target rendering context. - * @param {boolean} allowClip - If `true` then path operations will be used instead of fill operations. - */ -var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) -{ - var commandBuffer = src.commandBuffer; - var commandBufferLength = commandBuffer.length; - - var ctx = renderTargetCtx || renderer.currentContext; - - if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - return; - } - - var lineAlpha = 1; - var fillAlpha = 1; - var lineColor = 0; - var fillColor = 0; - var lineWidth = 1; - var red = 0; - var green = 0; - var blue = 0; - - // Reset any currently active paths - ctx.beginPath(); - - for (var index = 0; index < commandBufferLength; ++index) - { - var commandID = commandBuffer[index]; - - switch (commandID) - { - case Commands.ARC: - ctx.arc( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4], - commandBuffer[index + 5], - commandBuffer[index + 6] - ); - - // +7 because overshoot is the 7th value, not used in Canvas - index += 7; - break; - - case Commands.LINE_STYLE: - lineWidth = commandBuffer[index + 1]; - lineColor = commandBuffer[index + 2]; - lineAlpha = commandBuffer[index + 3]; - red = ((lineColor & 0xFF0000) >>> 16); - green = ((lineColor & 0xFF00) >>> 8); - blue = (lineColor & 0xFF); - ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + lineAlpha + ')'; - ctx.lineWidth = lineWidth; - index += 3; - break; - - case Commands.FILL_STYLE: - fillColor = commandBuffer[index + 1]; - fillAlpha = commandBuffer[index + 2]; - red = ((fillColor & 0xFF0000) >>> 16); - green = ((fillColor & 0xFF00) >>> 8); - blue = (fillColor & 0xFF); - ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; - index += 2; - break; - - case Commands.BEGIN_PATH: - ctx.beginPath(); - break; - - case Commands.CLOSE_PATH: - ctx.closePath(); - break; - - case Commands.FILL_PATH: - if (!allowClip) - { - ctx.fill(); - } - break; - - case Commands.STROKE_PATH: - if (!allowClip) - { - ctx.stroke(); - } - break; - - case Commands.FILL_RECT: - if (!allowClip) - { - ctx.fillRect( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4] - ); - } - else - { - ctx.rect( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4] - ); - } - index += 4; - break; - - case Commands.FILL_TRIANGLE: - ctx.beginPath(); - ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); - ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); - ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); - ctx.closePath(); - if (!allowClip) - { - ctx.fill(); - } - index += 6; - break; - - case Commands.STROKE_TRIANGLE: - ctx.beginPath(); - ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); - ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); - ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); - ctx.closePath(); - if (!allowClip) - { - ctx.stroke(); - } - index += 6; - break; - - case Commands.LINE_TO: - ctx.lineTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.MOVE_TO: - ctx.moveTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.LINE_FX_TO: - ctx.lineTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 5; - break; - - case Commands.MOVE_FX_TO: - ctx.moveTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 5; - break; - - case Commands.SAVE: - ctx.save(); - break; - - case Commands.RESTORE: - ctx.restore(); - break; - - case Commands.TRANSLATE: - ctx.translate( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.SCALE: - ctx.scale( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.ROTATE: - ctx.rotate( - commandBuffer[index + 1] - ); - index += 1; - break; - - case Commands.GRADIENT_FILL_STYLE: - index += 5; - break; - - case Commands.GRADIENT_LINE_STYLE: - index += 6; - break; - } - } - - // Restore the context saved in SetTransform - ctx.restore(); -}; - -module.exports = GraphicsCanvasRenderer; - - -/***/ }), -/* 427 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var FloatBetween = __webpack_require__(135); -var GetEaseFunction = __webpack_require__(80); -var GetFastValue = __webpack_require__(2); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * A Particle Emitter property. - * - * Facilitates changing Particle properties as they are emitted and throughout their lifetime. - * - * @class EmitterOp - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for the Particle Emitter that owns this property. - * @param {string} key - The name of the property. - * @param {number} defaultValue - The default value of the property. - * @param {boolean} [emitOnly=false] - Whether the property can only be modified when a Particle is emitted. - */ -var EmitterOp = new Class({ - - initialize: - - function EmitterOp (config, key, defaultValue, emitOnly) - { - if (emitOnly === undefined) - { - emitOnly = false; - } - - /** - * The name of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#propertyKey - * @type {string} - * @since 3.0.0 - */ - this.propertyKey = key; - - /** - * The value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue - * @type {number} - * @since 3.0.0 - */ - this.propertyValue = defaultValue; - - /** - * The default value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue - * @type {number} - * @since 3.0.0 - */ - this.defaultValue = defaultValue; - - /** - * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. - * - * @name Phaser.GameObjects.Particles.EmitterOp#steps - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.steps = 0; - - /** - * The step counter for stepped easing, per emit. - * - * @name Phaser.GameObjects.Particles.EmitterOp#counter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.counter = 0; - - /** - * The start value for this property to ease between. - * - * @name Phaser.GameObjects.Particles.EmitterOp#start - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.start = 0; - - /** - * The end value for this property to ease between. - * - * @name Phaser.GameObjects.Particles.EmitterOp#end - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.end = 0; - - /** - * The easing function to use for updating this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#ease - * @type {?function} - * @since 3.0.0 - */ - this.ease; - - /** - * Whether this property can only be modified when a Particle is emitted. - * - * Set to `true` to allow only {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} callbacks to be set and - * affect this property. - * - * Set to `false` to allow both {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and - * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks to be set and affect this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#emitOnly - * @type {boolean} - * @since 3.0.0 - */ - this.emitOnly = emitOnly; - - /** - * The callback to run for Particles when they are emitted from the Particle Emitter. - * - * @name Phaser.GameObjects.Particles.EmitterOp#onEmit - * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback} - * @since 3.0.0 - */ - this.onEmit = this.defaultEmit; - - /** - * The callback to run for Particles when they are updated. - * - * @name Phaser.GameObjects.Particles.EmitterOp#onUpdate - * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} - * @since 3.0.0 - */ - this.onUpdate = this.defaultUpdate; - - this.loadConfig(config); - }, - - /** - * Load the property from a Particle Emitter configuration object. - * - * Optionally accepts a new property key to use, replacing the current one. - * - * @method Phaser.GameObjects.Particles.EmitterOp#loadConfig - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Settings for the Particle Emitter that owns this property. - * @param {string} [newKey] - The new key to use for this property, if any. - */ - loadConfig: function (config, newKey) - { - if (config === undefined) - { - config = {}; - } - - if (newKey) - { - this.propertyKey = newKey; - } - - this.propertyValue = GetFastValue( - config, - this.propertyKey, - this.defaultValue - ); - - this.setMethods(); - - if (this.emitOnly) - { - // Reset it back again - this.onUpdate = this.defaultUpdate; - } - }, - - /** - * Build a JSON representation of this Particle Emitter property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#toJSON - * @since 3.0.0 - * - * @return {object} A JSON representation of this Particle Emitter property. - */ - toJSON: function () - { - return this.propertyValue; - }, - - /** - * Change the current value of the property and update its callback methods. - * - * @method Phaser.GameObjects.Particles.EmitterOp#onChange - * @since 3.0.0 - * - * @param {number} value - The value of the property. - * - * @return {this} This Emitter Op object. - */ - onChange: function (value) - { - this.propertyValue = value; - - return this.setMethods(); - }, - - /** - * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and - * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the type of the current - * {@link Phaser.GameObjects.Particles.EmitterOp#propertyValue}. - * - * @method Phaser.GameObjects.Particles.EmitterOp#setMethods - * @since 3.0.0 - * - * @return {this} This Emitter Op object. - */ - setMethods: function () - { - var value = this.propertyValue; - - var t = typeof value; - - // Reset them in case they're not changed below - this.onEmit = this.defaultEmit; - this.onUpdate = this.defaultUpdate; - - if (t === 'number') - { - // Explicit static value: - // x: 400 - - this.onEmit = this.staticValueEmit; - this.onUpdate = this.staticValueUpdate; // How? - } - else if (Array.isArray(value)) - { - // Picks a random element from the array: - // x: [ 100, 200, 300, 400 ] - - this.onEmit = this.randomStaticValueEmit; - } - else if (t === 'function') - { - // The same as setting just the onUpdate function and no onEmit (unless this op is an emitOnly one) - // Custom callback, must return a value: - - /* - x: function (particle, key, t, value) - { - return value + 50; - } - */ - - if (this.emitOnly) - { - this.onEmit = value; - } - else - { - this.onUpdate = value; - } - } - else if (t === 'object' && this.hasBoth(value, 'start', 'end')) - { - this.start = value.start; - this.end = value.end; - - // x: { start: 100, end: 400, random: true } (random optional) = eases between start and end - - var isRandom = this.has(value, 'random'); - - if (isRandom) - { - this.onEmit = this.randomRangedValueEmit; - } - - if (this.has(value, 'steps')) - { - // A stepped (per emit) range - - // x: { start: 100, end: 400, steps: 64 } - - // Increments a value stored in the emitter - - this.steps = value.steps; - this.counter = this.start; - - this.onEmit = this.steppedEmit; - } - else - { - // An eased range (defaults to Linear if not specified) - - // x: { start: 100, end: 400, [ ease: 'Linear' ] } - - var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; - - this.ease = GetEaseFunction(easeType, value.easeParams); - - if (!isRandom) - { - this.onEmit = this.easedValueEmit; - } - - this.onUpdate = this.easeValueUpdate; - } - } - else if (t === 'object' && this.hasBoth(value, 'min', 'max')) - { - // { min: 100, max: 400 } = pick a random number between min and max - - this.start = value.min; - this.end = value.max; - this.onEmit = this.randomRangedValueEmit; - } - else if (t === 'object' && this.has(value, 'random')) - { - // { random: [ 100, 400 ] } = pick a random number between the two elements of the array - - var rnd = value.random; - - if (Array.isArray(rnd)) - { - this.start = rnd[0]; - this.end = rnd[1]; - } - - this.onEmit = this.randomRangedValueEmit; - } - else if (t === 'object' && this.hasEither(value, 'onEmit', 'onUpdate')) - { - // Custom onEmit and onUpdate callbacks - - /* - x: { - // Called at the start of the particles life, when it is being created - onEmit: function (particle, key, t, value) - { - return value; - }, - - // Called during the particles life on each update - onUpdate: function (particle, key, t, value) - { - return value; - } - } - */ - - if (this.has(value, 'onEmit')) - { - this.onEmit = value.onEmit; - } - - if (this.has(value, 'onUpdate')) - { - this.onUpdate = value.onUpdate; - } - } - - return this; - }, - - /** - * Check whether an object has the given property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#has - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key - The key of the property to look for in the object. - * - * @return {boolean} `true` if the property exists in the object, `false` otherwise. - */ - has: function (object, key) - { - return object.hasOwnProperty(key); - }, - - /** - * Check whether an object has both of the given properties. - * - * @method Phaser.GameObjects.Particles.EmitterOp#hasBoth - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key1 - The key of the first property to check the object for. - * @param {string} key2 - The key of the second property to check the object for. - * - * @return {boolean} `true` if both properties exist in the object, `false` otherwise. - */ - hasBoth: function (object, key1, key2) - { - return object.hasOwnProperty(key1) && object.hasOwnProperty(key2); - }, - - /** - * Check whether an object has at least one of the given properties. - * - * @method Phaser.GameObjects.Particles.EmitterOp#hasEither - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key1 - The key of the first property to check the object for. - * @param {string} key2 - The key of the second property to check the object for. - * - * @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist. - */ - hasEither: function (object, key1, key2) - { - return object.hasOwnProperty(key1) || object.hasOwnProperty(key2); - }, - - /** - * The returned value sets what the property will be at the START of the particles life, on emit. - * - * @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} [value] - The current value of the property. - * - * @return {number} The new value of the property. - */ - defaultEmit: function (particle, key, value) - { - return value; - }, - - /** - * The returned value updates the property for the duration of the particles life. - * - * @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} t - The T value (between 0 and 1) - * @param {number} value - The current value of the property. - * - * @return {number} The new value of the property. - */ - defaultUpdate: function (particle, key, t, value) - { - return value; - }, - - /** - * An `onEmit` callback that returns the current value of the property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit - * @since 3.0.0 - * - * @return {number} The current value of the property. - */ - staticValueEmit: function () - { - return this.propertyValue; - }, - - /** - * An `onUpdate` callback that returns the current value of the property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate - * @since 3.0.0 - * - * @return {number} The current value of the property. - */ - staticValueUpdate: function () - { - return this.propertyValue; - }, - - /** - * An `onEmit` callback that returns a random value from the current value array. - * - * @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit - * @since 3.0.0 - * - * @return {number} The new value of the property. - */ - randomStaticValueEmit: function () - { - var randomIndex = Math.floor(Math.random() * this.propertyValue.length); - - return this.propertyValue[randomIndex]; - }, - - /** - * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The key of the property. - * - * @return {number} The new value of the property. - */ - randomRangedValueEmit: function (particle, key) - { - var value = FloatBetween(this.start, this.end); - - if (particle && particle.data[key]) - { - particle.data[key].min = value; - } - - return value; - }, - - /** - * An `onEmit` callback that returns a stepped value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit - * @since 3.0.0 - * - * @return {number} The new value of the property. - */ - steppedEmit: function () - { - var current = this.counter; - - var next = this.counter + (this.end - this.start) / this.steps; - - this.counter = Wrap(next, this.start, this.end); - - return current; - }, - - /** - * An `onEmit` callback for an eased property. - * - * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. - * - * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * - * @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property. - */ - easedValueEmit: function (particle, key) - { - if (particle && particle.data[key]) - { - var data = particle.data[key]; - - data.min = this.start; - data.max = this.end; - } - - return this.start; - }, - - /** - * An `onUpdate` callback that returns an eased value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} t - The T value (between 0 and 1) - * - * @return {number} The new value of the property. - */ - easeValueUpdate: function (particle, key, t) - { - var data = particle.data[key]; - - return (data.max - data.min) * this.ease(t) + data.min; - } -}); - -module.exports = EmitterOp; - - -/***/ }), -/* 428 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * The GravityWell action applies a force on the particle to draw it towards, or repel it from, a single point. - * - * The force applied is inversely proportional to the square of the distance from the particle to the point, in accordance with Newton's law of gravity. - * - * This simulates the effect of gravity over large distances (as between planets, for example). - * - * @class GravityWell - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {(number|Phaser.Types.GameObjects.Particles.GravityWellConfig)} [x=0] - The x coordinate of the Gravity Well, in world space. - * @param {number} [y=0] - The y coordinate of the Gravity Well, in world space. - * @param {number} [power=0] - The strength of the gravity force - larger numbers produce a stronger force. - * @param {number} [epsilon=100] - The minimum distance for which the gravity force is calculated. - * @param {number} [gravity=50] - The gravitational force of this Gravity Well. - */ -var GravityWell = new Class({ - - initialize: - - function GravityWell (x, y, power, epsilon, gravity) - { - if (typeof x === 'object') - { - var config = x; - - x = GetFastValue(config, 'x', 0); - y = GetFastValue(config, 'y', 0); - power = GetFastValue(config, 'power', 0); - epsilon = GetFastValue(config, 'epsilon', 100); - gravity = GetFastValue(config, 'gravity', 50); - } - else - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (power === undefined) { power = 0; } - if (epsilon === undefined) { epsilon = 100; } - if (gravity === undefined) { gravity = 50; } - } - - /** - * The x coordinate of the Gravity Well, in world space. - * - * @name Phaser.GameObjects.Particles.GravityWell#x - * @type {number} - * @since 3.0.0 - */ - this.x = x; - - /** - * The y coordinate of the Gravity Well, in world space. - * - * @name Phaser.GameObjects.Particles.GravityWell#y - * @type {number} - * @since 3.0.0 - */ - this.y = y; - - /** - * The active state of the Gravity Well. An inactive Gravity Well will not influence any particles. - * - * @name Phaser.GameObjects.Particles.GravityWell#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Internal gravity value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_gravity - * @type {number} - * @private - * @since 3.0.0 - */ - this._gravity = gravity; - - /** - * Internal power value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_power - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._power = 0; - - /** - * Internal epsilon value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_epsilon - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._epsilon = 0; - - /** - * The strength of the gravity force - larger numbers produce a stronger force. - * - * @name Phaser.GameObjects.Particles.GravityWell#power - * @type {number} - * @since 3.0.0 - */ - this.power = power; - - /** - * The minimum distance for which the gravity force is calculated. - * - * @name Phaser.GameObjects.Particles.GravityWell#epsilon - * @type {number} - * @since 3.0.0 - */ - this.epsilon = epsilon; - }, - - /** - * Takes a Particle and updates it based on the properties of this Gravity Well. - * - * @method Phaser.GameObjects.Particles.GravityWell#update - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update. - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - */ - update: function (particle, delta) - { - var x = this.x - particle.x; - var y = this.y - particle.y; - var dSq = x * x + y * y; - - if (dSq === 0) - { - return; - } - - var d = Math.sqrt(dSq); - - if (dSq < this._epsilon) - { - dSq = this._epsilon; - } - - var factor = ((this._power * delta) / (dSq * d)) * 100; - - particle.velocityX += x * factor; - particle.velocityY += y * factor; - }, - - epsilon: { - - get: function () - { - return Math.sqrt(this._epsilon); - }, - - set: function (value) - { - this._epsilon = value * value; - } - - }, - - power: { - - get: function () - { - return this._power / this._gravity; - }, - - set: function (value) - { - this._power = value * this._gravity; - } - - }, - - gravity: { - - get: function () - { - return this._gravity; - }, - - set: function (value) - { - var pwr = this.power; - this._gravity = value; - this.power = pwr; - } - - } - -}); - -module.exports = GravityWell; - - -/***/ }), -/* 429 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var DistanceBetween = __webpack_require__(48); - -/** - * @classdesc - * A Particle is a simple Game Object controlled by a Particle Emitter and Manager, and rendered by the Manager. - * It uses its own lightweight physics system, and can interact only with its Emitter's bounds and zones. - * - * @class Particle - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. - */ -var Particle = new Class({ - - initialize: - - function Particle (emitter) - { - /** - * The Emitter to which this Particle belongs. - * - * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. - * - * @name Phaser.GameObjects.Particles.Particle#emitter - * @type {Phaser.GameObjects.Particles.ParticleEmitter} - * @since 3.0.0 - */ - this.emitter = emitter; - - /** - * The texture frame used to render this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#frame - * @type {Phaser.Textures.Frame} - * @default null - * @since 3.0.0 - */ - this.frame = null; - - /** - * The x coordinate of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = 0; - - /** - * The y coordinate of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = 0; - - /** - * The x velocity of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#velocityX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.velocityX = 0; - - /** - * The y velocity of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#velocityY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.velocityY = 0; - - /** - * The x acceleration of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#accelerationX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelerationX = 0; - - /** - * The y acceleration of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#accelerationY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelerationY = 0; - - /** - * The maximum horizontal velocity this Particle can travel at. - * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityX - * @type {number} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityX = 10000; - - /** - * The maximum vertical velocity this Particle can travel at. - * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityY - * @type {number} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityY = 10000; - - /** - * The bounciness, or restitution, of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#bounce - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.bounce = 0; - - /** - * The horizontal scale of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#scaleX - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.scaleX = 1; - - /** - * The vertical scale of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#scaleY - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.scaleY = 1; - - /** - * The alpha value of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#alpha - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.alpha = 1; - - /** - * The angle of this Particle in degrees. - * - * @name Phaser.GameObjects.Particles.Particle#angle - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angle = 0; - - /** - * The angle of this Particle in radians. - * - * @name Phaser.GameObjects.Particles.Particle#rotation - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.rotation = 0; - - /** - * The tint applied to this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#tint - * @type {number} - * @webglOnly - * @since 3.0.0 - */ - this.tint = 0xffffff; - - /** - * The lifespan of this Particle in ms. - * - * @name Phaser.GameObjects.Particles.Particle#life - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.life = 1000; - - /** - * The current life of this Particle in ms. - * - * @name Phaser.GameObjects.Particles.Particle#lifeCurrent - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.lifeCurrent = 1000; - - /** - * The delay applied to this Particle upon emission, in ms. - * - * @name Phaser.GameObjects.Particles.Particle#delayCurrent - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.delayCurrent = 0; - - /** - * The normalized lifespan T value, where 0 is the start and 1 is the end. - * - * @name Phaser.GameObjects.Particles.Particle#lifeT - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lifeT = 0; - - /** - * The data used by the ease equation. - * - * @name Phaser.GameObjects.Particles.Particle#data - * @type {object} - * @since 3.0.0 - */ - this.data = { - tint: { min: 0xffffff, max: 0xffffff, current: 0xffffff }, - alpha: { min: 1, max: 1 }, - rotate: { min: 0, max: 0 }, - scaleX: { min: 1, max: 1 }, - scaleY: { min: 1, max: 1 } - }; - }, - - /** - * Checks to see if this Particle is alive and updating. - * - * @method Phaser.GameObjects.Particles.Particle#isAlive - * @since 3.0.0 - * - * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. - */ - isAlive: function () - { - return (this.lifeCurrent > 0); - }, - - /** - * Resets the position of this particle back to zero. - * - * @method Phaser.GameObjects.Particles.Particle#resetPosition - * @since 3.16.0 - */ - resetPosition: function () - { - this.x = 0; - this.y = 0; - }, - - /** - * Starts this Particle from the given coordinates. - * - * @method Phaser.GameObjects.Particles.Particle#fire - * @since 3.0.0 - * - * @param {number} x - The x coordinate to launch this Particle from. - * @param {number} y - The y coordinate to launch this Particle from. - */ - fire: function (x, y) - { - var emitter = this.emitter; - - this.frame = emitter.getFrame(); - - if (emitter.emitZone) - { - // Updates particle.x and particle.y during this call - emitter.emitZone.getPoint(this); - } - - if (x === undefined) - { - this.x += emitter.x.onEmit(this, 'x'); - } - else - { - this.x += x; - } - - if (y === undefined) - { - this.y += emitter.y.onEmit(this, 'y'); - } - else - { - this.y += y; - } - - this.life = emitter.lifespan.onEmit(this, 'lifespan'); - this.lifeCurrent = this.life; - this.lifeT = 0; - - var sx = emitter.speedX.onEmit(this, 'speedX'); - var sy = (emitter.speedY) ? emitter.speedY.onEmit(this, 'speedY') : sx; - - if (emitter.radial) - { - var rad = DegToRad(emitter.angle.onEmit(this, 'angle')); - - this.velocityX = Math.cos(rad) * Math.abs(sx); - this.velocityY = Math.sin(rad) * Math.abs(sy); - } - else if (emitter.moveTo) - { - var mx = emitter.moveToX.onEmit(this, 'moveToX'); - var my = (emitter.moveToY) ? emitter.moveToY.onEmit(this, 'moveToY') : mx; - - var angle = Math.atan2(my - this.y, mx - this.x); - - var speed = DistanceBetween(this.x, this.y, mx, my) / (this.life / 1000); - - // We know how many pixels we need to move, but how fast? - // var speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000); - - this.velocityX = Math.cos(angle) * speed; - this.velocityY = Math.sin(angle) * speed; - } - else - { - this.velocityX = sx; - this.velocityY = sy; - } - - if (emitter.acceleration) - { - this.accelerationX = emitter.accelerationX.onEmit(this, 'accelerationX'); - this.accelerationY = emitter.accelerationY.onEmit(this, 'accelerationY'); - } - - this.maxVelocityX = emitter.maxVelocityX.onEmit(this, 'maxVelocityX'); - this.maxVelocityY = emitter.maxVelocityY.onEmit(this, 'maxVelocityY'); - - this.delayCurrent = emitter.delay.onEmit(this, 'delay'); - - this.scaleX = emitter.scaleX.onEmit(this, 'scaleX'); - this.scaleY = (emitter.scaleY) ? emitter.scaleY.onEmit(this, 'scaleY') : this.scaleX; - - this.angle = emitter.rotate.onEmit(this, 'rotate'); - this.rotation = DegToRad(this.angle); - - this.bounce = emitter.bounce.onEmit(this, 'bounce'); - - this.alpha = emitter.alpha.onEmit(this, 'alpha'); - - this.tint = emitter.tint.onEmit(this, 'tint'); - }, - - /** - * An internal method that calculates the velocity of the Particle. - * - * @method Phaser.GameObjects.Particles.Particle#computeVelocity - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle. - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - * @param {array} processors - Particle processors (gravity wells). - */ - computeVelocity: function (emitter, delta, step, processors) - { - var vx = this.velocityX; - var vy = this.velocityY; - - var ax = this.accelerationX; - var ay = this.accelerationY; - - var mx = this.maxVelocityX; - var my = this.maxVelocityY; - - vx += (emitter.gravityX * step); - vy += (emitter.gravityY * step); - - if (ax) - { - vx += (ax * step); - } - - if (ay) - { - vy += (ay * step); - } - - if (vx > mx) - { - vx = mx; - } - else if (vx < -mx) - { - vx = -mx; - } - - if (vy > my) - { - vy = my; - } - else if (vy < -my) - { - vy = -my; - } - - this.velocityX = vx; - this.velocityY = vy; - - // Apply any additional processors - for (var i = 0; i < processors.length; i++) - { - processors[i].update(this, delta, step); - } - }, - - /** - * Checks if this Particle is still within the bounds defined by the given Emitter. - * - * If not, and depending on the Emitter collision flags, the Particle may either stop or rebound. - * - * @method Phaser.GameObjects.Particles.Particle#checkBounds - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against. - */ - checkBounds: function (emitter) - { - var bounds = emitter.bounds; - var bounce = -this.bounce; - - if (this.x < bounds.x && emitter.collideLeft) - { - this.x = bounds.x; - this.velocityX *= bounce; - } - else if (this.x > bounds.right && emitter.collideRight) - { - this.x = bounds.right; - this.velocityX *= bounce; - } - - if (this.y < bounds.y && emitter.collideTop) - { - this.y = bounds.y; - this.velocityY *= bounce; - } - else if (this.y > bounds.bottom && emitter.collideBottom) - { - this.y = bounds.bottom; - this.velocityY *= bounce; - } - }, - - /** - * The main update method for this Particle. - * - * Updates its life values, computes the velocity and repositions the Particle. - * - * @method Phaser.GameObjects.Particles.Particle#update - * @since 3.0.0 - * - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - * @param {array} processors - An optional array of update processors. - * - * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. - */ - update: function (delta, step, processors) - { - if (this.delayCurrent > 0) - { - this.delayCurrent -= delta; - - return false; - } - - var emitter = this.emitter; - - // How far along in life is this particle? (t = 0 to 1) - var t = 1 - (this.lifeCurrent / this.life); - - this.lifeT = t; - - this.computeVelocity(emitter, delta, step, processors); - - this.x += this.velocityX * step; - this.y += this.velocityY * step; - - if (emitter.bounds) - { - this.checkBounds(emitter); - } - - if (emitter.deathZone && emitter.deathZone.willKill(this)) - { - this.lifeCurrent = 0; - - // No need to go any further, particle has been killed - return true; - } - - this.scaleX = emitter.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); - - if (emitter.scaleY) - { - this.scaleY = emitter.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); - } - else - { - this.scaleY = this.scaleX; - } - - this.angle = emitter.rotate.onUpdate(this, 'rotate', t, this.angle); - this.rotation = DegToRad(this.angle); - - this.alpha = emitter.alpha.onUpdate(this, 'alpha', t, this.alpha); - - this.tint = emitter.tint.onUpdate(this, 'tint', t, this.tint); - - this.lifeCurrent -= delta; - - return (this.lifeCurrent <= 0); - } - -}); - -module.exports = Particle; - - -/***/ }), -/* 430 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BlendModes = __webpack_require__(38); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DeathZone = __webpack_require__(431); -var EdgeZone = __webpack_require__(432); -var EmitterOp = __webpack_require__(427); -var GetFastValue = __webpack_require__(2); -var GetRandom = __webpack_require__(205); -var HasAny = __webpack_require__(433); -var HasValue = __webpack_require__(125); -var Particle = __webpack_require__(429); -var RandomZone = __webpack_require__(434); -var Rectangle = __webpack_require__(10); -var StableSort = __webpack_require__(79); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * A particle emitter represents a single particle stream. - * It controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles} and is controlled by a {@link Phaser.GameObjects.Particles.ParticleEmitterManager Particle Emitter Manager}. - * - * @class ParticleEmitter - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} manager - The Emitter Manager this Emitter belongs to. - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. - */ -var ParticleEmitter = new Class({ - - Mixins: [ - Components.BlendMode, - Components.Mask, - Components.ScrollFactor, - Components.Visible - ], - - initialize: - - function ParticleEmitter (manager, config) - { - /** - * The Emitter Manager this Emitter belongs to. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#manager - * @type {Phaser.GameObjects.Particles.ParticleEmitterManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * The texture assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 - */ - this.texture = manager.texture; - - /** - * The texture frames assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frames - * @type {Phaser.Textures.Frame[]} - * @since 3.0.0 - */ - this.frames = [ manager.defaultFrame ]; - - /** - * The default texture frame assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#defaultFrame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 - */ - this.defaultFrame = manager.defaultFrame; - - /** - * Names of simple configuration properties. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configFastMap - * @type {object} - * @since 3.0.0 - */ - this.configFastMap = [ - 'active', - 'blendMode', - 'collideBottom', - 'collideLeft', - 'collideRight', - 'collideTop', - 'deathCallback', - 'deathCallbackScope', - 'emitCallback', - 'emitCallbackScope', - 'follow', - 'frequency', - 'gravityX', - 'gravityY', - 'maxParticles', - 'name', - 'on', - 'particleBringToTop', - 'particleClass', - 'radial', - 'timeScale', - 'trackVisible', - 'visible' - ]; - - /** - * Names of complex configuration properties. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configOpMap - * @type {object} - * @since 3.0.0 - */ - this.configOpMap = [ - 'accelerationX', - 'accelerationY', - 'angle', - 'alpha', - 'bounce', - 'delay', - 'lifespan', - 'maxVelocityX', - 'maxVelocityY', - 'moveToX', - 'moveToY', - 'quantity', - 'rotate', - 'scaleX', - 'scaleY', - 'speedX', - 'speedY', - 'tint', - 'x', - 'y' - ]; - - /** - * The name of this Particle Emitter. - * - * Empty by default and never populated by Phaser, this is left for developers to use. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#name - * @type {string} - * @default '' - * @since 3.0.0 - */ - this.name = ''; - - /** - * The Particle Class which will be emitted by this Emitter. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass - * @type {Phaser.GameObjects.Particles.Particle} - * @default Phaser.GameObjects.Particles.Particle - * @since 3.0.0 - */ - this.particleClass = Particle; - - /** - * The x-coordinate of the particle origin (where particles will be emitted). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#x - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition - */ - this.x = new EmitterOp(config, 'x', 0, true); - - /** - * The y-coordinate of the particle origin (where particles will be emitted). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#y - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition - */ - this.y = new EmitterOp(config, 'y', 0, true); - - /** - * A radial emitter will emit particles in all directions between angle min and max, - * using {@link Phaser.GameObjects.Particles.ParticleEmitter#speed} as the value. If set to false then this acts as a point Emitter. - * A point emitter will emit particles only in the direction derived from the speedX and speedY values. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#radial - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial - */ - this.radial = true; - - /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity - */ - this.gravityX = 0; - - /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity - */ - this.gravityY = 0; - - /** - * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#acceleration - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.acceleration = false; - - /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.accelerationX = new EmitterOp(config, 'accelerationX', 0, true); - - /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.accelerationY = new EmitterOp(config, 'accelerationY', 0, true); - - /** - * The maximum horizontal velocity of emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityX = new EmitterOp(config, 'maxVelocityX', 10000, true); - - /** - * The maximum vertical velocity of emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityY = new EmitterOp(config, 'maxVelocityY', 10000, true); - - /** - * The initial horizontal speed of emitted particles, in pixels per second. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#speedX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX - */ - this.speedX = new EmitterOp(config, 'speedX', 0, true); - - /** - * The initial vertical speed of emitted particles, in pixels per second. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#speedY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY - */ - this.speedY = new EmitterOp(config, 'speedY', 0, true); - - /** - * Whether moveToX and moveToY are nonzero. Set automatically during configuration. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveTo - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.moveTo = false; - - /** - * The x-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.moveToX = new EmitterOp(config, 'moveToX', 0, true); - - /** - * The y-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.moveToY = new EmitterOp(config, 'moveToY', 0, true); - - /** - * Whether particles will rebound when they meet the emitter bounds. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#bounce - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.bounce = new EmitterOp(config, 'bounce', 0, true); - - /** - * The horizontal scale of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleX - */ - this.scaleX = new EmitterOp(config, 'scaleX', 1); - - /** - * The vertical scale of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleY - */ - this.scaleY = new EmitterOp(config, 'scaleY', 1); - - /** - * Color tint applied to emitted particles. Value must not include the alpha channel. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#tint - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0xffffff - * @since 3.0.0 - */ - this.tint = new EmitterOp(config, 'tint', 0xffffff); - - /** - * The alpha (transparency) of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#alpha - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setAlpha - */ - this.alpha = new EmitterOp(config, 'alpha', 1); - - /** - * The lifespan of emitted particles, in ms. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1000 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setLifespan - */ - this.lifespan = new EmitterOp(config, 'lifespan', 1000, true); - - /** - * The angle of the initial velocity of emitted particles, in degrees. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#angle - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default { min: 0, max: 360 } - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setAngle - */ - this.angle = new EmitterOp(config, 'angle', { min: 0, max: 360 }, true); - - /** - * The rotation of emitted particles, in degrees. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#rotate - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.rotate = new EmitterOp(config, 'rotate', 0); - - /** - * A function to call when a particle is emitted. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallback - * @type {?Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} - * @default null - * @since 3.0.0 - */ - this.emitCallback = null; - - /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallbackScope - * @type {?*} - * @default null - * @since 3.0.0 - */ - this.emitCallbackScope = null; - - /** - * A function to call when a particle dies. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallback - * @type {?Phaser.Types.GameObjects.Particles.ParticleDeathCallback} - * @default null - * @since 3.0.0 - */ - this.deathCallback = null; - - /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallbackScope - * @type {?*} - * @default null - * @since 3.0.0 - */ - this.deathCallbackScope = null; - - /** - * Set to hard limit the amount of particle objects this emitter is allowed to create. - * 0 means unlimited. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxParticles - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxParticles = 0; - - /** - * How many particles are emitted each time particles are emitted (one explosion or one flow cycle). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#quantity - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - * @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity - */ - this.quantity = new EmitterOp(config, 'quantity', 1, true); - - /** - * How many ms to wait after emission before the particles start updating. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#delay - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.delay = new EmitterOp(config, 'delay', 0, true); - - /** - * For a flow emitter, the time interval (>= 0) between particle flow cycles in ms. - * A value of 0 means there is one particle flow cycle for each logic update (the maximum flow frequency). This is the default setting. - * For an exploding emitter, this value will be -1. - * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} also puts the emitter in flow mode (frequency >= 0). - * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} also puts the emitter in explode mode (frequency = -1). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frequency - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - */ - this.frequency = 0; - - /** - * Controls if the emitter is currently emitting a particle flow (when frequency >= 0). - * Already alive particles will continue to update until they expire. - * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#start} and {@link Phaser.GameObjects.Particles.ParticleEmitter#stop}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#on - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.on = true; - - /** - * Newly emitted particles are added to the top of the particle list, i.e. rendered above those already alive. - * Set to false to send them to the back. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.particleBringToTop = true; - - /** - * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * An object describing a shape to emit particles from. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitZone - * @type {?Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone - */ - this.emitZone = null; - - /** - * An object describing a shape that deactivates particles when they interact with it. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathZone - * @type {?Phaser.GameObjects.Particles.Zones.DeathZone} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone - */ - this.deathZone = null; - - /** - * A rectangular boundary constraining particle movement. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#bounds - * @type {?Phaser.Geom.Rectangle} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setBounds - */ - this.bounds = null; - - /** - * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideLeft - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideLeft = true; - - /** - * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideRight - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideRight = true; - - /** - * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideTop - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideTop = true; - - /** - * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideBottom - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideBottom = true; - - /** - * Whether this emitter updates itself and its particles. - * - * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#pause} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#resume}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Set this to false to hide any active particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#visible - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setVisible - */ - this.visible = true; - - /** - * The blend mode of this emitter's particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#blendMode - * @type {number} - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setBlendMode - */ - this.blendMode = BlendModes.NORMAL; - - /** - * A Game Object whose position is used as the particle origin. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#follow - * @type {?Phaser.GameObjects.GameObject} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - * @see Phaser.GameObjects.Particles.ParticleEmitter#stopFollow - */ - this.follow = null; - - /** - * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#followOffset - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - */ - this.followOffset = new Vector2(); - - /** - * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track - * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#trackVisible - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - */ - this.trackVisible = false; - - /** - * The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.currentFrame = 0; - - /** - * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#randomFrame - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.randomFrame = true; - - /** - * The number of consecutive particles that receive a single texture frame (per frame cycle). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity - * @type {number} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.frameQuantity = 1; - - /** - * Inactive particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#dead - * @type {Phaser.GameObjects.Particles.Particle[]} - * @private - * @since 3.0.0 - */ - this.dead = []; - - /** - * Active particles - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#alive - * @type {Phaser.GameObjects.Particles.Particle[]} - * @private - * @since 3.0.0 - */ - this.alive = []; - - /** - * The time until the next flow cycle. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#_counter - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._counter = 0; - - /** - * Counts up to {@link Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#_frameCounter - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._frameCounter = 0; - - if (config) - { - this.fromJSON(config); - } - }, - - /** - * Merges configuration settings into the emitter's current settings. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. - * - * @return {this} This Particle Emitter. - */ - fromJSON: function (config) - { - if (!config) - { - return this; - } - - // Only update properties from their current state if they exist in the given config - - var i = 0; - var key = ''; - - for (i = 0; i < this.configFastMap.length; i++) - { - key = this.configFastMap[i]; - - if (HasValue(config, key)) - { - this[key] = GetFastValue(config, key); - } - } - - for (i = 0; i < this.configOpMap.length; i++) - { - key = this.configOpMap[i]; - - if (HasValue(config, key)) - { - this[key].loadConfig(config); - } - } - - this.acceleration = (this.accelerationX.propertyValue !== 0 || this.accelerationY.propertyValue !== 0); - - this.moveTo = (this.moveToX.propertyValue !== 0 || this.moveToY.propertyValue !== 0); - - // Special 'speed' override - - if (HasValue(config, 'speed')) - { - this.speedX.loadConfig(config, 'speed'); - this.speedY = null; - } - - // If you specify speedX, speedY or moveTo then it changes the emitter from radial to a point emitter - if (HasAny(config, [ 'speedX', 'speedY' ]) || this.moveTo) - { - this.radial = false; - } - - // Special 'scale' override - - if (HasValue(config, 'scale')) - { - this.scaleX.loadConfig(config, 'scale'); - this.scaleY = null; - } - - if (HasValue(config, 'callbackScope')) - { - var callbackScope = GetFastValue(config, 'callbackScope', null); - - this.emitCallbackScope = callbackScope; - this.deathCallbackScope = callbackScope; - } - - if (HasValue(config, 'emitZone')) - { - this.setEmitZone(config.emitZone); - } - - if (HasValue(config, 'deathZone')) - { - this.setDeathZone(config.deathZone); - } - - if (HasValue(config, 'bounds')) - { - this.setBounds(config.bounds); - } - - if (HasValue(config, 'followOffset')) - { - this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); - } - - if (HasValue(config, 'frame')) - { - this.setFrame(config.frame); - } - - if (HasValue(config, 'reserve')) - { - this.reserve(config.reserve); - } - - return this; - }, - - /** - * Creates a description of this emitter suitable for JSON serialization. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON - * @since 3.0.0 - * - * @param {object} [output] - An object to copy output into. - * - * @return {object} - The output object. - */ - toJSON: function (output) - { - if (output === undefined) { output = {}; } - - var i = 0; - var key = ''; - - for (i = 0; i < this.configFastMap.length; i++) - { - key = this.configFastMap[i]; - - output[key] = this[key]; - } - - for (i = 0; i < this.configOpMap.length; i++) - { - key = this.configOpMap[i]; - - if (this[key]) - { - output[key] = this[key].toJSON(); - } - } - - // special handlers - if (!this.speedY) - { - delete output.speedX; - output.speed = this.speedX.toJSON(); - } - - if (!this.scaleY) - { - delete output.scaleX; - output.scale = this.scaleX.toJSON(); - } - - return output; - }, - - /** - * Continuously moves the particle origin to follow a Game Object's position. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} target - The Game Object to follow. - * @param {number} [offsetX=0] - Horizontal offset of the particle origin from the Game Object. - * @param {number} [offsetY=0] - Vertical offset of the particle origin from the Game Object. - * @param {boolean} [trackVisible=false] - Whether the emitter's visible state will track the target's visible state. - * - * @return {this} This Particle Emitter. - */ - startFollow: function (target, offsetX, offsetY, trackVisible) - { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - if (trackVisible === undefined) { trackVisible = false; } - - this.follow = target; - this.followOffset.set(offsetX, offsetY); - this.trackVisible = trackVisible; - - return this; - }, - - /** - * Stops following a Game Object. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - stopFollow: function () - { - this.follow = null; - this.followOffset.set(0, 0); - this.trackVisible = false; - - return this; - }, - - /** - * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame - * @since 3.0.0 - * - * @return {Phaser.Textures.Frame} The texture frame. - */ - getFrame: function () - { - if (this.frames.length === 1) - { - return this.defaultFrame; - } - else if (this.randomFrame) - { - return GetRandom(this.frames); - } - else - { - var frame = this.frames[this.currentFrame]; - - this._frameCounter++; - - if (this._frameCounter === this.frameQuantity) - { - this._frameCounter = 0; - this.currentFrame = Wrap(this.currentFrame + 1, 0, this._frameLength); - } - - return frame; - } - }, - - // frame: 0 - // frame: 'red' - // frame: [ 0, 1, 2, 3 ] - // frame: [ 'red', 'green', 'blue', 'pink', 'white' ] - // frame: { frames: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } - - /** - * Sets a pattern for assigning texture frames to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrame - * @since 3.0.0 - * - * @param {(array|string|number|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} frames - One or more texture frames, or a configuration object. - * @param {boolean} [pickRandom=true] - Whether frames should be assigned at random from `frames`. - * @param {number} [quantity=1] - The number of consecutive particles that will receive each frame. - * - * @return {this} This Particle Emitter. - */ - setFrame: function (frames, pickRandom, quantity) - { - if (pickRandom === undefined) { pickRandom = true; } - if (quantity === undefined) { quantity = 1; } - - this.randomFrame = pickRandom; - this.frameQuantity = quantity; - this.currentFrame = 0; - this._frameCounter = 0; - - var t = typeof (frames); - - if (Array.isArray(frames) || t === 'string' || t === 'number') - { - this.manager.setEmitterFrames(frames, this); - } - else if (t === 'object') - { - var frameConfig = frames; - - frames = GetFastValue(frameConfig, 'frames', null); - - if (frames) - { - this.manager.setEmitterFrames(frames, this); - } - - var isCycle = GetFastValue(frameConfig, 'cycle', false); - - this.randomFrame = (isCycle) ? false : true; - - this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); - } - - this._frameLength = this.frames.length; - - if (this._frameLength === 1) - { - this.frameQuantity = 1; - this.randomFrame = false; - } - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial - * @since 3.0.0 - * - * @param {boolean} [value=true] - Radial mode (true) or point mode (true). - * - * @return {this} This Particle Emitter. - */ - setRadial: function (value) - { - if (value === undefined) { value = true; } - - this.radial = value; - - return this; - }, - - /** - * Sets the position of the emitter's particle origin. - * New particles will be emitted here. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setPosition - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} x - The x-coordinate of the particle origin. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} y - The y-coordinate of the particle origin. - * - * @return {this} This Particle Emitter. - */ - setPosition: function (x, y) - { - this.x.onChange(x); - this.y.onChange(y); - - return this; - }, - - /** - * Sets or modifies a rectangular boundary constraining the particles. - * - * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setBounds - * @since 3.0.0 - * - * @param {(number|Phaser.Types.GameObjects.Particles.ParticleEmitterBounds|Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt)} x - The x-coordinate of the left edge of the boundary, or an object representing a rectangle. - * @param {number} y - The y-coordinate of the top edge of the boundary. - * @param {number} width - The width of the boundary. - * @param {number} height - The height of the boundary. - * - * @return {this} This Particle Emitter. - */ - setBounds: function (x, y, width, height) - { - if (typeof x === 'object') - { - var obj = x; - - x = obj.x; - y = obj.y; - width = (HasValue(obj, 'w')) ? obj.w : obj.width; - height = (HasValue(obj, 'h')) ? obj.h : obj.height; - } - - if (this.bounds) - { - this.bounds.setTo(x, y, width, height); - } - else - { - this.bounds = new Rectangle(x, y, width, height); - } - - return this; - }, - - /** - * Sets the initial horizontal speed of emitted particles. - * Changes the emitter to point mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeedX: function (value) - { - this.speedX.onChange(value); - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = false; - - return this; - }, - - /** - * Sets the initial vertical speed of emitted particles. - * Changes the emitter to point mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeedY: function (value) - { - if (this.speedY) - { - this.speedY.onChange(value); - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = false; - } - - return this; - }, - - /** - * Sets the initial radial speed of emitted particles. - * Changes the emitter to radial mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeed - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeed: function (value) - { - this.speedX.onChange(value); - this.speedY = null; - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = true; - - return this; - }, - - /** - * Sets the horizontal scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleX - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScaleX: function (value) - { - this.scaleX.onChange(value); - - return this; - }, - - /** - * Sets the vertical scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleY - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScaleY: function (value) - { - this.scaleY.onChange(value); - - return this; - }, - - /** - * Sets the scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScale: function (value) - { - this.scaleX.onChange(value); - this.scaleY = null; - - return this; - }, - - /** - * Sets the horizontal gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityX - * @since 3.0.0 - * - * @param {number} value - Acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravityX: function (value) - { - this.gravityX = value; - - return this; - }, - - /** - * Sets the vertical gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityY - * @since 3.0.0 - * - * @param {number} value - Acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravityY: function (value) - { - this.gravityY = value; - - return this; - }, - - /** - * Sets the gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravity - * @since 3.0.0 - * - * @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. - * @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravity: function (x, y) - { - this.gravityX = x; - this.gravityY = y; - - return this; - }, - - /** - * Sets the opacity of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAlpha - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 (transparent) and 1 (opaque). - * - * @return {this} This Particle Emitter. - */ - setAlpha: function (value) - { - this.alpha.onChange(value); - - return this; - }, - - /** - * Sets the color tint of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setTint - * @since 3.22.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff. - * - * @return {this} This Particle Emitter. - */ - setTint: function (value) - { - this.tint.onChange(value); - - return this; - }, - - /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. - * - * @return {this} This Particle Emitter. - */ - setEmitterAngle: function (value) - { - this.angle.onChange(value); - - return this; - }, - - /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAngle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. - * - * @return {this} This Particle Emitter. - */ - setAngle: function (value) - { - this.angle.onChange(value); - - return this; - }, - - /** - * Sets the lifespan of newly emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setLifespan - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The particle lifespan, in ms. - * - * @return {this} This Particle Emitter. - */ - setLifespan: function (value) - { - this.lifespan.onChange(value); - - return this; - }, - - /** - * Sets the number of particles released at each flow cycle or explosion. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} quantity - The number of particles to release at each flow cycle or explosion. - * - * @return {this} This Particle Emitter. - */ - setQuantity: function (quantity) - { - this.quantity.onChange(quantity); - - return this; - }, - - /** - * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - * @since 3.0.0 - * - * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [quantity] - The number of particles to release at each flow cycle or explosion. - * - * @return {this} This Particle Emitter. - */ - setFrequency: function (frequency, quantity) - { - this.frequency = frequency; - - this._counter = 0; - - if (quantity) - { - this.quantity.onChange(quantity); - } - - return this; - }, - - /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#emitZone}. - * - * An {@link Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig EdgeZone} places particles on its edges. Its {@link Phaser.Types.GameObjects.Particles.EdgeZoneSource source} can be a Curve, Path, Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback getPoints} method. - * - * A {@link Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig RandomZone} places randomly within its interior. Its {@link RandomZoneSource source} can be a Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.RandomZoneSourceCallback getRandomPoint} method. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current emit zone. - * - * @return {this} This Particle Emitter. - */ - setEmitZone: function (zoneConfig) - { - if (zoneConfig === undefined) - { - this.emitZone = null; - } - else - { - // Where source = Geom like Circle, or a Path or Curve - // emitZone: { type: 'random', source: X } - // emitZone: { type: 'edge', source: X, quantity: 32, [stepRate=0], [yoyo=false], [seamless=true] } - - var type = GetFastValue(zoneConfig, 'type', 'random'); - var source = GetFastValue(zoneConfig, 'source', null); - - switch (type) - { - case 'random': - - this.emitZone = new RandomZone(source); - - break; - - case 'edge': - - var quantity = GetFastValue(zoneConfig, 'quantity', 1); - var stepRate = GetFastValue(zoneConfig, 'stepRate', 0); - var yoyo = GetFastValue(zoneConfig, 'yoyo', false); - var seamless = GetFastValue(zoneConfig, 'seamless', true); - - this.emitZone = new EdgeZone(source, quantity, stepRate, yoyo, seamless); - - break; - } - } - - return this; - }, - - /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current death zone. - * - * @return {this} This Particle Emitter. - */ - setDeathZone: function (zoneConfig) - { - if (zoneConfig === undefined) - { - this.deathZone = null; - } - else - { - // Where source = Geom like Circle or Rect that supports a 'contains' function - // deathZone: { type: 'onEnter', source: X } - // deathZone: { type: 'onLeave', source: X } - - var type = GetFastValue(zoneConfig, 'type', 'onEnter'); - var source = GetFastValue(zoneConfig, 'source', null); - - if (source && typeof source.contains === 'function') - { - var killOnEnter = (type === 'onEnter') ? true : false; - - this.deathZone = new DeathZone(source, killOnEnter); - } - } - - return this; - }, - - /** - * Creates inactive particles and adds them to this emitter's pool. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve - * @since 3.0.0 - * - * @param {number} particleCount - The number of particles to create. - * - * @return {this} This Particle Emitter. - */ - reserve: function (particleCount) - { - var dead = this.dead; - - for (var i = 0; i < particleCount; i++) - { - dead.push(new this.particleClass(this)); - } - - return this; - }, - - /** - * Gets the number of active (in-use) particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles with `active=true`. - */ - getAliveParticleCount: function () - { - return this.alive.length; - }, - - /** - * Gets the number of inactive (available) particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles with `active=false`. - */ - getDeadParticleCount: function () - { - return this.dead.length; - }, - - /** - * Gets the total number of particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles, including both alive and dead. - */ - getParticleCount: function () - { - return this.getAliveParticleCount() + this.getDeadParticleCount(); - }, - - /** - * Whether this emitter is at its limit (if set). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit - * @since 3.0.0 - * - * @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level. - */ - atLimit: function () - { - return (this.maxParticles > 0 && this.getParticleCount() === this.maxParticles); - }, - - /** - * Sets a function to call for each newly emitted particle. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} [context] - The calling context. - * - * @return {this} This Particle Emitter. - */ - onParticleEmit: function (callback, context) - { - if (callback === undefined) - { - // Clear any previously set callback - this.emitCallback = null; - this.emitCallbackScope = null; - } - else if (typeof callback === 'function') - { - this.emitCallback = callback; - - if (context) - { - this.emitCallbackScope = context; - } - } - - return this; - }, - - /** - * Sets a function to call for each particle death. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleDeathCallback} callback - The function. - * @param {*} [context] - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - onParticleDeath: function (callback, context) - { - if (callback === undefined) - { - // Clear any previously set callback - this.deathCallback = null; - this.deathCallbackScope = null; - } - else if (typeof callback === 'function') - { - this.deathCallback = callback; - - if (context) - { - this.deathCallbackScope = context; - } - } - - return this; - }, - - /** - * Deactivates every particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - killAll: function () - { - var dead = this.dead; - var alive = this.alive; - - while (alive.length > 0) - { - dead.push(alive.pop()); - } - - return this; - }, - - /** - * Calls a function for each active particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} context - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - forEachAlive: function (callback, context) - { - var alive = this.alive; - var length = alive.length; - - for (var index = 0; index < length; ++index) - { - // Sends the Particle and the Emitter - callback.call(context, alive[index], this); - } - - return this; - }, - - /** - * Calls a function for each inactive particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} context - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - forEachDead: function (callback, context) - { - var dead = this.dead; - var length = dead.length; - - for (var index = 0; index < length; ++index) - { - // Sends the Particle and the Emitter - callback.call(context, dead[index], this); - } - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on} the emitter and resets the flow counter. - * - * If this emitter is in flow mode (frequency >= 0; the default), the particle flow will start (or restart). - * - * If this emitter is in explode mode (frequency = -1), nothing will happen. - * Use {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} or {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} instead. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#start - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - start: function () - { - this.on = true; - - this._counter = 0; - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stop - * @since 3.11.0 - * - * @return {this} This Particle Emitter. - */ - stop: function () - { - this.on = false; - - return this; - }, - - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#pause - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - pause: function () - { - this.active = false; - - return this; - }, - - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#resume - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - resume: function () - { - this.active = true; - - return this; - }, - - /** - * Removes the emitter from its manager and the scene. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#remove - * @since 3.22.0 - * - * @return {this} This Particle Emitter. - */ - remove: function () - { - this.manager.removeEmitter(this); - - return this; - }, - - /** - * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - depthSort: function () - { - StableSort(this.alive, this.depthSortCallback); - - return this; - }, - - /** - * Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow. - * - * To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#flow - * @since 3.0.0 - * - * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [count=1] - The number of particles to emit at each flow cycle. - * - * @return {this} This Particle Emitter. - */ - flow: function (frequency, count) - { - if (count === undefined) { count = 1; } - - this.frequency = frequency; - - this.quantity.onChange(count); - - return this.start(); - }, - - /** - * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#explode - * @since 3.0.0 - * - * @param {number} count - The amount of Particles to emit. - * @param {number} x - The x coordinate to emit the Particles from. - * @param {number} y - The y coordinate to emit the Particles from. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - */ - explode: function (count, x, y) - { - this.frequency = -1; - - return this.emitParticle(count, x, y); - }, - - /** - * Emits particles at a given position (or the emitter's current position). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt - * @since 3.0.0 - * - * @param {number} [x=this.x] - The x coordinate to emit the Particles from. - * @param {number} [y=this.x] - The y coordinate to emit the Particles from. - * @param {number} [count=this.quantity] - The number of Particles to emit. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - */ - emitParticleAt: function (x, y, count) - { - return this.emitParticle(count, x, y); - }, - - /** - * Emits particles at a given position (or the emitter's current position). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle - * @since 3.0.0 - * - * @param {number} [count=this.quantity] - The number of Particles to emit. - * @param {number} [x=this.x] - The x coordinate to emit the Particles from. - * @param {number} [y=this.x] - The y coordinate to emit the Particles from. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - * - * @see Phaser.GameObjects.Particles.Particle#fire - */ - emitParticle: function (count, x, y) - { - if (this.atLimit()) - { - return; - } - - if (count === undefined) - { - count = this.quantity.onEmit(); - } - - var dead = this.dead; - - var followX = (this.follow) ? this.follow.x + this.followOffset.x : x; - var followY = (this.follow) ? this.follow.y + this.followOffset.y : y; - - for (var i = 0; i < count; i++) - { - var particle = dead.pop(); - - if (!particle) - { - particle = new this.particleClass(this); - } - - particle.fire(followX, followY); - - if (this.particleBringToTop) - { - this.alive.push(particle); - } - else - { - this.alive.unshift(particle); - } - - if (this.emitCallback) - { - this.emitCallback.call(this.emitCallbackScope, particle, this); - } - - if (this.atLimit()) - { - break; - } - } - - return particle; - }, - - /** - * Updates this emitter and its particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - preUpdate: function (time, delta) - { - // Scale the delta - delta *= this.timeScale; - - var step = (delta / 1000); - - if (this.trackVisible) - { - this.visible = this.follow.visible; - } - - // Any particle processors? - var processors = this.manager.getProcessors(); - - var particles = this.alive; - var dead = this.dead; - - var i = 0; - var rip = []; - var length = particles.length; - - for (i = 0; i < length; i++) - { - var particle = particles[i]; - - // update returns `true` if the particle is now dead (lifeCurrent <= 0) - if (particle.update(delta, step, processors)) - { - rip.push({ index: i, particle: particle }); - } - } - - // Move dead particles to the dead array - length = rip.length; - - if (length > 0) - { - var deathCallback = this.deathCallback; - var deathCallbackScope = this.deathCallbackScope; - - for (i = length - 1; i >= 0; i--) - { - var entry = rip[i]; - - // Remove from particles array - particles.splice(entry.index, 1); - - // Add to dead array - dead.push(entry.particle); - - // Callback - if (deathCallback) - { - deathCallback.call(deathCallbackScope, entry.particle); - } - - entry.particle.resetPosition(); - } - } - - if (!this.on) - { - return; - } - - if (this.frequency === 0) - { - this.emitParticle(); - } - else if (this.frequency > 0) - { - this._counter -= delta; - - if (this._counter <= 0) - { - this.emitParticle(); - - // counter = frequency - remained from previous delta - this._counter = (this.frequency - Math.abs(this._counter)); - } - } - }, - - /** - * Calculates the difference of two particles, for sorting them by depth. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback - * @since 3.0.0 - * - * @param {object} a - The first particle. - * @param {object} b - The second particle. - * - * @return {number} The difference of a and b's y coordinates. - */ - depthSortCallback: function (a, b) - { - return a.y - b.y; - } - -}); - -module.exports = ParticleEmitter; - - -/***/ }), -/* 431 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A Death Zone. - * - * A Death Zone is a special type of zone that will kill a Particle as soon as it either enters, or leaves, the zone. - * - * The zone consists of a `source` which could be a Geometric shape, such as a Rectangle or Ellipse, or your own - * object as long as it includes a `contains` method for which the Particles can be tested against. - * - * @class DeathZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.DeathZoneSource} source - An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. - * @param {boolean} killOnEnter - Should the Particle be killed when it enters the zone? `true` or leaves it? `false` - */ -var DeathZone = new Class({ - - initialize: - - function DeathZone (source, killOnEnter) - { - /** - * An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. - * This could be a Geometry shape, such as `Phaser.Geom.Circle`, or your own custom object. - * - * @name Phaser.GameObjects.Particles.Zones.DeathZone#source - * @type {Phaser.Types.GameObjects.Particles.DeathZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * Set to `true` if the Particle should be killed if it enters this zone. - * Set to `false` to kill the Particle if it leaves this zone. - * - * @name Phaser.GameObjects.Particles.Zones.DeathZone#killOnEnter - * @type {boolean} - * @since 3.0.0 - */ - this.killOnEnter = killOnEnter; - }, - - /** - * Checks if the given Particle will be killed or not by this zone. - * - * @method Phaser.GameObjects.Particles.Zones.DeathZone#willKill - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to be checked against this zone. - * - * @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`. - */ - willKill: function (particle) - { - var withinZone = this.source.contains(particle.x, particle.y); - - return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); - } - -}); - -module.exports = DeathZone; - - -/***/ }), -/* 432 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A zone that places particles on a shape's edges. - * - * @class EdgeZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * @param {number} quantity - The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - * @param {number} stepRate - The distance between each particle. When set, `quantity` is implied and should be set to 0. - * @param {boolean} [yoyo=false] - Whether particles are placed from start to end and then end to start. - * @param {boolean} [seamless=true] - Whether one endpoint will be removed if it's identical to the other. - */ -var EdgeZone = new Class({ - - initialize: - - function EdgeZone (source, quantity, stepRate, yoyo, seamless) - { - if (yoyo === undefined) { yoyo = false; } - if (seamless === undefined) { seamless = true; } - - /** - * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source - * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * The points placed on the source edge. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points - * @type {Phaser.Geom.Point[]} - * @default [] - * @since 3.0.0 - */ - this.points = []; - - /** - * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#quantity - * @type {number} - * @since 3.0.0 - */ - this.quantity = quantity; - - /** - * The distance between each particle. When set, `quantity` is implied and should be set to 0. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#stepRate - * @type {number} - * @since 3.0.0 - */ - this.stepRate = stepRate; - - /** - * Whether particles are placed from start to end and then end to start. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#yoyo - * @type {boolean} - * @since 3.0.0 - */ - this.yoyo = yoyo; - - /** - * The counter used for iterating the EdgeZone's points. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.counter = -1; - - /** - * Whether one endpoint will be removed if it's identical to the other. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless - * @type {boolean} - * @since 3.0.0 - */ - this.seamless = seamless; - - /** - * An internal count of the points belonging to this EdgeZone. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_length - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._length = 0; - - /** - * An internal value used to keep track of the current iteration direction for the EdgeZone's points. - * - * 0 = forwards, 1 = backwards - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_direction - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._direction = 0; - - this.updateSource(); - }, - - /** - * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's - * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. - * - * Also updates internal properties. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource - * @since 3.0.0 - * - * @return {this} This Edge Zone. - */ - updateSource: function () - { - this.points = this.source.getPoints(this.quantity, this.stepRate); - - // Remove ends? - if (this.seamless) - { - var a = this.points[0]; - var b = this.points[this.points.length - 1]; - - if (a.x === b.x && a.y === b.y) - { - this.points.pop(); - } - } - - var oldLength = this._length; - - this._length = this.points.length; - - // Adjust counter if we now have less points than before - if (this._length < oldLength && this.counter > this._length) - { - this.counter = this._length - 1; - } - - return this; - }, - - /** - * Change the source of the EdgeZone. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * - * @return {this} This Edge Zone. - */ - changeSource: function (source) - { - this.source = source; - - return this.updateSource(); - }, - - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. - */ - getPoint: function (particle) - { - if (this._direction === 0) - { - this.counter++; - - if (this.counter >= this._length) - { - if (this.yoyo) - { - this._direction = 1; - this.counter = this._length - 1; - } - else - { - this.counter = 0; - } - } - } - else - { - this.counter--; - - if (this.counter === -1) - { - if (this.yoyo) - { - this._direction = 0; - this.counter = 0; - } - else - { - this.counter = this._length - 1; - } - } - } - - var point = this.points[this.counter]; - - if (point) - { - particle.x = point.x; - particle.y = point.y; - } - } - -}); - -module.exports = EdgeZone; - - -/***/ }), -/* 433 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Verifies that an object contains at least one of the requested keys - * - * @function Phaser.Utils.Objects.HasAny - * @since 3.0.0 - * - * @param {object} source - an object on which to check for key existence - * @param {string[]} keys - an array of keys to search the object for - * - * @return {boolean} true if the source object contains at least one of the keys, false otherwise - */ -var HasAny = function (source, keys) -{ - for (var i = 0; i < keys.length; i++) - { - if (source.hasOwnProperty(keys[i])) - { - return true; - } - } - - return false; -}; - -module.exports = HasAny; - - -/***/ }), -/* 434 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A zone that places particles randomly within a shapes area. - * - * @class RandomZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.RandomZoneSource} source - An object instance with a `getRandomPoint(point)` method. - */ -var RandomZone = new Class({ - - initialize: - - function RandomZone (source) - { - /** - * An object instance with a `getRandomPoint(point)` method. - * - * @name Phaser.GameObjects.Particles.Zones.RandomZone#source - * @type {Phaser.Types.GameObjects.Particles.RandomZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * Internal calculation vector. - * - * @name Phaser.GameObjects.Particles.Zones.RandomZone#_tempVec - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tempVec = new Vector2(); - }, - - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * - * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. - */ - getPoint: function (particle) - { - var vec = this._tempVec; - - this.source.getRandomPoint(vec); - - particle.x = vec.x; - particle.y = vec.y; - } - -}); - -module.exports = RandomZone; - - -/***/ }), -/* 435 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var Sprite = __webpack_require__(73); - -/** - * @classdesc - * A PathFollower Game Object. - * - * A PathFollower is a Sprite Game Object with some extra helpers to allow it to follow a Path automatically. - * - * Anything you can do with a standard Sprite can be done with this PathFollower, such as animate it, tint it, - * scale it and so on. - * - * PathFollowers are bound to a single Path at any one time and can traverse the length of the Path, from start - * to finish, forwards or backwards, or from any given point on the Path to its end. They can optionally rotate - * to face the direction of the path, be offset from the path coordinates or rotate independently of the Path. - * - * @class PathFollower - * @extends Phaser.GameObjects.Sprite - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.PathFollower - * - * @param {Phaser.Scene} scene - The Scene to which this PathFollower belongs. - * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. - * @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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - */ -var PathFollower = new Class({ - - Extends: Sprite, - - Mixins: [ - Components.PathFollower - ], - - initialize: - - function PathFollower (scene, path, x, y, texture, frame) - { - Sprite.call(this, scene, x, y, texture, frame); - - this.path = path; - }, - - /** - * 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.PathFollower#preUpdate - * @protected - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - preUpdate: function (time, delta) - { - this.anims.update(time, delta); - this.pathUpdate(time); - } - -}); - -module.exports = PathFollower; - - -/***/ }), -/* 436 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns an object containing dimensions of the Text object. - * - * @function Phaser.GameObjects.GetTextSize - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Text} text - The Text object to calculate the size from. - * @param {Phaser.Types.GameObjects.Text.TextMetrics} size - The Text metrics to use when calculating the size. - * @param {string[]} lines - The lines of text to calculate the size from. - * - * @return {Phaser.Types.GameObjects.Text.GetTextSizeObject} An object containing dimensions of the Text object. - */ -var GetTextSize = function (text, size, lines) -{ - var canvas = text.canvas; - var context = text.context; - var style = text.style; - - var lineWidths = []; - var maxLineWidth = 0; - var drawnLines = lines.length; - - if (style.maxLines > 0 && style.maxLines < lines.length) - { - drawnLines = style.maxLines; - } - - style.syncFont(canvas, context); - - // Text Width - - for (var i = 0; i < drawnLines; i++) - { - var lineWidth = style.strokeThickness; - - lineWidth += context.measureText(lines[i]).width; - - // Adjust for wrapped text - if (style.wordWrap) - { - lineWidth -= context.measureText(' ').width; - } - - lineWidths[i] = Math.ceil(lineWidth); - maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); - } - - // Text Height - - var lineHeight = size.fontSize + style.strokeThickness; - var height = lineHeight * drawnLines; - var lineSpacing = text.lineSpacing; - - // Adjust for line spacing - if (drawnLines > 1) - { - height += lineSpacing * (drawnLines - 1); - } - - return { - width: maxLineWidth, - height: height, - lines: drawnLines, - lineWidths: lineWidths, - lineSpacing: lineSpacing, - lineHeight: lineHeight - }; -}; - -module.exports = GetTextSize; - - -/***/ }), -/* 437 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetAdvancedValue = __webpack_require__(13); -var GetValue = __webpack_require__(6); -var MeasureText = __webpack_require__(438); - -// Key: [ Object Key, Default Value ] - -var propertyMap = { - fontFamily: [ 'fontFamily', 'Courier' ], - fontSize: [ 'fontSize', '16px' ], - fontStyle: [ 'fontStyle', '' ], - backgroundColor: [ 'backgroundColor', null ], - color: [ 'color', '#fff' ], - stroke: [ 'stroke', '#fff' ], - strokeThickness: [ 'strokeThickness', 0 ], - shadowOffsetX: [ 'shadow.offsetX', 0 ], - shadowOffsetY: [ 'shadow.offsetY', 0 ], - shadowColor: [ 'shadow.color', '#000' ], - shadowBlur: [ 'shadow.blur', 0 ], - shadowStroke: [ 'shadow.stroke', false ], - shadowFill: [ 'shadow.fill', false ], - align: [ 'align', 'left' ], - maxLines: [ 'maxLines', 0 ], - fixedWidth: [ 'fixedWidth', 0 ], - fixedHeight: [ 'fixedHeight', 0 ], - resolution: [ 'resolution', 0 ], - rtl: [ 'rtl', false ], - testString: [ 'testString', '|MÉqgy' ], - baselineX: [ 'baselineX', 1.2 ], - baselineY: [ 'baselineY', 1.4 ], - wordWrapWidth: [ 'wordWrap.width', null ], - wordWrapCallback: [ 'wordWrap.callback', null ], - wordWrapCallbackScope: [ 'wordWrap.callbackScope', null ], - wordWrapUseAdvanced: [ 'wordWrap.useAdvancedWrap', false ] -}; - -/** - * @classdesc - * A TextStyle class manages all of the style settings for a Text object. - * - * Text Game Objects create a TextStyle instance automatically, which is - * accessed via the `Text.style` property. You do not normally need to - * instantiate one yourself. - * - * @class TextStyle - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Text} text - The Text object that this TextStyle is styling. - * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. - */ -var TextStyle = new Class({ - - initialize: - - function TextStyle (text, style) - { - /** - * The Text object that this TextStyle is styling. - * - * @name Phaser.GameObjects.TextStyle#parent - * @type {Phaser.GameObjects.Text} - * @since 3.0.0 - */ - this.parent = text; - - /** - * The font family. - * - * @name Phaser.GameObjects.TextStyle#fontFamily - * @type {string} - * @default 'Courier' - * @since 3.0.0 - */ - this.fontFamily; - - /** - * The font size. - * - * @name Phaser.GameObjects.TextStyle#fontSize - * @type {string} - * @default '16px' - * @since 3.0.0 - */ - this.fontSize; - - /** - * The font style. - * - * @name Phaser.GameObjects.TextStyle#fontStyle - * @type {string} - * @since 3.0.0 - */ - this.fontStyle; - - /** - * The background color. - * - * @name Phaser.GameObjects.TextStyle#backgroundColor - * @type {string} - * @since 3.0.0 - */ - this.backgroundColor; - - /** - * The text fill color. - * - * @name Phaser.GameObjects.TextStyle#color - * @type {string} - * @default '#fff' - * @since 3.0.0 - */ - this.color; - - /** - * The text stroke color. - * - * @name Phaser.GameObjects.TextStyle#stroke - * @type {string} - * @default '#fff' - * @since 3.0.0 - */ - this.stroke; - - /** - * The text stroke thickness. - * - * @name Phaser.GameObjects.TextStyle#strokeThickness - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.strokeThickness; - - /** - * The horizontal shadow offset. - * - * @name Phaser.GameObjects.TextStyle#shadowOffsetX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowOffsetX; - - /** - * The vertical shadow offset. - * - * @name Phaser.GameObjects.TextStyle#shadowOffsetY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowOffsetY; - - /** - * The shadow color. - * - * @name Phaser.GameObjects.TextStyle#shadowColor - * @type {string} - * @default '#000' - * @since 3.0.0 - */ - this.shadowColor; - - /** - * The shadow blur radius. - * - * @name Phaser.GameObjects.TextStyle#shadowBlur - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowBlur; - - /** - * Whether shadow stroke is enabled or not. - * - * @name Phaser.GameObjects.TextStyle#shadowStroke - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shadowStroke; - - /** - * Whether shadow fill is enabled or not. - * - * @name Phaser.GameObjects.TextStyle#shadowFill - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shadowFill; - - /** - * The text alignment. - * - * @name Phaser.GameObjects.TextStyle#align - * @type {string} - * @default 'left' - * @since 3.0.0 - */ - this.align; - - /** - * The maximum number of lines to draw. - * - * @name Phaser.GameObjects.TextStyle#maxLines - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxLines; - - /** - * The fixed width of the text. - * - * `0` means no fixed with. - * - * @name Phaser.GameObjects.TextStyle#fixedWidth - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.fixedWidth; - - /** - * The fixed height of the text. - * - * `0` means no fixed height. - * - * @name Phaser.GameObjects.TextStyle#fixedHeight - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.fixedHeight; - - /** - * The resolution the text is rendered to its internal canvas at. - * The default is 0, which means it will use the resolution set in the Game Config. - * - * @name Phaser.GameObjects.TextStyle#resolution - * @type {number} - * @default 0 - * @since 3.12.0 - */ - this.resolution; - - /** - * Whether the text should render right to left. - * - * @name Phaser.GameObjects.TextStyle#rtl - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.rtl; - - /** - * The test string to use when measuring the font. - * - * @name Phaser.GameObjects.TextStyle#testString - * @type {string} - * @default '|MÉqgy' - * @since 3.0.0 - */ - this.testString; - - /** - * The amount of horizontal padding added to the width of the text when calculating the font metrics. - * - * @name Phaser.GameObjects.TextStyle#baselineX - * @type {number} - * @default 1.2 - * @since 3.3.0 - */ - this.baselineX; - - /** - * The amount of vertical padding added to the height of the text when calculating the font metrics. - * - * @name Phaser.GameObjects.TextStyle#baselineY - * @type {number} - * @default 1.4 - * @since 3.3.0 - */ - this.baselineY; - - /** - * The maximum width of a line of text in pixels. Null means no line wrapping. Setting this - * property directly will not re-run the word wrapping algorithm. To change the width and - * re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapWidth - * @type {number | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapWidth; - - /** - * A custom function that will be responsible for wrapping the text. It will receive two - * arguments: text (the string to wrap), textObject (this Text instance). It should return - * the wrapped lines either as an array of lines or as a string with newline characters in - * place to indicate where breaks should happen. Setting this directly will not re-run the - * word wrapping algorithm. To change the callback and re-wrap, use - * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapCallback - * @type {TextStyleWordWrapCallback | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapCallback; - - /** - * The scope that will be applied when the wordWrapCallback is invoked. Setting this directly will not re-run the - * word wrapping algorithm. To change the callback and re-wrap, use - * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapCallbackScope - * @type {object | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapCallbackScope; - - /** - * Whether or not to use the advanced wrapping algorithm. If true, spaces are collapsed and - * whitespace is trimmed from lines. If false, spaces and whitespace are left as is. Setting - * this property directly will not re-run the word wrapping algorithm. To change the - * advanced setting and re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapUseAdvanced - * @type {boolean} - * @default false - * @since 3.24.0 - */ - this.wordWrapUseAdvanced; - - /** - * The font style, size and family. - * - * @name Phaser.GameObjects.TextStyle#_font - * @type {string} - * @private - * @since 3.0.0 - */ - this._font; - - // Set to defaults + user style - this.setStyle(style, false, true); - - var metrics = GetValue(style, 'metrics', false); - - // Provide optional TextMetrics in the style object to avoid the canvas look-up / scanning - // Doing this is reset if you then change the font of this TextStyle after creation - if (metrics) - { - this.metrics = { - ascent: GetValue(metrics, 'ascent', 0), - descent: GetValue(metrics, 'descent', 0), - fontSize: GetValue(metrics, 'fontSize', 0) - }; - } - else - { - this.metrics = MeasureText(this); - } - }, - - /** - * Set the text style. - * - * @example - * text.setStyle({ - * fontSize: '64px', - * fontFamily: 'Arial', - * color: '#ffffff', - * align: 'center', - * backgroundColor: '#ff00ff' - * }); - * - * @method Phaser.GameObjects.TextStyle#setStyle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. - * @param {boolean} [updateText=true] - Whether to update the text immediately. - * @param {boolean} [setDefaults=false] - Use the default values is not set, or the local values. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setStyle: function (style, updateText, setDefaults) - { - if (updateText === undefined) { updateText = true; } - if (setDefaults === undefined) { setDefaults = false; } - - // Avoid type mutation - // eslint-disable-next-line no-prototype-builtins - if (style && style.hasOwnProperty('fontSize') && typeof style.fontSize === 'number') - { - style.fontSize = style.fontSize.toString() + 'px'; - } - - for (var key in propertyMap) - { - var value = (setDefaults) ? propertyMap[key][1] : this[key]; - - if (key === 'wordWrapCallback' || key === 'wordWrapCallbackScope') - { - // Callback & scope should be set without processing the values - this[key] = GetValue(style, propertyMap[key][0], value); - } - else - { - this[key] = GetAdvancedValue(style, propertyMap[key][0], value); - } - } - - // Allow for 'font' override - var font = GetValue(style, 'font', null); - - if (font !== null) - { - this.setFont(font, false); - } - - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - - // Allow for 'fill' to be used in place of 'color' - var fill = GetValue(style, 'fill', null); - - if (fill !== null) - { - this.color = fill; - } - - if (updateText) - { - return this.update(true); - } - else - { - return this.parent; - } - }, - - /** - * Synchronize the font settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncFont - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The Canvas Element. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - */ - syncFont: function (canvas, context) - { - context.font = this._font; - }, - - /** - * Synchronize the text style settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncStyle - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The Canvas Element. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - */ - syncStyle: function (canvas, context) - { - context.textBaseline = 'alphabetic'; - - context.fillStyle = this.color; - context.strokeStyle = this.stroke; - - context.lineWidth = this.strokeThickness; - context.lineCap = 'round'; - context.lineJoin = 'round'; - }, - - /** - * Synchronize the shadow settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncShadow - * @since 3.0.0 - * - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - * @param {boolean} enabled - Whether shadows are enabled or not. - */ - syncShadow: function (context, enabled) - { - if (enabled) - { - context.shadowOffsetX = this.shadowOffsetX; - context.shadowOffsetY = this.shadowOffsetY; - context.shadowColor = this.shadowColor; - context.shadowBlur = this.shadowBlur; - } - else - { - context.shadowOffsetX = 0; - context.shadowOffsetY = 0; - context.shadowColor = 0; - context.shadowBlur = 0; - } - }, - - /** - * Update the style settings for the parent Text object. - * - * @method Phaser.GameObjects.TextStyle#update - * @since 3.0.0 - * - * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - update: function (recalculateMetrics) - { - if (recalculateMetrics) - { - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - - this.metrics = MeasureText(this); - } - - return this.parent.updateText(); - }, - - /** - * Set the font. - * - * If a string is given, the font family is set. - * - * If an object is given, the `fontFamily`, `fontSize` and `fontStyle` - * properties of that object are set. - * - * @method Phaser.GameObjects.TextStyle#setFont - * @since 3.0.0 - * - * @param {(string|object)} font - The font family or font settings to set. - * @param {boolean} [updateText=true] - Whether to update the text immediately. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFont: function (font, updateText) - { - if (updateText === undefined) { updateText = true; } - - var fontFamily = font; - var fontSize = ''; - var fontStyle = ''; - - if (typeof font !== 'string') - { - fontFamily = GetValue(font, 'fontFamily', 'Courier'); - fontSize = GetValue(font, 'fontSize', '16px'); - fontStyle = GetValue(font, 'fontStyle', ''); - } - else - { - var fontSplit = font.split(' '); - - var i = 0; - - fontStyle = (fontSplit.length > 2) ? fontSplit[i++] : ''; - fontSize = fontSplit[i++] || '16px'; - fontFamily = fontSplit[i++] || 'Courier'; - } - - if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) - { - this.fontFamily = fontFamily; - this.fontSize = fontSize; - this.fontStyle = fontStyle; - - if (updateText) - { - this.update(true); - } - } - - return this.parent; - }, - - /** - * Set the font family. - * - * @method Phaser.GameObjects.TextStyle#setFontFamily - * @since 3.0.0 - * - * @param {string} family - The font family. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontFamily: function (family) - { - if (this.fontFamily !== family) - { - this.fontFamily = family; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the font style. - * - * @method Phaser.GameObjects.TextStyle#setFontStyle - * @since 3.0.0 - * - * @param {string} style - The font style. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontStyle: function (style) - { - if (this.fontStyle !== style) - { - this.fontStyle = style; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the font size. - * - * @method Phaser.GameObjects.TextStyle#setFontSize - * @since 3.0.0 - * - * @param {(number|string)} size - The font size. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontSize: function (size) - { - if (typeof size === 'number') - { - size = size.toString() + 'px'; - } - - if (this.fontSize !== size) - { - this.fontSize = size; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the test string to use when measuring the font. - * - * @method Phaser.GameObjects.TextStyle#setTestString - * @since 3.0.0 - * - * @param {string} string - The test string to use when measuring the font. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setTestString: function (string) - { - this.testString = string; - - return this.update(true); - }, - - /** - * Set a fixed width and height for the text. - * - * Pass in `0` for either of these parameters to disable fixed width or height respectively. - * - * @method Phaser.GameObjects.TextStyle#setFixedSize - * @since 3.0.0 - * - * @param {number} width - The fixed width to set. - * @param {number} height - The fixed height to set. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFixedSize: function (width, height) - { - this.fixedWidth = width; - this.fixedHeight = height; - - if (width) - { - this.parent.width = width; - } - - if (height) - { - this.parent.height = height; - } - - return this.update(false); - }, - - /** - * Set the background color. - * - * @method Phaser.GameObjects.TextStyle#setBackgroundColor - * @since 3.0.0 - * - * @param {string} color - The background color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setBackgroundColor: function (color) - { - this.backgroundColor = color; - - return this.update(false); - }, - - /** - * Set the text fill color. - * - * @method Phaser.GameObjects.TextStyle#setFill - * @since 3.0.0 - * - * @param {string} color - The text fill color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFill: function (color) - { - this.color = color; - - return this.update(false); - }, - - /** - * Set the text fill color. - * - * @method Phaser.GameObjects.TextStyle#setColor - * @since 3.0.0 - * - * @param {string} color - The text fill color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setColor: function (color) - { - this.color = color; - - return this.update(false); - }, - - /** - * Set the resolution used by the Text object. - * - * By default it will be set to match the resolution set in the Game Config, - * but you can override it via this method. It allows for much clearer text on High DPI devices, - * at the cost of memory because it uses larger internal Canvas textures for the Text. - * - * Please use with caution, as the more high res Text you have, the more memory it uses up. - * - * @method Phaser.GameObjects.TextStyle#setResolution - * @since 3.12.0 - * - * @param {number} value - The resolution for this Text object to use. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setResolution: function (value) - { - this.resolution = value; - - return this.update(false); - }, - - /** - * Set the stroke settings. - * - * @method Phaser.GameObjects.TextStyle#setStroke - * @since 3.0.0 - * - * @param {string} color - The stroke color. - * @param {number} thickness - The stroke thickness. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setStroke: function (color, thickness) - { - if (thickness === undefined) { thickness = this.strokeThickness; } - - if (color === undefined && this.strokeThickness !== 0) - { - // Reset the stroke to zero (disabling it) - this.strokeThickness = 0; - - this.update(true); - } - else if (this.stroke !== color || this.strokeThickness !== thickness) - { - this.stroke = color; - this.strokeThickness = thickness; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the shadow settings. - * - * Calling this method always re-measures the parent Text object, - * so only call it when you actually change the shadow settings. - * - * @method Phaser.GameObjects.TextStyle#setShadow - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal shadow offset. - * @param {number} [y=0] - The vertical shadow offset. - * @param {string} [color='#000'] - The shadow color. - * @param {number} [blur=0] - The shadow blur radius. - * @param {boolean} [shadowStroke=false] - Whether to stroke the shadow. - * @param {boolean} [shadowFill=true] - Whether to fill the shadow. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadow: function (x, y, color, blur, shadowStroke, shadowFill) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (color === undefined) { color = '#000'; } - if (blur === undefined) { blur = 0; } - if (shadowStroke === undefined) { shadowStroke = false; } - if (shadowFill === undefined) { shadowFill = true; } - - this.shadowOffsetX = x; - this.shadowOffsetY = y; - this.shadowColor = color; - this.shadowBlur = blur; - this.shadowStroke = shadowStroke; - this.shadowFill = shadowFill; - - return this.update(false); - }, - - /** - * Set the shadow offset. - * - * @method Phaser.GameObjects.TextStyle#setShadowOffset - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal shadow offset. - * @param {number} [y=0] - The vertical shadow offset. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowOffset: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.shadowOffsetX = x; - this.shadowOffsetY = y; - - return this.update(false); - }, - - /** - * Set the shadow color. - * - * @method Phaser.GameObjects.TextStyle#setShadowColor - * @since 3.0.0 - * - * @param {string} [color='#000'] - The shadow color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowColor: function (color) - { - if (color === undefined) { color = '#000'; } - - this.shadowColor = color; - - return this.update(false); - }, - - /** - * Set the shadow blur radius. - * - * @method Phaser.GameObjects.TextStyle#setShadowBlur - * @since 3.0.0 - * - * @param {number} [blur=0] - The shadow blur radius. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowBlur: function (blur) - { - if (blur === undefined) { blur = 0; } - - this.shadowBlur = blur; - - return this.update(false); - }, - - /** - * Enable or disable shadow stroke. - * - * @method Phaser.GameObjects.TextStyle#setShadowStroke - * @since 3.0.0 - * - * @param {boolean} enabled - Whether shadow stroke is enabled or not. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowStroke: function (enabled) - { - this.shadowStroke = enabled; - - return this.update(false); - }, - - /** - * Enable or disable shadow fill. - * - * @method Phaser.GameObjects.TextStyle#setShadowFill - * @since 3.0.0 - * - * @param {boolean} enabled - Whether shadow fill is enabled or not. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowFill: function (enabled) - { - this.shadowFill = enabled; - - return this.update(false); - }, - - /** - * Set the width (in pixels) to use for wrapping lines. - * - * Pass in null to remove wrapping by width. - * - * @method Phaser.GameObjects.TextStyle#setWordWrapWidth - * @since 3.0.0 - * - * @param {number} width - The maximum width of a line in pixels. Set to null to remove wrapping. - * @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping - * algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false, - * spaces and whitespace are left as is. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setWordWrapWidth: function (width, useAdvancedWrap) - { - if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } - - this.wordWrapWidth = width; - this.wordWrapUseAdvanced = useAdvancedWrap; - - return this.update(false); - }, - - /** - * Set a custom callback for wrapping lines. - * - * Pass in null to remove wrapping by callback. - * - * @method Phaser.GameObjects.TextStyle#setWordWrapCallback - * @since 3.0.0 - * - * @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the - * text. It will receive two arguments: text (the string to wrap), textObject (this Text - * instance). It should return the wrapped lines either as an array of lines or as a string with - * newline characters in place to indicate where breaks should happen. - * @param {object} [scope=null] - The scope that will be applied when the callback is invoked. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setWordWrapCallback: function (callback, scope) - { - if (scope === undefined) { scope = null; } - - this.wordWrapCallback = callback; - this.wordWrapCallbackScope = scope; - - return this.update(false); - }, - - /** - * Set the alignment of the text in this Text object. - * - * The argument can be one of: `left`, `right`, `center` or `justify`. - * - * Alignment only works if the Text object has more than one line of text. - * - * @method Phaser.GameObjects.TextStyle#setAlign - * @since 3.0.0 - * - * @param {string} [align='left'] - The text alignment for multi-line text. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setAlign: function (align) - { - if (align === undefined) { align = 'left'; } - - this.align = align; - - return this.update(false); - }, - - /** - * Set the maximum number of lines to draw. - * - * @method Phaser.GameObjects.TextStyle#setMaxLines - * @since 3.0.0 - * - * @param {number} [max=0] - The maximum number of lines to draw. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setMaxLines: function (max) - { - if (max === undefined) { max = 0; } - - this.maxLines = max; - - return this.update(false); - }, - - /** - * Get the current text metrics. - * - * @method Phaser.GameObjects.TextStyle#getTextMetrics - * @since 3.0.0 - * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. - */ - getTextMetrics: function () - { - var metrics = this.metrics; - - return { - ascent: metrics.ascent, - descent: metrics.descent, - fontSize: metrics.fontSize - }; - }, - - /** - * Build a JSON representation of this Text Style. - * - * @method Phaser.GameObjects.TextStyle#toJSON - * @since 3.0.0 - * - * @return {object} A JSON representation of this Text Style. - */ - toJSON: function () - { - var output = {}; - - for (var key in propertyMap) - { - output[key] = this[key]; - } - - output.metrics = this.getTextMetrics(); - - return output; - }, - - /** - * Destroy this Text Style. - * - * @method Phaser.GameObjects.TextStyle#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.parent = undefined; - } - -}); - -module.exports = TextStyle; - - -/***/ }), -/* 438 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); - -/** - * Calculates the ascent, descent and fontSize of a given font style. - * - * @function Phaser.GameObjects.MeasureText - * @since 3.0.0 - * - * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. - * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. - */ -var MeasureText = function (textStyle) -{ - var canvas = CanvasPool.create(this); - var context = canvas.getContext('2d'); - - textStyle.syncFont(canvas, context); - - var metrics = context.measureText(textStyle.testString); - - if (metrics.hasOwnProperty('actualBoundingBoxAscent')) - { - var ascent = metrics.actualBoundingBoxAscent; - var descent = metrics.actualBoundingBoxDescent; - - CanvasPool.remove(canvas); - - return { - ascent: ascent, - descent: descent, - fontSize: ascent + descent - }; - } - - var width = Math.ceil(metrics.width * textStyle.baselineX); - var baseline = width; - var height = 2 * baseline; - - baseline = baseline * textStyle.baselineY | 0; - - canvas.width = width; - canvas.height = height; - - context.fillStyle = '#f00'; - context.fillRect(0, 0, width, height); - - context.font = textStyle._font; - - context.textBaseline = 'alphabetic'; - context.fillStyle = '#000'; - context.fillText(textStyle.testString, 0, baseline); - - var output = { - ascent: 0, - descent: 0, - fontSize: 0 - }; - - if (!context.getImageData(0, 0, width, height)) - { - output.ascent = baseline; - output.descent = baseline + 6; - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; - } - - var imagedata = context.getImageData(0, 0, width, height).data; - var pixels = imagedata.length; - var line = width * 4; - var i; - var j; - var idx = 0; - var stop = false; - - // ascent. scan from top to bottom until we find a non red pixel - for (i = 0; i < baseline; i++) - { - for (j = 0; j < line; j += 4) - { - if (imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx += line; - } - else - { - break; - } - } - - output.ascent = baseline - i; - - idx = pixels - line; - stop = false; - - // descent. scan from bottom to top until we find a non red pixel - for (i = height; i > baseline; i--) - { - for (j = 0; j < line; j += 4) - { - if (imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx -= line; - } - else - { - break; - } - } - - output.descent = (i - baseline); - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; -}; - -module.exports = MeasureText; - - -/***/ }), -/* 439 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcRender = __webpack_require__(1091); -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var Earcut = __webpack_require__(67); -var GeomCircle = __webpack_require__(61); -var MATH_CONST = __webpack_require__(14); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Arc Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * When it renders it displays an arc shape. You can control the start and end angles of the arc, - * as well as if the angles are winding clockwise or anti-clockwise. With the default settings - * it renders as a complete circle. By changing the angles you can create other arc shapes, - * such as half-circles. - * - * Arcs also have an `iterations` property and corresponding `setIterations` method. This allows - * you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. - * - * @class Arc - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [radius=128] - The radius of the arc. - * @param {number} [startAngle=0] - The start angle of the arc, in degrees. - * @param {number} [endAngle=360] - The end angle of the arc, in degrees. - * @param {boolean} [anticlockwise=false] - The winding order of the start and end angles. - * @param {number} [fillColor] - The color the arc will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Arc = new Class({ - - Extends: Shape, - - Mixins: [ - ArcRender - ], - - initialize: - - function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 128; } - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 360; } - if (anticlockwise === undefined) { anticlockwise = false; } - - Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius)); - - /** - * Private internal value. Holds the start angle in degrees. - * - * @name Phaser.GameObjects.Arc#_startAngle - * @type {number} - * @private - * @since 3.13.0 - */ - this._startAngle = startAngle; - - /** - * Private internal value. Holds the end angle in degrees. - * - * @name Phaser.GameObjects.Arc#_endAngle - * @type {number} - * @private - * @since 3.13.0 - */ - this._endAngle = endAngle; - - /** - * Private internal value. Holds the winding order of the start and end angles. - * - * @name Phaser.GameObjects.Arc#_anticlockwise - * @type {boolean} - * @private - * @since 3.13.0 - */ - this._anticlockwise = anticlockwise; - - /** - * Private internal value. Holds the number of iterations used when drawing the arc. - * - * @name Phaser.GameObjects.Arc#_iterations - * @type {number} - * @default 0.01 - * @private - * @since 3.13.0 - */ - this._iterations = 0.01; - - this.setPosition(x, y); - - var diameter = this.geom.radius * 2; - this.setSize(diameter, diameter); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * The number of iterations used when drawing the arc. - * Increase this value for smoother arcs, at the cost of more polygons being rendered. - * Modify this value by small amounts, such as 0.01. - * - * @name Phaser.GameObjects.Arc#iterations - * @type {number} - * @default 0.01 - * @since 3.13.0 - */ - iterations: { - - get: function () - { - return this._iterations; - }, - - set: function (value) - { - this._iterations = value; - - this.updateData(); - } - - }, - - /** - * The radius of the arc. - * - * @name Phaser.GameObjects.Arc#radius - * @type {number} - * @since 3.13.0 - */ - radius: { - - get: function () - { - return this.geom.radius; - }, - - set: function (value) - { - this.geom.radius = value; - - var diameter = value * 2; - this.setSize(diameter, diameter); - this.updateDisplayOrigin(); - this.updateData(); - } - - }, - - /** - * The start angle of the arc, in degrees. - * - * @name Phaser.GameObjects.Arc#startAngle - * @type {number} - * @since 3.13.0 - */ - startAngle: { - - get: function () - { - return this._startAngle; - }, - - set: function (value) - { - this._startAngle = value; - - this.updateData(); - } - - }, - - /** - * The end angle of the arc, in degrees. - * - * @name Phaser.GameObjects.Arc#endAngle - * @type {number} - * @since 3.13.0 - */ - endAngle: { - - get: function () - { - return this._endAngle; - }, - - set: function (value) - { - this._endAngle = value; - - this.updateData(); - } - - }, - - /** - * The winding order of the start and end angles. - * - * @name Phaser.GameObjects.Arc#anticlockwise - * @type {boolean} - * @since 3.13.0 - */ - anticlockwise: { - - get: function () - { - return this._anticlockwise; - }, - - set: function (value) - { - this._anticlockwise = value; - - this.updateData(); - } - - }, - - /** - * Sets the radius of the arc. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setRadius - * @since 3.13.0 - * - * @param {number} value - The value to set the radius to. - * - * @return {this} This Game Object instance. - */ - setRadius: function (value) - { - this.radius = value; - - return this; - }, - - /** - * Sets the number of iterations used when drawing the arc. - * Increase this value for smoother arcs, at the cost of more polygons being rendered. - * Modify this value by small amounts, such as 0.01. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setIterations - * @since 3.13.0 - * - * @param {number} value - The value to set the iterations to. - * - * @return {this} This Game Object instance. - */ - setIterations: function (value) - { - if (value === undefined) { value = 0.01; } - - this.iterations = value; - - return this; - }, - - /** - * Sets the starting angle of the arc, in degrees. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setStartAngle - * @since 3.13.0 - * - * @param {number} value - The value to set the starting angle to. - * - * @return {this} This Game Object instance. - */ - setStartAngle: function (angle, anticlockwise) - { - this._startAngle = angle; - - if (anticlockwise !== undefined) - { - this._anticlockwise = anticlockwise; - } - - return this.updateData(); - }, - - /** - * Sets the ending angle of the arc, in degrees. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setEndAngle - * @since 3.13.0 - * - * @param {number} value - The value to set the ending angle to. - * - * @return {this} This Game Object instance. - */ - setEndAngle: function (angle, anticlockwise) - { - this._endAngle = angle; - - if (anticlockwise !== undefined) - { - this._anticlockwise = anticlockwise; - } - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Arc#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var step = this._iterations; - var iteration = step; - - var radius = this.geom.radius; - var startAngle = DegToRad(this._startAngle); - var endAngle = DegToRad(this._endAngle); - var anticlockwise = this._anticlockwise; - - var x = radius; - var y = radius; - - endAngle -= startAngle; - - if (anticlockwise) - { - if (endAngle < -MATH_CONST.PI2) - { - endAngle = -MATH_CONST.PI2; - } - else if (endAngle > 0) - { - endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; - } - } - else if (endAngle > MATH_CONST.PI2) - { - endAngle = MATH_CONST.PI2; - } - else if (endAngle < 0) - { - endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; - } - - var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; - - var ta; - - while (iteration < 1) - { - ta = endAngle * iteration + startAngle; - - path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); - - iteration += step; - } - - ta = endAngle + startAngle; - - path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); - - path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Arc; - - -/***/ }), -/* 440 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CurveRender = __webpack_require__(1094); -var Earcut = __webpack_require__(67); -var Rectangle = __webpack_require__(10); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Curve Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to - * the Curve Shape in the constructor. - * - * The Curve shape also has a `smoothness` property and corresponding `setSmoothness` method. - * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. Increase and decrease the default value for smoother, or more - * jagged, shapes. - * - * @class Curve - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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.Curves.Curve} [curve] - The Curve object to use to create the Shape. - * @param {number} [fillColor] - The color the curve will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Curve = new Class({ - - Extends: Shape, - - Mixins: [ - CurveRender - ], - - initialize: - - function Curve (scene, x, y, curve, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - Shape.call(this, scene, 'Curve', curve); - - /** - * Private internal value. - * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. - * - * @name Phaser.GameObjects.Curve#_smoothness - * @type {number} - * @private - * @since 3.13.0 - */ - this._smoothness = 32; - - /** - * Private internal value. - * The Curve bounds rectangle. - * - * @name Phaser.GameObjects.Curve#_curveBounds - * @type {Phaser.Geom.Rectangle} - * @private - * @since 3.13.0 - */ - this._curveBounds = new Rectangle(); - - this.closePath = false; - - this.setPosition(x, y); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateData(); - }, - - /** - * The smoothness of the curve. The number of points used when rendering it. - * Increase this value for smoother curves, at the cost of more polygons being rendered. - * - * @name Phaser.GameObjects.Curve#smoothness - * @type {number} - * @default 32 - * @since 3.13.0 - */ - smoothness: { - - get: function () - { - return this._smoothness; - }, - - set: function (value) - { - this._smoothness = value; - - this.updateData(); - } - - }, - - /** - * Sets the smoothness of the curve. The number of points used when rendering it. - * Increase this value for smoother curves, at the cost of more polygons being rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.Curve#setSmoothness - * @since 3.13.0 - * - * @param {number} value - The value to set the smoothness to. - * - * @return {this} This Game Object instance. - */ - setSmoothness: function (value) - { - this._smoothness = value; - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Curve#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var bounds = this._curveBounds; - var smoothness = this._smoothness; - - // Update the bounds in case the underlying data has changed - this.geom.getBounds(bounds, smoothness); - - this.setSize(bounds.width, bounds.height); - this.updateDisplayOrigin(); - - var path = []; - var points = this.geom.getPoints(smoothness); - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Curve; - - -/***/ }), -/* 441 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var EllipseRender = __webpack_require__(1097); -var GeomEllipse = __webpack_require__(106); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * When it renders it displays an ellipse shape. You can control the width and height of the ellipse. - * If the width and height match it will render as a circle. If the width is less than the height, - * it will look more like an egg shape. - * - * The Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method. - * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. Increase and decrease the default value for smoother, or more - * jagged, shapes. - * - * @class Ellipse - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [width=128] - The width of the ellipse. An ellipse with equal width and height renders as a circle. - * @param {number} [height=128] - The height of the ellipse. An ellipse with equal width and height renders as a circle. - * @param {number} [fillColor] - The color the ellipse will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Ellipse = new Class({ - - Extends: Shape, - - Mixins: [ - EllipseRender - ], - - initialize: - - function Ellipse (scene, x, y, width, height, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - - Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); - - /** - * Private internal value. - * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. - * - * @name Phaser.GameObjects.Ellipse#_smoothness - * @type {number} - * @private - * @since 3.13.0 - */ - this._smoothness = 64; - - this.setPosition(x, y); - - this.width = width; - this.height = height; - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * The smoothness of the ellipse. The number of points used when rendering it. - * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. - * - * @name Phaser.GameObjects.Ellipse#smoothness - * @type {number} - * @default 64 - * @since 3.13.0 - */ - smoothness: { - - get: function () - { - return this._smoothness; - }, - - set: function (value) - { - this._smoothness = value; - - this.updateData(); - } - - }, - - /** - * Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object. - * This call can be chained. - * - * @method Phaser.GameObjects.Ellipse#setSize - * @since 3.13.0 - * - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * - * @return {this} This Game Object instance. - */ - setSize: function (width, height) - { - this.width = width; - this.height = height; - this.geom.setPosition(width / 2, height / 2); - this.geom.setSize(width, height); - - return this.updateData(); - }, - - /** - * Sets the smoothness of the ellipse. The number of points used when rendering it. - * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.Ellipse#setSmoothness - * @since 3.13.0 - * - * @param {number} value - The value to set the smoothness to. - * - * @return {this} This Game Object instance. - */ - setSmoothness: function (value) - { - this._smoothness = value; - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Ellipse#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var points = this.geom.getPoints(this._smoothness); - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Ellipse; - - -/***/ }), -/* 442 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GridRender = __webpack_require__(1100); - -/** - * @classdesc - * The Grid Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * A Grid Shape allows you to display a grid in your game, where you can control the size of the - * grid as well as the width and height of the grid cells. You can set a fill color for each grid - * cell as well as an alternate fill color. When the alternate fill color is set then the grid - * cells will alternate the fill colors as they render, creating a chess-board effect. You can - * also optionally have an outline fill color. If set, this draws lines between the grid cells - * in the given color. If you specify an outline color with an alpha of zero, then it will draw - * the cells spaced out, but without the lines between them. - * - * @class Grid - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [width=128] - The width of the grid. - * @param {number} [height=128] - The height of the grid. - * @param {number} [cellWidth=32] - The width of one cell in the grid. - * @param {number} [cellHeight=32] - The height of one cell in the grid. - * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * @param {number} [outlineFillColor] - The color of the lines between the grid cells. See the `setOutline` method. - * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. - */ -var Grid = new Class({ - - Extends: Shape, - - Mixins: [ - GridRender - ], - - initialize: - - function Grid (scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - if (cellWidth === undefined) { cellWidth = 32; } - if (cellHeight === undefined) { cellHeight = 32; } - - Shape.call(this, scene, 'Grid', null); - - /** - * The width of each grid cell. - * Must be a positive value. - * - * @name Phaser.GameObjects.Grid#cellWidth - * @type {number} - * @since 3.13.0 - */ - this.cellWidth = cellWidth; - - /** - * The height of each grid cell. - * Must be a positive value. - * - * @name Phaser.GameObjects.Grid#cellHeight - * @type {number} - * @since 3.13.0 - */ - this.cellHeight = cellHeight; - - /** - * Will the grid render its cells in the `fillColor`? - * - * @name Phaser.GameObjects.Grid#showCells - * @type {boolean} - * @since 3.13.0 - */ - this.showCells = true; - - /** - * The color of the lines between each grid cell. - * - * @name Phaser.GameObjects.Grid#outlineFillColor - * @type {number} - * @since 3.13.0 - */ - this.outlineFillColor = 0; - - /** - * The alpha value for the color of the lines between each grid cell. - * - * @name Phaser.GameObjects.Grid#outlineFillAlpha - * @type {number} - * @since 3.13.0 - */ - this.outlineFillAlpha = 0; - - /** - * Will the grid display the lines between each cell when it renders? - * - * @name Phaser.GameObjects.Grid#showOutline - * @type {boolean} - * @since 3.13.0 - */ - this.showOutline = true; - - /** - * Will the grid render the alternating cells in the `altFillColor`? - * - * @name Phaser.GameObjects.Grid#showAltCells - * @type {boolean} - * @since 3.13.0 - */ - this.showAltCells = false; - - /** - * The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. - * - * @name Phaser.GameObjects.Grid#altFillColor - * @type {number} - * @since 3.13.0 - */ - this.altFillColor; - - /** - * The alpha the alternating grid cells will be filled with. - * You can also set the alpha of the overall Shape using its `alpha` property. - * - * @name Phaser.GameObjects.Grid#altFillAlpha - * @type {number} - * @since 3.13.0 - */ - this.altFillAlpha; - - this.setPosition(x, y); - this.setSize(width, height); - - this.setFillStyle(fillColor, fillAlpha); - - if (outlineFillColor !== undefined) - { - this.setOutlineStyle(outlineFillColor, outlineFillAlpha); - } - - this.updateDisplayOrigin(); - }, - - /** - * Sets the fill color and alpha level the grid cells will use when rendering. - * - * If this method is called with no values then the grid cells will not be rendered, - * however the grid lines and alternating cells may still be. - * - * Also see the `setOutlineStyle` and `setAltFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showCells = false; - } - else - { - this.fillColor = fillColor; - this.fillAlpha = fillAlpha; - this.showCells = true; - } - - return this; - }, - - /** - * Sets the fill color and alpha level that the alternating grid cells will use. - * - * If this method is called with no values then alternating grid cells will not be rendered in a different color. - * - * Also see the `setOutlineStyle` and `setFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setAltFillStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the alternating grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setAltFillStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showAltCells = false; - } - else - { - this.altFillColor = fillColor; - this.altFillAlpha = fillAlpha; - this.showAltCells = true; - } - - return this; - }, - - /** - * Sets the fill color and alpha level that the lines between each grid cell will use. - * - * If this method is called with no values then the grid lines will not be rendered at all, however - * the cells themselves may still be if they have colors set. - * - * Also see the `setFillStyle` and `setAltFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setOutlineStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the lines between the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the lines between the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setOutlineStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showOutline = false; - } - else - { - this.outlineFillColor = fillColor; - this.outlineFillAlpha = fillAlpha; - this.showOutline = true; - } - - return this; - } - -}); - -module.exports = Grid; - - -/***/ }), -/* 443 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var IsoBoxRender = __webpack_require__(1103); -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The IsoBox Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * An IsoBox is an 'isometric' rectangle. Each face of it has a different fill color. You can set - * the color of the top, left and right faces of the rectangle respectively. You can also choose - * which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. - * - * You cannot view an IsoBox from under-neath, however you can change the 'angle' by setting - * the `projection` property. - * - * @class IsoBox - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [size=48] - The width of the iso box in pixels. The left and right faces will be exactly half this value. - * @param {number} [height=32] - The height of the iso box. The left and right faces will be this tall. The overall height of the isobox will be this value plus half the `size` value. - * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso box. - * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso box. - * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso box. - */ -var IsoBox = new Class({ - - Extends: Shape, - - Mixins: [ - IsoBoxRender - ], - - initialize: - - function IsoBox (scene, x, y, size, height, fillTop, fillLeft, fillRight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (size === undefined) { size = 48; } - if (height === undefined) { height = 32; } - if (fillTop === undefined) { fillTop = 0xeeeeee; } - if (fillLeft === undefined) { fillLeft = 0x999999; } - if (fillRight === undefined) { fillRight = 0xcccccc; } - - Shape.call(this, scene, 'IsoBox', null); - - /** - * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * - * @name Phaser.GameObjects.IsoBox#projection - * @type {number} - * @default 4 - * @since 3.13.0 - */ - this.projection = 4; - - /** - * The color used to fill in the top of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillTop - * @type {number} - * @since 3.13.0 - */ - this.fillTop = fillTop; - - /** - * The color used to fill in the left-facing side of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillLeft - * @type {number} - * @since 3.13.0 - */ - this.fillLeft = fillLeft; - - /** - * The color used to fill in the right-facing side of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillRight - * @type {number} - * @since 3.13.0 - */ - this.fillRight = fillRight; - - /** - * Controls if the top-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showTop - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showTop = true; - - /** - * Controls if the left-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showLeft - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showLeft = true; - - /** - * Controls if the right-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showRight - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showRight = true; - - this.isFilled = true; - - this.setPosition(x, y); - this.setSize(size, height); - - this.updateDisplayOrigin(); - }, - - /** - * Sets the projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setProjection - * @since 3.13.0 - * - * @param {number} value - The value to set the projection to. - * - * @return {this} This Game Object instance. - */ - setProjection: function (value) - { - this.projection = value; - - return this; - }, - - /** - * Sets which faces of the iso box will be rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setFaces - * @since 3.13.0 - * - * @param {boolean} [showTop=true] - Show the top-face of the iso box. - * @param {boolean} [showLeft=true] - Show the left-face of the iso box. - * @param {boolean} [showRight=true] - Show the right-face of the iso box. - * - * @return {this} This Game Object instance. - */ - setFaces: function (showTop, showLeft, showRight) - { - if (showTop === undefined) { showTop = true; } - if (showLeft === undefined) { showLeft = true; } - if (showRight === undefined) { showRight = true; } - - this.showTop = showTop; - this.showLeft = showLeft; - this.showRight = showRight; - - return this; - }, - - /** - * Sets the fill colors for each face of the iso box. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillTop] - The color used to fill the top of the iso box. - * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso box. - * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso box. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillTop, fillLeft, fillRight) - { - this.fillTop = fillTop; - this.fillLeft = fillLeft; - this.fillRight = fillRight; - - this.isFilled = true; - - return this; - } - -}); - -module.exports = IsoBox; - - -/***/ }), -/* 444 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var IsoTriangleRender = __webpack_require__(1106); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The IsoTriangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * An IsoTriangle is an 'isometric' triangle. Think of it like a pyramid. Each face has a different - * fill color. You can set the color of the top, left and right faces of the triangle respectively - * You can also choose which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. - * - * You cannot view an IsoTriangle from under-neath, however you can change the 'angle' by setting - * the `projection` property. The `reversed` property controls if the IsoTriangle is rendered upside - * down or not. - * - * @class IsoTriangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [size=48] - The width of the iso triangle in pixels. The left and right faces will be exactly half this value. - * @param {number} [height=32] - The height of the iso triangle. The left and right faces will be this tall. The overall height of the iso triangle will be this value plus half the `size` value. - * @param {boolean} [reversed=false] - Is the iso triangle upside down? - * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso triangle. - * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso triangle. - * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso triangle. - */ -var IsoTriangle = new Class({ - - Extends: Shape, - - Mixins: [ - IsoTriangleRender - ], - - initialize: - - function IsoTriangle (scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (size === undefined) { size = 48; } - if (height === undefined) { height = 32; } - if (reversed === undefined) { reversed = false; } - if (fillTop === undefined) { fillTop = 0xeeeeee; } - if (fillLeft === undefined) { fillLeft = 0x999999; } - if (fillRight === undefined) { fillRight = 0xcccccc; } - - Shape.call(this, scene, 'IsoTriangle', null); - - /** - * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * - * @name Phaser.GameObjects.IsoTriangle#projection - * @type {number} - * @default 4 - * @since 3.13.0 - */ - this.projection = 4; - - /** - * The color used to fill in the top of the iso triangle. This is only used if the triangle is reversed. - * - * @name Phaser.GameObjects.IsoTriangle#fillTop - * @type {number} - * @since 3.13.0 - */ - this.fillTop = fillTop; - - /** - * The color used to fill in the left-facing side of the iso triangle. - * - * @name Phaser.GameObjects.IsoTriangle#fillLeft - * @type {number} - * @since 3.13.0 - */ - this.fillLeft = fillLeft; - - /** - * The color used to fill in the right-facing side of the iso triangle. - * - * @name Phaser.GameObjects.IsoTriangle#fillRight - * @type {number} - * @since 3.13.0 - */ - this.fillRight = fillRight; - - /** - * Controls if the top-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showTop - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showTop = true; - - /** - * Controls if the left-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showLeft - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showLeft = true; - - /** - * Controls if the right-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showRight - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showRight = true; - - /** - * Sets if the iso triangle will be rendered upside down or not. - * - * @name Phaser.GameObjects.IsoTriangle#isReversed - * @type {boolean} - * @default false - * @since 3.13.0 - */ - this.isReversed = reversed; - - this.isFilled = true; - - this.setPosition(x, y); - this.setSize(size, height); - - this.updateDisplayOrigin(); - }, - - /** - * Sets the projection level of the iso triangle. Change this to change the 'angle' at which you are looking at the pyramid. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setProjection - * @since 3.13.0 - * - * @param {number} value - The value to set the projection to. - * - * @return {this} This Game Object instance. - */ - setProjection: function (value) - { - this.projection = value; - - return this; - }, - - /** - * Sets if the iso triangle will be rendered upside down or not. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setReversed - * @since 3.13.0 - * - * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. - * - * @return {this} This Game Object instance. - */ - setReversed: function (reversed) - { - this.isReversed = reversed; - - return this; - }, - - /** - * Sets which faces of the iso triangle will be rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setFaces - * @since 3.13.0 - * - * @param {boolean} [showTop=true] - Show the top-face of the iso triangle (only if `reversed` is true) - * @param {boolean} [showLeft=true] - Show the left-face of the iso triangle. - * @param {boolean} [showRight=true] - Show the right-face of the iso triangle. - * - * @return {this} This Game Object instance. - */ - setFaces: function (showTop, showLeft, showRight) - { - if (showTop === undefined) { showTop = true; } - if (showLeft === undefined) { showLeft = true; } - if (showRight === undefined) { showRight = true; } - - this.showTop = showTop; - this.showLeft = showLeft; - this.showRight = showRight; - - return this; - }, - - /** - * Sets the fill colors for each face of the iso triangle. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillTop] - The color used to fill the top of the iso triangle. - * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso triangle. - * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso triangle. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillTop, fillLeft, fillRight) - { - this.fillTop = fillTop; - this.fillLeft = fillLeft; - this.fillRight = fillRight; - - this.isFilled = true; - - return this; - } - -}); - -module.exports = IsoTriangle; - - -/***/ }), -/* 445 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GeomLine = __webpack_require__(45); -var LineRender = __webpack_require__(1109); - -/** - * @classdesc - * The Line Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only stroke colors and cannot be filled. - * - * A Line Shape allows you to draw a line between two points in your game. You can control the - * stroke color and thickness of the line. In WebGL only you can also specify a different - * thickness for the start and end of the line, allowing you to render lines that taper-off. - * - * If you need to draw multiple lines in a sequence you may wish to use the Polygon Shape instead. - * - * Be aware that as with all Game Objects the default origin is 0.5. If you need to draw a Line - * between two points and want the x1/y1 values to match the x/y values, then set the origin to 0. - * - * @class Line - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [x1=0] - The horizontal position of the start of the line. - * @param {number} [y1=0] - The vertical position of the start of the line. - * @param {number} [x2=128] - The horizontal position of the end of the line. - * @param {number} [y2=0] - The vertical position of the end of the line. - * @param {number} [strokeColor] - The color the line will be drawn in, i.e. 0xff0000 for red. - * @param {number} [strokeAlpha] - The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Line = new Class({ - - Extends: Shape, - - Mixins: [ - LineRender - ], - - initialize: - - function Line (scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 128; } - if (y2 === undefined) { y2 = 0; } - - Shape.call(this, scene, 'Line', new GeomLine(x1, y1, x2, y2)); - - var width = Math.max(1, this.geom.right - this.geom.left); - var height = Math.max(1, this.geom.bottom - this.geom.top); - - /** - * The width (or thickness) of the line. - * See the setLineWidth method for extra details on changing this on WebGL. - * - * @name Phaser.GameObjects.Line#lineWidth - * @type {number} - * @since 3.13.0 - */ - this.lineWidth = 1; - - /** - * Private internal value. Holds the start width of the line. - * - * @name Phaser.GameObjects.Line#_startWidth - * @type {number} - * @private - * @since 3.13.0 - */ - this._startWidth = 1; - - /** - * Private internal value. Holds the end width of the line. - * - * @name Phaser.GameObjects.Line#_endWidth - * @type {number} - * @private - * @since 3.13.0 - */ - this._endWidth = 1; - - this.setPosition(x, y); - this.setSize(width, height); - - if (strokeColor !== undefined) - { - this.setStrokeStyle(1, strokeColor, strokeAlpha); - } - - this.updateDisplayOrigin(); - }, - - /** - * Sets the width of the line. - * - * When using the WebGL renderer you can have different start and end widths. - * When using the Canvas renderer only the `startWidth` value is used. The `endWidth` is ignored. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Line#setLineWidth - * @since 3.13.0 - * - * @param {number} startWidth - The start width of the line. - * @param {number} [endWidth] - The end width of the line. Only used in WebGL. - * - * @return {this} This Game Object instance. - */ - setLineWidth: function (startWidth, endWidth) - { - if (endWidth === undefined) { endWidth = startWidth; } - - this._startWidth = startWidth; - this._endWidth = endWidth; - - this.lineWidth = startWidth; - - return this; - }, - - /** - * Sets the start and end coordinates of this Line. - * - * @method Phaser.GameObjects.Line#setTo - * @since 3.13.0 - * - * @param {number} [x1=0] - The horizontal position of the start of the line. - * @param {number} [y1=0] - The vertical position of the start of the line. - * @param {number} [x2=0] - The horizontal position of the end of the line. - * @param {number} [y2=0] - The vertical position of the end of the line. - * - * @return {this} This Line object. - */ - setTo: function (x1, y1, x2, y2) - { - this.geom.setTo(x1, y1, x2, y2); - - return this; - } - -}); - -module.exports = Line; - - -/***/ }), -/* 446 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var PolygonRender = __webpack_require__(1112); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var GetAABB = __webpack_require__(447); -var GeomPolygon = __webpack_require__(222); -var Shape = __webpack_require__(32); -var Smooth = __webpack_require__(450); - -/** - * @classdesc - * The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * The Polygon Shape is created by providing a list of points, which are then used to create an - * internal Polygon geometry object. The points can be set from a variety of formats: - * - * - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` - * - An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]` - * - An array of objects with public x/y properties: `[obj1, obj2, ...]` - * - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]` - * - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]` - * - * By default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending - * on the coordinates of the points provided, the final shape may be rendered offset from its origin. - * - * @class Polygon - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {any} [points] - The points that make up the polygon. - * @param {number} [fillColor] - The color the polygon will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Polygon = new Class({ - - Extends: Shape, - - Mixins: [ - PolygonRender - ], - - initialize: - - function Polygon (scene, x, y, points, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - Shape.call(this, scene, 'Polygon', new GeomPolygon(points)); - - var bounds = GetAABB(this.geom); - - this.setPosition(x, y); - this.setSize(bounds.width, bounds.height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Smooths the polygon over the number of iterations specified. - * The base polygon data will be updated and replaced with the smoothed values. - * This call can be chained. - * - * @method Phaser.GameObjects.Polygon#smooth - * @since 3.13.0 - * - * @param {number} [iterations=1] - The number of times to apply the polygon smoothing. - * - * @return {this} This Game Object instance. - */ - smooth: function (iterations) - { - if (iterations === undefined) { iterations = 1; } - - for (var i = 0; i < iterations; i++) - { - Smooth(this.geom); - } - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Polygon#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var points = this.geom.points; - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Polygon; - - -/***/ }), -/* 447 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -/** - * Calculates the bounding AABB rectangle of a polygon. - * - * @function Phaser.Geom.Polygon.GetAABB - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The polygon that should be calculated. - * @param {(Phaser.Geom.Rectangle|object)} [out] - The rectangle or object that has x, y, width, and height properties to store the result. Optional. - * - * @return {(Phaser.Geom.Rectangle|object)} The resulting rectangle or object that is passed in with position and dimensions of the polygon's AABB. - */ -var GetAABB = function (polygon, out) -{ - if (out === undefined) { out = new Rectangle(); } - - var minX = Infinity; - var minY = Infinity; - var maxX = -minX; - var maxY = -minY; - var p; - - for (var i = 0; i < polygon.points.length; i++) - { - p = polygon.points[i]; - - minX = Math.min(minX, p.x); - minY = Math.min(minY, p.y); - maxX = Math.max(maxX, p.x); - maxY = Math.max(maxY, p.y); - } - - out.x = minX; - out.y = minY; - out.width = maxX - minX; - out.height = maxY - minY; - - return out; -}; - -module.exports = GetAABB; - - -/***/ }), -/* 448 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Line = __webpack_require__(45); -var Perimeter = __webpack_require__(449); - -/** - * Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon, - * based on the given quantity or stepRate values. - * - * @function Phaser.Geom.Polygon.GetPoints - * @since 3.12.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the points from. - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate. - * @param {array} [output] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {Phaser.Geom.Point[]} An array of Point objects pertaining to the points around the perimeter of the Polygon. - */ -var GetPoints = function (polygon, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } - - var points = polygon.points; - var perimeter = Perimeter(polygon); - - // 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 / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var position = perimeter * (i / quantity); - var accumulatedPerimeter = 0; - - for (var j = 0; j < points.length; j++) - { - var pointA = points[j]; - var pointB = points[(j + 1) % points.length]; - var line = new Line( - pointA.x, - pointA.y, - pointB.x, - pointB.y - ); - var length = Length(line); - - if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) - { - accumulatedPerimeter += length; - continue; - } - - var point = line.getPoint((position - accumulatedPerimeter) / length); - out.push(point); - - break; - } - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 449 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Line = __webpack_require__(45); - -/** - * Returns the perimeter of the given Polygon. - * - * @function Phaser.Geom.Polygon.Perimeter - * @since 3.12.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the perimeter of. - * - * @return {number} The perimeter of the Polygon. - */ -var Perimeter = function (polygon) -{ - var points = polygon.points; - var perimeter = 0; - - for (var i = 0; i < points.length; i++) - { - var pointA = points[i]; - var pointB = points[(i + 1) % points.length]; - var line = new Line( - pointA.x, - pointA.y, - pointB.x, - pointB.y - ); - - perimeter += Length(line); - } - - return perimeter; -}; - -module.exports = Perimeter; - - -/***/ }), -/* 450 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Igor Ognichenko - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @ignore - */ -var copy = function (out, a) -{ - out[0] = a[0]; - out[1] = a[1]; - - return out; -}; - -/** - * Takes a Polygon object and applies Chaikin's smoothing algorithm on its points. - * - * @function Phaser.Geom.Polygon.Smooth - * @since 3.13.0 - * - * @generic {Phaser.Geom.Polygon} O - [polygon,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The polygon to be smoothed. The polygon will be modified in-place and returned. - * - * @return {Phaser.Geom.Polygon} The input polygon. - */ -var Smooth = function (polygon) -{ - var i; - var points = []; - var data = polygon.points; - - for (i = 0; i < data.length; i++) - { - points.push([ data[i].x, data[i].y ]); - } - - var output = []; - - if (points.length > 0) - { - output.push(copy([ 0, 0 ], points[0])); - } - - for (i = 0; i < points.length - 1; i++) - { - var p0 = points[i]; - var p1 = points[i + 1]; - var p0x = p0[0]; - var p0y = p0[1]; - var p1x = p1[0]; - var p1y = p1[1]; - - output.push([ 0.85 * p0x + 0.15 * p1x, 0.85 * p0y + 0.15 * p1y ]); - output.push([ 0.15 * p0x + 0.85 * p1x, 0.15 * p0y + 0.85 * p1y ]); - } - - if (points.length > 1) - { - output.push(copy([ 0, 0 ], points[points.length - 1])); - } - - return polygon.setTo(output); -}; - -module.exports = Smooth; - - -/***/ }), -/* 451 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GeomRectangle = __webpack_require__(10); -var Shape = __webpack_require__(32); -var RectangleRender = __webpack_require__(1115); - -/** - * @classdesc - * The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * You can change the size of the rectangle by changing the `width` and `height` properties. - * - * @class Rectangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 - The horizontal position of this Game Object in the world. - * @param {number} y - The vertical position of this Game Object in the world. - * @param {number} [width=128] - The width of the rectangle. - * @param {number} [height=128] - The height of the rectangle. - * @param {number} [fillColor] - The color the rectangle will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Rectangle = new Class({ - - Extends: Shape, - - Mixins: [ - RectangleRender - ], - - initialize: - - function Rectangle (scene, x, y, width, height, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - - Shape.call(this, scene, 'Rectangle', new GeomRectangle(0, 0, width, height)); - - this.setPosition(x, y); - this.setSize(width, height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * 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.Rectangle#setSize - * @since 3.13.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; - - this.geom.setSize(width, height); - - this.updateData(); - - return this; - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Rectangle#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var rect = this.geom; - var line = this._tempLine; - - rect.getLineA(line); - - path.push(line.x1, line.y1, line.x2, line.y2); - - rect.getLineB(line); - - path.push(line.x2, line.y2); - - rect.getLineC(line); - - path.push(line.x2, line.y2); - - rect.getLineD(line); - - path.push(line.x2, line.y2); - - this.pathData = path; - - return this; - } - -}); - -module.exports = Rectangle; - - -/***/ }), -/* 452 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var StarRender = __webpack_require__(1118); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Star Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * As the name implies, the Star shape will display a star in your game. You can control several - * aspects of it including the number of points that constitute the star. The default is 5. If - * you change it to 4 it will render as a diamond. If you increase them, you'll get a more spiky - * star shape. - * - * You can also control the inner and outer radius, which is how 'long' each point of the star is. - * Modify these values to create more interesting shapes. - * - * @class Star - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [points=5] - The number of points on the star. - * @param {number} [innerRadius=32] - The inner radius of the star. - * @param {number} [outerRadius=64] - The outer radius of the star. - * @param {number} [fillColor] - The color the star will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Star = new Class({ - - Extends: Shape, - - Mixins: [ - StarRender - ], - - initialize: - - function Star (scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (points === undefined) { points = 5; } - if (innerRadius === undefined) { innerRadius = 32; } - if (outerRadius === undefined) { outerRadius = 64; } - - Shape.call(this, scene, 'Star', null); - - /** - * Private internal value. - * The number of points in the star. - * - * @name Phaser.GameObjects.Star#_points - * @type {number} - * @private - * @since 3.13.0 - */ - this._points = points; - - /** - * Private internal value. - * The inner radius of the star. - * - * @name Phaser.GameObjects.Star#_innerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._innerRadius = innerRadius; - - /** - * Private internal value. - * The outer radius of the star. - * - * @name Phaser.GameObjects.Star#_outerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._outerRadius = outerRadius; - - this.setPosition(x, y); - this.setSize(outerRadius * 2, outerRadius * 2); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Sets the number of points that make up the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setPoints - * @since 3.13.0 - * - * @param {number} value - The amount of points the Star will have. - * - * @return {this} This Game Object instance. - */ - setPoints: function (value) - { - this._points = value; - - return this.updateData(); - }, - - /** - * Sets the inner radius of the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setInnerRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the inner radius to. - * - * @return {this} This Game Object instance. - */ - setInnerRadius: function (value) - { - this._innerRadius = value; - - return this.updateData(); - }, - - /** - * Sets the outer radius of the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setOuterRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the outer radius to. - * - * @return {this} This Game Object instance. - */ - setOuterRadius: function (value) - { - this._outerRadius = value; - - return this.updateData(); - }, - - /** - * The number of points that make up the Star shape. - * - * @name Phaser.GameObjects.Star#points - * @type {number} - * @default 5 - * @since 3.13.0 - */ - points: { - - get: function () - { - return this._points; - }, - - set: function (value) - { - this._points = value; - - this.updateData(); - } - - }, - - /** - * The inner radius of the Star shape. - * - * @name Phaser.GameObjects.Star#innerRadius - * @type {number} - * @default 32 - * @since 3.13.0 - */ - innerRadius: { - - get: function () - { - return this._innerRadius; - }, - - set: function (value) - { - this._innerRadius = value; - - this.updateData(); - } - - }, - - /** - * The outer radius of the Star shape. - * - * @name Phaser.GameObjects.Star#outerRadius - * @type {number} - * @default 64 - * @since 3.13.0 - */ - outerRadius: { - - get: function () - { - return this._outerRadius; - }, - - set: function (value) - { - this._outerRadius = value; - - this.updateData(); - } - - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Star#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - - var points = this._points; - var innerRadius = this._innerRadius; - var outerRadius = this._outerRadius; - - var rot = Math.PI / 2 * 3; - var step = Math.PI / points; - - // So origin 0.5 = the center of the star - var x = outerRadius; - var y = outerRadius; - - path.push(x, y + -outerRadius); - - for (var i = 0; i < points; i++) - { - path.push(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius); - - rot += step; - - path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius); - - rot += step; - } - - path.push(x, y + -outerRadius); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Star; - - -/***/ }), -/* 453 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GeomTriangle = __webpack_require__(82); -var TriangleRender = __webpack_require__(1121); - -/** - * @classdesc - * The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * The Triangle consists of 3 lines, joining up to form a triangular shape. You can control the - * position of each point of these lines. The triangle is always closed and cannot have an open - * face. If you require that, consider using a Polygon instead. - * - * @class Triangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [x1=0] - The horizontal position of the first point in the triangle. - * @param {number} [y1=128] - The vertical position of the first point in the triangle. - * @param {number} [x2=64] - The horizontal position of the second point in the triangle. - * @param {number} [y2=0] - The vertical position of the second point in the triangle. - * @param {number} [x3=128] - The horizontal position of the third point in the triangle. - * @param {number} [y3=128] - The vertical position of the third point in the triangle. - * @param {number} [fillColor] - The color the triangle will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Triangle = new Class({ - - Extends: Shape, - - Mixins: [ - TriangleRender - ], - - initialize: - - function Triangle (scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 128; } - if (x2 === undefined) { x2 = 64; } - if (y2 === undefined) { y2 = 0; } - if (x3 === undefined) { x3 = 128; } - if (y3 === undefined) { y3 = 128; } - - Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); - - var width = this.geom.right - this.geom.left; - var height = this.geom.bottom - this.geom.top; - - this.setPosition(x, y); - this.setSize(width, height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Sets the data for the lines that make up this Triangle shape. - * - * @method Phaser.GameObjects.Triangle#setTo - * @since 3.13.0 - * - * @param {number} [x1=0] - The horizontal position of the first point in the triangle. - * @param {number} [y1=0] - The vertical position of the first point in the triangle. - * @param {number} [x2=0] - The horizontal position of the second point in the triangle. - * @param {number} [y2=0] - The vertical position of the second point in the triangle. - * @param {number} [x3=0] - The horizontal position of the third point in the triangle. - * @param {number} [y3=0] - The vertical position of the third point in the triangle. - * - * @return {this} This Game Object instance. - */ - setTo: function (x1, y1, x2, y2, x3, y3) - { - this.geom.setTo(x1, y1, x2, y2, x3, y3); - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Triangle#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var tri = this.geom; - var line = this._tempLine; - - tri.getLineA(line); - - path.push(line.x1, line.y1, line.x2, line.y2); - - tri.getLineB(line); - - path.push(line.x2, line.y2); - - tri.getLineC(line); - - path.push(line.x2, line.y2); - - this.pathData = path; - - return this; - } - -}); - -module.exports = Triangle; - - -/***/ }), -/* 454 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); -var Length = __webpack_require__(63); - -/** - * Returns a Point from around the perimeter of a Triangle. - * - * @function Phaser.Geom.Triangle.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the point on its perimeter from. - * @param {number} position - The position along the perimeter of the triangle. A value between 0 and 1. - * @param {(Phaser.Geom.Point|object)} [out] - An option Point, or Point-like object to store the value in. If not given a new Point will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point object containing the given position from the perimeter of the triangle. - */ -var GetPoint = function (triangle, position, out) -{ - if (out === undefined) { out = new Point(); } - - var line1 = triangle.getLineA(); - var line2 = triangle.getLineB(); - var line3 = triangle.getLineC(); - - if (position <= 0 || position >= 1) - { - out.x = line1.x1; - out.y = line1.y1; - - return out; - } - - var length1 = Length(line1); - var length2 = Length(line2); - var length3 = Length(line3); - - var perimeter = length1 + length2 + length3; - - var p = perimeter * position; - var localPosition = 0; - - // Which line is it on? - - if (p < length1) - { - // Line 1 - localPosition = p / length1; - - out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; - out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; - } - else if (p > length1 + length2) - { - // Line 3 - p -= length1 + length2; - localPosition = p / length3; - - out.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; - out.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; - } - else - { - // Line 2 - p -= length1; - localPosition = p / length2; - - out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } - - return out; -}; - -module.exports = GetPoint; - - -/***/ }), -/* 455 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Point = __webpack_require__(4); - -/** - * Returns an array of evenly spaced points on the perimeter of a Triangle. - * - * @function Phaser.Geom.Triangle.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the points from. - * @param {number} quantity - The number of evenly spaced points to return. Set to 0 to return an arbitrary number of points based on the `stepRate`. - * @param {number} stepRate - If `quantity` is 0, the distance between each returned point. - * @param {(array|Phaser.Geom.Point[])} [out] - An array to which the points should be appended. - * - * @return {(array|Phaser.Geom.Point[])} The modified `out` array, or a new array if none was provided. - */ -var GetPoints = function (triangle, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } - - var line1 = triangle.getLineA(); - var line2 = triangle.getLineB(); - var line3 = triangle.getLineC(); - - var length1 = Length(line1); - var length2 = Length(line2); - var length3 = Length(line3); - - var perimeter = length1 + length2 + length3; - - // 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 / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var p = perimeter * (i / quantity); - var localPosition = 0; - - var point = new Point(); - - // Which line is it on? - - if (p < length1) - { - // Line 1 - localPosition = p / length1; - - point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; - point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; - } - else if (p > length1 + length2) - { - // Line 3 - p -= length1 + length2; - localPosition = p / length3; - - point.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; - point.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; - } - else - { - // Line 2 - p -= length1; - localPosition = p / length2; - - point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } - - out.push(point); - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 456 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets a value in an object, allowing for dot notation to control the depth of the property. - * - * For example: - * - * ```javascript - * var data = { - * world: { - * position: { - * x: 200, - * y: 100 - * } - * } - * }; - * - * SetValue(data, 'world.position.y', 300); - * - * console.log(data.world.position.y); // 300 - * ``` - * - * @function Phaser.Utils.Objects.SetValue - * @since 3.17.0 - * - * @param {object} source - The object to set the value in. - * @param {string} key - The name of the property in the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - * @param {any} value - The value to set into the property, if found in the source object. - * - * @return {boolean} `true` if the property key was valid and the value was set, otherwise `false`. - */ -var SetValue = function (source, key, value) -{ - if (!source || typeof source === 'number') - { - return false; - } - else if (source.hasOwnProperty(key)) - { - source[key] = value; - - return true; - } - else if (key.indexOf('.') !== -1) - { - var keys = key.split('.'); - var parent = source; - var prev = source; - - // 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 - prev = parent; - parent = parent[keys[i]]; - } - else - { - return false; - } - } - - prev[keys[keys.length - 1]] = value; - - return true; - } - - return false; -}; - -module.exports = SetValue; - - -/***/ }), -/* 457 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Face = __webpack_require__(111); -var Vertex = __webpack_require__(113); - -/** - * Generates a set of Face and Vertex objects by parsing the given data. - * - * This method will take vertex data in one of two formats, based on the `containsZ` parameter. - * - * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default) - * - * If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true. - * - * The `uvs` parameter is a numeric array consisting of `u` and `v` pairs. - * - * The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well. - * - * The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added. - * - * The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created. - * - * The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created. - * - * When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices. - * - * The following example will create a 256 x 256 sized quad using an index array: - * - * ```javascript - * const vertices = [ - * -128, 128, - * 128, 128, - * -128, -128, - * 128, -128 - * ]; - * - * const uvs = [ - * 0, 1, - * 1, 1, - * 0, 0, - * 1, 0 - * ]; - * - * const indices = [ 0, 2, 1, 2, 3, 1 ]; - * - * GenerateVerts(vertices, uvs, indicies); - * ``` - * - * If the data is not indexed, it's assumed that the arrays all contain sequential data. - * - * @function Phaser.Geom.Mesh.GenerateVerts - * @since 3.50.0 - * - * @param {number[]} vertices - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. - * @param {number[]} uvs - The UVs pairs array. - * @param {number[]} [indicies] - Optional vertex indicies array. If you don't have one, pass `null` or an empty array. - * @param {boolean} [containsZ=false] - Does the vertices data include a `z` component? - * @param {number[]} [normals] - Optional vertex normals array. If you don't have one, pass `null` or an empty array. - * @param {number|number[]} [colors=0xffffff] - An array of colors, one per vertex, or a single color value applied to all vertices. - * @param {number|number[]} [alphas=1] - An array of alpha values, one per vertex, or a single alpha value applied to all vertices. - * - * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. - */ -var GenerateVerts = function (vertices, uvs, indicies, containsZ, normals, colors, alphas) -{ - if (containsZ === undefined) { containsZ = false; } - if (colors === undefined) { colors = 0xffffff; } - if (alphas === undefined) { alphas = 1; } - - if (vertices.length !== uvs.length) - { - console.warn('GenerateVerts: vertices and uvs count not equal'); - return; - } - - var result = { - faces: [], - verts: [] - }; - - var i; - - var x; - var y; - var z; - - var u; - var v; - - var color; - var alpha; - - var normalX; - var normalY; - var normalZ; - - var iInc = (containsZ) ? 3 : 2; - - var isColorArray = Array.isArray(colors); - var isAlphaArray = Array.isArray(alphas); - - if (Array.isArray(indicies) && indicies.length > 0) - { - for (i = 0; i < indicies.length; i++) - { - var index1 = indicies[i]; - var index2 = indicies[i] * 2; - var index3 = indicies[i] * iInc; - - x = vertices[index3]; - y = vertices[index3 + 1]; - z = (containsZ) ? vertices[index3 + 2] : 0; - - u = uvs[index2]; - v = uvs[index2 + 1]; - - color = (isColorArray) ? colors[index1] : colors; - alpha = (isAlphaArray) ? alphas[index1] : alphas; - - normalX = 0; - normalY = 0; - normalZ = 0; - - if (normals) - { - normalX = normals[index3]; - normalY = normals[index3 + 1]; - normalZ = (containsZ) ? normals[index3 + 2] : 0; - } - - result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); - } - } - else - { - var uvIndex = 0; - var colorIndex = 0; - - for (i = 0; i < vertices.length; i += iInc) - { - x = vertices[i]; - y = vertices[i + 1]; - z = (containsZ) ? vertices[i + 2] : 0; - - u = uvs[uvIndex]; - v = uvs[uvIndex + 1]; - - color = (isColorArray) ? colors[colorIndex] : colors; - alpha = (isAlphaArray) ? alphas[colorIndex] : alphas; - - normalX = 0; - normalY = 0; - normalZ = 0; - - if (normals) - { - normalX = normals[i]; - normalY = normals[i + 1]; - normalZ = (containsZ) ? normals[i + 2] : 0; - } - - result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); - - uvIndex += 2; - colorIndex++; - } - } - - for (i = 0; i < result.verts.length; i += 3) - { - var vert1 = result.verts[i]; - var vert2 = result.verts[i + 1]; - var vert3 = result.verts[i + 2]; - - result.faces.push(new Face(vert1, vert2, vert3)); - } - - return result; -}; - -module.exports = GenerateVerts; - - -/***/ }), -/* 458 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Face = __webpack_require__(111); -var Matrix4 = __webpack_require__(65); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); - -var tempPosition = new Vector3(); -var tempRotation = new Vector3(); -var tempMatrix = new Matrix4(); - -/** - * This method will return an object containing Face and Vertex instances, generated - * from the parsed triangulated OBJ Model data given to this function. - * - * The obj data should have been parsed in advance via the ParseObj function: - * - * ```javascript - * var data = Phaser.Geom.Mesh.ParseObj(rawData, flipUV); - * - * var results = GenerateObjVerts(data); - * ``` - * - * Alternatively, you can parse obj files loaded via the OBJFile loader: - * - * ```javascript - * preload () - * { - * this.load.obj('alien', 'assets/3d/alien.obj); - * } - * - * var results = GenerateObjVerts(this.cache.obj.get('alien)); - * ``` - * - * Make sure your 3D package has triangulated the model data prior to exporting it. - * - * You can use the data returned by this function to populate the vertices of a Mesh Game Object. - * - * You may add multiple models to a single Mesh, although they will act as one when - * moved or rotated. You can scale the model data, should it be too small (or large) to visualize. - * You can also offset the model via the `x`, `y` and `z` parameters. - * - * @function Phaser.Geom.Mesh.GenerateObjVerts - * @since 3.50.0 - * - * @param {Phaser.Types.Geom.Mesh.OBJData} data - The parsed OBJ model data. - * @param {Phaser.GameObjects.Mesh} [mesh] - An optional Mesh Game Object. If given, the generated Faces will be automatically added to this Mesh. Set to `null` to skip. - * @param {number} [scale=1] - An amount to scale the model data by. Use this if the model has exported too small, or large, to see. - * @param {number} [x=0] - Translate the model x position by this amount. - * @param {number} [y=0] - Translate the model y position by this amount. - * @param {number} [z=0] - Translate the model z position by this amount. - * @param {number} [rotateX=0] - Rotate the model on the x axis by this amount, in radians. - * @param {number} [rotateY=0] - Rotate the model on the y axis by this amount, in radians. - * @param {number} [rotateZ=0] - Rotate the model on the z axis by this amount, in radians. - * @param {boolean} [zIsUp=true] - Is the z axis up (true), or is y axis up (false)? - * - * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. - */ -var GenerateObjVerts = function (data, mesh, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) -{ - if (scale === undefined) { scale = 1; } - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (z === undefined) { z = 0; } - if (rotateX === undefined) { rotateX = 0; } - if (rotateY === undefined) { rotateY = 0; } - if (rotateZ === undefined) { rotateZ = 0; } - if (zIsUp === undefined) { zIsUp = true; } - - var result = { - faces: [], - verts: [] - }; - - var materials = data.materials; - - tempPosition.set(x, y, z); - tempRotation.set(rotateX, rotateY, rotateZ); - tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); - - for (var m = 0; m < data.models.length; m++) - { - var model = data.models[m]; - - var vertices = model.vertices; - var textureCoords = model.textureCoords; - var faces = model.faces; - - for (var i = 0; i < faces.length; i++) - { - var face = faces[i]; - - var v1 = face.vertices[0]; - var v2 = face.vertices[1]; - var v3 = face.vertices[2]; - - var m1 = vertices[v1.vertexIndex]; - var m2 = vertices[v2.vertexIndex]; - var m3 = vertices[v3.vertexIndex]; - - var t1 = v1.textureCoordsIndex; - var t2 = v2.textureCoordsIndex; - var t3 = v3.textureCoordsIndex; - - var uv1 = (t1 === -1) ? { u: 0, v: 1 } : textureCoords[t1]; - var uv2 = (t2 === -1) ? { u: 0, v: 0 } : textureCoords[t2]; - var uv3 = (t3 === -1) ? { u: 1, v: 1 } : textureCoords[t3]; - - var color = 0xffffff; - - if (face.material !== '' && materials[face.material]) - { - color = materials[face.material]; - } - - var vert1 = new Vertex(m1.x * scale, m1.y * scale, m1.z * scale, uv1.u, uv1.v, color).transformMat4(tempMatrix); - var vert2 = new Vertex(m2.x * scale, m2.y * scale, m2.z * scale, uv2.u, uv2.v, color).transformMat4(tempMatrix); - var vert3 = new Vertex(m3.x * scale, m3.y * scale, m3.z * scale, uv3.u, uv3.v, color).transformMat4(tempMatrix); - - result.verts.push(vert1, vert2, vert3); - result.faces.push(new Face(vert1, vert2, vert3)); - } - } - - if (mesh) - { - mesh.faces = mesh.faces.concat(result.faces); - mesh.vertices = mesh.vertices.concat(result.verts); - } - - return result; -}; - -module.exports = GenerateObjVerts; - - -/***/ }), -/* 459 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Circle = __webpack_require__(61); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var RGB = __webpack_require__(195); -var Utils = __webpack_require__(12); - -/** - * @classdesc - * A 2D point light. - * - * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. - * - * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. - * - * They can also simply be used to represent a point light for your own purposes. - * - * @class Light - * @extends Phaser.Geom.Circle - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible - * - * @param {number} x - The horizontal position of the light. - * @param {number} y - The vertical position of the light. - * @param {number} radius - The radius of the light. - * @param {number} r - The red color of the light. A value between 0 and 1. - * @param {number} g - The green color of the light. A value between 0 and 1. - * @param {number} b - The blue color of the light. A value between 0 and 1. - * @param {number} intensity - The intensity of the light. - */ -var Light = new Class({ - - Extends: Circle, - - Mixins: [ - Components.ScrollFactor, - Components.Visible - ], - - initialize: - - function Light (x, y, radius, r, g, b, intensity) - { - Circle.call(this, x, y, radius); - - /** - * The color of the light. - * - * @name Phaser.GameObjects.Light#color - * @type {Phaser.Display.RGB} - * @since 3.50.0 - */ - this.color = new RGB(r, g, b); - - /** - * The intensity of the light. - * - * @name Phaser.GameObjects.Light#intensity - * @type {number} - * @since 3.50.0 - */ - this.intensity = intensity; - - /** - * 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 {number} - * @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; - - this.setScrollFactor(1, 1); - }, - - /** - * 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.Light#willRender - * @since 3.50.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 !(Light.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); - }, - - /** - * Set the color of the light from a single integer RGB value. - * - * @method Phaser.GameObjects.Light#setColor - * @since 3.0.0 - * - * @param {number} rgb - The integer RGB color of the light. - * - * @return {this} This Light object. - */ - setColor: function (rgb) - { - var color = Utils.getFloatsFromUintRGB(rgb); - - this.color.set(color[0], color[1], color[2]); - - return this; - }, - - /** - * Set the intensity of the light. - * - * @method Phaser.GameObjects.Light#setIntensity - * @since 3.0.0 - * - * @param {number} intensity - The intensity of the light. - * - * @return {this} This Light object. - */ - setIntensity: function (intensity) - { - this.intensity = intensity; - - return this; - }, - - /** - * Set the radius of the light. - * - * @method Phaser.GameObjects.Light#setRadius - * @since 3.0.0 - * - * @param {number} radius - The radius of the light. - * - * @return {this} This Light object. - */ - setRadius: function (radius) - { - this.radius = radius; - - return this; - } - -}); - -/** - * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. - * - * @constant {number} RENDER_MASK - * @memberof Phaser.GameObjects.Light - * @default - */ -Light.RENDER_MASK = 15; - -module.exports = Light; - - -/***/ }), -/* 460 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircleToRectangle = __webpack_require__(149); -var Class = __webpack_require__(0); -var DistanceBetween = __webpack_require__(48); -var Light = __webpack_require__(459); -var PointLight = __webpack_require__(148); -var RGB = __webpack_require__(195); -var SpliceOne = __webpack_require__(74); -var StableSort = __webpack_require__(79); -var Utils = __webpack_require__(12); - -/** - * @callback LightForEach - * - * @param {Phaser.GameObjects.Light} light - The Light. - */ - -/** - * @classdesc - * Manages Lights for a Scene. - * - * Affects the rendering of Game Objects using the `Light2D` pipeline. - * - * @class LightsManager - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - */ -var LightsManager = new Class({ - - initialize: - - function LightsManager () - { - /** - * The Lights in the Scene. - * - * @name Phaser.GameObjects.LightsManager#lights - * @type {Phaser.GameObjects.Light[]} - * @default [] - * @since 3.0.0 - */ - this.lights = []; - - /** - * The ambient color. - * - * @name Phaser.GameObjects.LightsManager#ambientColor - * @type {Phaser.Display.RGB} - * @since 3.50.0 - */ - this.ambientColor = new RGB(0.1, 0.1, 0.1); - - /** - * Whether the Lights Manager is enabled. - * - * @name Phaser.GameObjects.LightsManager#active - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.active = false; - - /** - * The maximum number of lights that a single Camera and the lights shader can process. - * Change this via the `maxLights` property in your game config, as it cannot be changed at runtime. - * - * @name Phaser.GameObjects.LightsManager#maxLights - * @type {number} - * @readonly - * @since 3.15.0 - */ - this.maxLights = -1; - - /** - * The number of lights that the LightPipeline processed in the _previous_ frame. - * - * @name Phaser.GameObjects.LightsManager#visibleLights - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.visibleLights = 0; - }, - - addPointLight: function (x, y, color, radius, intensity) - { - return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity)); - }, - - /** - * Enable the Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#enable - * @since 3.0.0 - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - enable: function () - { - if (this.maxLights === -1) - { - this.maxLights = this.scene.sys.renderer.config.maxLights; - } - - this.active = true; - - return this; - }, - - /** - * Disable the Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#disable - * @since 3.0.0 - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - disable: function () - { - this.active = false; - - return this; - }, - - /** - * Get all lights that can be seen by the given Camera. - * - * It will automatically cull lights that are outside the world view of the Camera. - * - * If more lights are returned than supported by the pipeline, the lights are then culled - * based on the distance from the center of the camera. Only those closest are rendered. - * - * @method Phaser.GameObjects.LightsManager#getLights - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. - * - * @return {Phaser.GameObjects.Light[]} The culled Lights. - */ - getLights: function (camera) - { - var lights = this.lights; - var worldView = camera.worldView; - - var visibleLights = []; - - for (var i = 0; i < lights.length; i++) - { - var light = lights[i]; - - if (light.willRender(camera) && CircleToRectangle(light, worldView)) - { - visibleLights.push({ - light: light, - distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY) - }); - } - } - - if (visibleLights.length > this.maxLights) - { - // We've got too many lights, so sort by distance from camera and cull those far away - // This isn't ideal because it doesn't factor in the radius of the lights, but it'll do for now - // and is significantly better than we had before! - - StableSort(visibleLights, this.sortByDistance); - - visibleLights = visibleLights.slice(0, this.maxLights); - } - - this.visibleLights = visibleLights.length; - - return visibleLights; - }, - - sortByDistance: function (a, b) - { - return (a.distance >= b.distance); - }, - - /** - * Set the ambient light color. - * - * @method Phaser.GameObjects.LightsManager#setAmbientColor - * @since 3.0.0 - * - * @param {number} rgb - The integer RGB color of the ambient light. - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - setAmbientColor: function (rgb) - { - var color = Utils.getFloatsFromUintRGB(rgb); - - this.ambientColor.set(color[0], color[1], color[2]); - - return this; - }, - - /** - * Returns the maximum number of Lights allowed to appear at once. - * - * @method Phaser.GameObjects.LightsManager#getMaxVisibleLights - * @since 3.0.0 - * - * @return {number} The maximum number of Lights allowed to appear at once. - */ - getMaxVisibleLights: function () - { - return this.maxLights; - }, - - /** - * Get the number of Lights managed by this Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#getLightCount - * @since 3.0.0 - * - * @return {number} The number of Lights managed by this Lights Manager. - */ - getLightCount: function () - { - return this.lights.length; - }, - - /** - * Add a Light. - * - * @method Phaser.GameObjects.LightsManager#addLight - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal position of the Light. - * @param {number} [y=0] - The vertical position of the Light. - * @param {number} [radius=100] - The radius of the Light. - * @param {number} [rgb=0xffffff] - The integer RGB color of the light. - * @param {number} [intensity=1] - The intensity of the Light. - * - * @return {Phaser.GameObjects.Light} The Light that was added. - */ - addLight: function (x, y, radius, rgb, intensity) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 128; } - if (rgb === undefined) { rgb = 0xffffff; } - if (intensity === undefined) { intensity = 1; } - - var color = Utils.getFloatsFromUintRGB(rgb); - - var light = new Light(x, y, radius, color[0], color[1], color[2], intensity); - - this.lights.push(light); - - return light; - }, - - /** - * Remove a Light. - * - * @method Phaser.GameObjects.LightsManager#removeLight - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Light} light - The Light to remove. - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - removeLight: function (light) - { - var index = this.lights.indexOf(light); - - if (index >= 0) - { - SpliceOne(this.lights, index); - } - - return this; - }, - - /** - * Shut down the Lights Manager. - * - * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and - * culled Lights. - * - * @method Phaser.GameObjects.LightsManager#shutdown - * @since 3.0.0 - */ - shutdown: function () - { - this.lights.length = 0; - }, - - /** - * Destroy the Lights Manager. - * - * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. - * - * @method Phaser.GameObjects.LightsManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - } - -}); - -module.exports = LightsManager; - - -/***/ }), -/* 461 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(55); -var Extend = __webpack_require__(19); - -/** - * @namespace Phaser.Geom - */ - -var Geom = { - - Circle: __webpack_require__(1185), - Ellipse: __webpack_require__(1195), - Intersects: __webpack_require__(462), - Line: __webpack_require__(1215), - Mesh: __webpack_require__(1237), - Point: __webpack_require__(1240), - Polygon: __webpack_require__(1254), - Rectangle: __webpack_require__(480), - Triangle: __webpack_require__(1287) - -}; - -// Merge in the consts -Geom = Extend(false, Geom, CONST); - -module.exports = Geom; - - -/***/ }), -/* 462 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Geom.Intersects - */ - -module.exports = { - - CircleToCircle: __webpack_require__(226), - CircleToRectangle: __webpack_require__(149), - GetCircleToCircle: __webpack_require__(1205), - GetCircleToRectangle: __webpack_require__(1206), - GetLineToCircle: __webpack_require__(227), - GetLineToLine: __webpack_require__(463), - GetLineToPoints: __webpack_require__(464), - GetLineToPolygon: __webpack_require__(465), - GetLineToRectangle: __webpack_require__(229), - GetRaysFromPointToPolygon: __webpack_require__(1207), - GetRectangleIntersection: __webpack_require__(1208), - GetRectangleToRectangle: __webpack_require__(1209), - GetRectangleToTriangle: __webpack_require__(1210), - GetTriangleToCircle: __webpack_require__(1211), - GetTriangleToLine: __webpack_require__(470), - GetTriangleToTriangle: __webpack_require__(1212), - LineToCircle: __webpack_require__(228), - LineToLine: __webpack_require__(91), - LineToRectangle: __webpack_require__(466), - PointToLine: __webpack_require__(474), - PointToLineSegment: __webpack_require__(1213), - RectangleToRectangle: __webpack_require__(112), - RectangleToTriangle: __webpack_require__(467), - RectangleToValues: __webpack_require__(1214), - TriangleToCircle: __webpack_require__(469), - TriangleToLine: __webpack_require__(471), - TriangleToTriangle: __webpack_require__(472) - -}; - - -/***/ }), -/* 463 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); - -/** - * Checks for intersection between the two line segments and returns the intersection point as a Vector3, - * or `null` if the lines are parallel, or do not intersect. - * - * The `z` property of the Vector3 contains the intersection distance, which can be used to find - * the closest intersecting point from a group of line segments. - * - * @function Phaser.Geom.Intersects.GetLineToLine - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line1 - The first line segment to check. - * @param {Phaser.Geom.Line} line2 - The second line segment to check. - * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. - * - * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. - */ -var GetLineToLine = function (line1, line2, out) -{ - var x1 = line1.x1; - var y1 = line1.y1; - var x2 = line1.x2; - var y2 = line1.y2; - - var x3 = line2.x1; - var y3 = line2.y1; - var x4 = line2.x2; - var y4 = line2.y2; - - var dx1 = x2 - x1; - var dy1 = y2 - y1; - - var dx2 = x4 - x3; - var dy2 = y4 - y3; - - var denom = dy2 * dx1 - dx2 * dy1; - - // Make sure there is not a division by zero - this also indicates that the lines are parallel. - // If numA and numB were both equal to zero the lines would be on top of each other (coincidental). - // This check is not done because it is not necessary for this implementation (the parallel check accounts for this). - - if (dx1 === 0 || denom === 0) - { - return false; - } - - var T2 = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); - var T1 = (x3 + dx2 * T2 - x1) / dx1; - - // Intersects? - if (T1 < 0 || T2 < 0 || T2 > 1) - { - return null; - } - - if (out === undefined) - { - out = new Vector3(); - } - - return out.set( - x1 + dx1 * T1, - y1 + dy1 * T1, - T1 - ); -}; - -module.exports = GetLineToLine; - - -/***/ }), -/* 464 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); -var GetLineToLine = __webpack_require__(463); -var Line = __webpack_require__(45); - -// Temp calculation segment -var segment = new Line(); - -// Temp vec3 -var tempIntersect = new Vector3(); - -/** - * Checks for the closest point of intersection between a line segment and an array of points, where each pair - * of points are converted to line segments for the intersection tests. - * - * If no intersection is found, this function returns `null`. - * - * If intersection was found, a Vector3 is returned with the following properties: - * - * The `x` and `y` components contain the point of the intersection. - * The `z` component contains the closest distance. - * - * @function Phaser.Geom.Intersects.GetLineToPoints - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Math.Vector2[] | Phaser.Geom.Point[]} points - An array of points to check. - * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. - * - * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. - */ -var GetLineToPoints = function (line, points, out) -{ - if (out === undefined) { out = new Vector3(); } - - var closestIntersect = false; - - // Reset our vec3s - out.set(); - tempIntersect.set(); - - var prev = points[0]; - - for (var i = 1; i < points.length; i++) - { - var current = points[i]; - - segment.setTo(prev.x, prev.y, current.x, current.y); - - prev = current; - - if (GetLineToLine(line, segment, tempIntersect)) - { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.copy(tempIntersect); - - closestIntersect = true; - } - } - } - - return (closestIntersect) ? out : null; -}; - -module.exports = GetLineToPoints; - - -/***/ }), -/* 465 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); -var Vector4 = __webpack_require__(138); -var GetLineToPoints = __webpack_require__(464); - -// Temp vec3 -var tempIntersect = new Vector3(); - -/** - * Checks for the closest point of intersection between a line segment and an array of polygons. - * - * If no intersection is found, this function returns `null`. - * - * If intersection was found, a Vector4 is returned with the following properties: - * - * The `x` and `y` components contain the point of the intersection. - * The `z` component contains the closest distance. - * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. - * - * @function Phaser.Geom.Intersects.GetLineToPolygon - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check. - * @param {Phaser.Math.Vector4} [out] - A Vector4 to store the intersection results in. - * - * @return {Phaser.Math.Vector4} A Vector4 containing the intersection results, or `null`. - */ -var GetLineToPolygon = function (line, polygons, out) -{ - if (out === undefined) { out = new Vector4(); } - - if (!Array.isArray(polygons)) - { - polygons = [ polygons ]; - } - - var closestIntersect = false; - - // Reset our vec4s - out.set(); - tempIntersect.set(); - - for (var i = 0; i < polygons.length; i++) - { - if (GetLineToPoints(line, polygons[i].points, tempIntersect)) - { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); - - closestIntersect = true; - } - } - } - - return (closestIntersect) ? out : null; -}; - -module.exports = GetLineToPolygon; - - -/***/ }), -/* 466 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Checks for intersection between the Line and a Rectangle shape, or a rectangle-like - * object, with public `x`, `y`, `right` and `bottom` properties, such as a Sprite or Body. - * - * An intersection is considered valid if: - * - * The line starts within, or ends within, the Rectangle. - * The line segment intersects one of the 4 rectangle edges. - * - * The for the purposes of this function rectangles are considered 'solid'. - * - * @function Phaser.Geom.Intersects.LineToRectangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The Line to check for intersection. - * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle to check for intersection. - * - * @return {boolean} `true` if the Line and the Rectangle intersect, `false` otherwise. - */ -var LineToRectangle = function (line, rect) -{ - var x1 = line.x1; - var y1 = line.y1; - - var x2 = line.x2; - var y2 = line.y2; - - var bx1 = rect.x; - var by1 = rect.y; - var bx2 = rect.right; - var by2 = rect.bottom; - - var t = 0; - - // If the start or end of the line is inside the rect then we assume - // collision, as rects are solid for our use-case. - - if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || - (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) - { - return true; - } - - if (x1 < bx1 && x2 >= bx1) - { - // Left edge - t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); - - if (t > by1 && t <= by2) - { - return true; - } - } - else if (x1 > bx2 && x2 <= bx2) - { - // Right edge - t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); - - if (t >= by1 && t <= by2) - { - return true; - } - } - - if (y1 < by1 && y2 >= by1) - { - // Top edge - t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); - - if (t >= bx1 && t <= bx2) - { - return true; - } - } - else if (y1 > by2 && y2 <= by2) - { - // Bottom edge - t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); - - if (t >= bx1 && t <= bx2) - { - return true; - } - } - - return false; -}; - -module.exports = LineToRectangle; - - -/***/ }), -/* 467 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToLine = __webpack_require__(91); -var Contains = __webpack_require__(56); -var ContainsArray = __webpack_require__(230); -var Decompose = __webpack_require__(468); - -/** - * Checks for intersection between Rectangle shape and Triangle shape. - * - * @function Phaser.Geom.Intersects.RectangleToTriangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. - * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. - * - * @return {boolean} A value of `true` if objects intersect; otherwise `false`. - */ -var RectangleToTriangle = function (rect, triangle) -{ - // First the cheapest ones: - - if ( - triangle.left > rect.right || - triangle.right < rect.left || - triangle.top > rect.bottom || - triangle.bottom < rect.top) - { - return false; - } - - var triA = triangle.getLineA(); - var triB = triangle.getLineB(); - var triC = triangle.getLineC(); - - // Are any of the triangle points within the rectangle? - - if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) - { - return true; - } - - if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) - { - return true; - } - - if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) - { - return true; - } - - // Cheap tests over, now to see if any of the lines intersect ... - - var rectA = rect.getLineA(); - var rectB = rect.getLineB(); - var rectC = rect.getLineC(); - var rectD = rect.getLineD(); - - if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) - { - return true; - } - - if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) - { - return true; - } - - if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) - { - return true; - } - - // None of the lines intersect, so are any rectangle points within the triangle? - - var points = Decompose(rect); - var within = ContainsArray(triangle, points, true); - - return (within.length > 0); -}; - -module.exports = RectangleToTriangle; - - -/***/ }), -/* 468 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Create an array of points for each corner of a Rectangle - * If an array is specified, each point object will be added to the end of the array, otherwise a new array will be created. - * - * @function Phaser.Geom.Rectangle.Decompose - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle object to be decomposed. - * @param {array} [out] - If provided, each point will be added to this array. - * - * @return {array} Will return the array you specified or a new array containing the points of the Rectangle. - */ -var Decompose = function (rect, out) -{ - if (out === undefined) { out = []; } - - out.push({ x: rect.x, y: rect.y }); - out.push({ x: rect.right, y: rect.y }); - out.push({ x: rect.right, y: rect.bottom }); - out.push({ x: rect.x, y: rect.bottom }); - - return out; -}; - -module.exports = Decompose; - - -/***/ }), -/* 469 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToCircle = __webpack_require__(228); -var Contains = __webpack_require__(110); - -/** - * Checks if a Triangle and a Circle intersect. - * - * A Circle intersects a Triangle if its center is located within it or if any of the Triangle's sides intersect the Circle. As such, the Triangle and the Circle are considered "solid" for the intersection. - * - * @function Phaser.Geom.Intersects.TriangleToCircle - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check for intersection. - * @param {Phaser.Geom.Circle} circle - The Circle to check for intersection. - * - * @return {boolean} `true` if the Triangle and the `Circle` intersect, otherwise `false`. - */ -var TriangleToCircle = function (triangle, circle) -{ - // First the cheapest ones: - - if ( - triangle.left > circle.right || - triangle.right < circle.left || - triangle.top > circle.bottom || - triangle.bottom < circle.top) - { - return false; - } - - if (Contains(triangle, circle.x, circle.y)) - { - return true; - } - - if (LineToCircle(triangle.getLineA(), circle)) - { - return true; - } - - if (LineToCircle(triangle.getLineB(), circle)) - { - return true; - } - - if (LineToCircle(triangle.getLineC(), circle)) - { - return true; - } - - return false; -}; - -module.exports = TriangleToCircle; - - -/***/ }), -/* 470 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); -var TriangleToLine = __webpack_require__(471); -var LineToLine = __webpack_require__(91); - -/** - * Checks if a Triangle and a Line intersect, and returns the intersection points as a Point object array. - * - * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". - * - * @function Phaser.Geom.Intersects.GetTriangleToLine - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. - * @param {Phaser.Geom.Line} line - The Line to check with. - * @param {array} [out] - An optional array in which to store the points of intersection. - * - * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. - */ -var GetTriangleToLine = function (triangle, line, out) -{ - if (out === undefined) { out = []; } - - if (TriangleToLine(triangle, line)) - { - var lineA = triangle.getLineA(); - var lineB = triangle.getLineB(); - var lineC = triangle.getLineC(); - - var output = [ new Point(), new Point(), new Point() ]; - - var result = [ - LineToLine(lineA, line, output[0]), - LineToLine(lineB, line, output[1]), - LineToLine(lineC, line, output[2]) - ]; - - for (var i = 0; i < 3; i++) - { - if (result[i]) { out.push(output[i]); } - } - } - - return out; -}; - -module.exports = GetTriangleToLine; - - -/***/ }), -/* 471 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToLine = __webpack_require__(91); - -/** - * Checks if a Triangle and a Line intersect. - * - * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". - * - * @function Phaser.Geom.Intersects.TriangleToLine - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. - * @param {Phaser.Geom.Line} line - The Line to check with. - * - * @return {boolean} `true` if the Triangle and the Line intersect, otherwise `false`. - */ -var TriangleToLine = function (triangle, line) -{ - // If the Triangle contains either the start or end point of the line, it intersects - if (triangle.contains(line.x1, line.y1) || triangle.contains(line.x2, line.y2)) - { - return true; - } - - // Now check the line against each line of the Triangle - if (LineToLine(triangle.getLineA(), line)) - { - return true; - } - - if (LineToLine(triangle.getLineB(), line)) - { - return true; - } - - if (LineToLine(triangle.getLineC(), line)) - { - return true; - } - - return false; -}; - -module.exports = TriangleToLine; - - -/***/ }), -/* 472 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ContainsArray = __webpack_require__(230); -var Decompose = __webpack_require__(473); -var LineToLine = __webpack_require__(91); - -/** - * Checks if two Triangles intersect. - * - * A Triangle intersects another Triangle if any pair of their lines intersects or if any point of one Triangle is within the other Triangle. Thus, the Triangles are considered "solid". - * - * @function Phaser.Geom.Intersects.TriangleToTriangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangleA - The first Triangle to check for intersection. - * @param {Phaser.Geom.Triangle} triangleB - The second Triangle to check for intersection. - * - * @return {boolean} `true` if the Triangles intersect, otherwise `false`. - */ -var TriangleToTriangle = function (triangleA, triangleB) -{ - // First the cheapest ones: - - if ( - triangleA.left > triangleB.right || - triangleA.right < triangleB.left || - triangleA.top > triangleB.bottom || - triangleA.bottom < triangleB.top) - { - return false; - } - - var lineAA = triangleA.getLineA(); - var lineAB = triangleA.getLineB(); - var lineAC = triangleA.getLineC(); - - var lineBA = triangleB.getLineA(); - var lineBB = triangleB.getLineB(); - var lineBC = triangleB.getLineC(); - - // Now check the lines against each line of TriangleB - if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) - { - return true; - } - - if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) - { - return true; - } - - if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) - { - return true; - } - - // Nope, so check to see if any of the points of triangleA are within triangleB - - var points = Decompose(triangleA); - var within = ContainsArray(triangleB, points, true); - - if (within.length > 0) - { - return true; - } - - // Finally check to see if any of the points of triangleB are within triangleA - - points = Decompose(triangleB); - within = ContainsArray(triangleA, points, true); - - if (within.length > 0) - { - return true; - } - - return false; -}; - -module.exports = TriangleToTriangle; - - -/***/ }), -/* 473 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Decomposes a Triangle into an array of its points. - * - * @function Phaser.Geom.Triangle.Decompose - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to decompose. - * @param {array} [out] - An array to store the points into. - * - * @return {array} The provided `out` array, or a new array if none was provided, with three objects with `x` and `y` properties representing each point of the Triangle appended to it. - */ -var Decompose = function (triangle, out) -{ - if (out === undefined) { out = []; } - - out.push({ x: triangle.x1, y: triangle.y1 }); - out.push({ x: triangle.x2, y: triangle.y2 }); - out.push({ x: triangle.x3, y: triangle.y3 }); - - return out; -}; - -module.exports = Decompose; - - -/***/ }), -/* 474 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Florian Mertens - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Checks if the a Point falls between the two end-points of a Line, based on the given line thickness. - * - * Assumes that the line end points are circular, not square. - * - * @function Phaser.Geom.Intersects.PointToLine - * @since 3.0.0 - * - * @param {(Phaser.Geom.Point|any)} point - The point, or point-like object to check. - * @param {Phaser.Geom.Line} line - The line segment to test for intersection on. - * @param {number} [lineThickness=1] - The line thickness. Assumes that the line end points are circular. - * - * @return {boolean} `true` if the Point falls on the Line, otherwise `false`. - */ -var PointToLine = function (point, line, lineThickness) -{ - if (lineThickness === undefined) { lineThickness = 1; } - - var x1 = line.x1; - var y1 = line.y1; - - var x2 = line.x2; - var y2 = line.y2; - - var px = point.x; - var py = point.y; - - var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); - - if (L2 === 0) - { - return false; - } - - var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; - - // Assume line thickness is circular - if (r < 0) - { - // Outside line1 - return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); - } - else if ((r >= 0) && (r <= 1)) - { - // On the line segment - var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; - - return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); - } - else - { - // Outside line2 - return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); - } -}; - -module.exports = PointToLine; - - -/***/ }), -/* 475 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var MATH_CONST = __webpack_require__(14); -var Wrap = __webpack_require__(64); -var Angle = __webpack_require__(92); - -/** - * Get the angle of the normal of the given line in radians. - * - * @function Phaser.Geom.Line.NormalAngle - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the angle of the normal of. - * - * @return {number} The angle of the normal of the line in radians. - */ -var NormalAngle = function (line) -{ - var angle = Angle(line) - MATH_CONST.TAU; - - return Wrap(angle, -Math.PI, Math.PI); -}; - -module.exports = NormalAngle; - - -/***/ }), -/* 476 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var flip = true; - -var defaultModelName = 'untitled'; -var currentGroup = ''; -var currentMaterial = ''; - -/** - * @ignore - */ -function stripComments (line) -{ - var idx = line.indexOf('#'); - - return (idx > -1) ? line.substring(0, idx) : line; -} - -/** - * @ignore - */ -function currentModel (result) -{ - if (result.models.length === 0) - { - result.models.push({ - faces: [], - name: defaultModelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); - } - - currentGroup = ''; - - return result.models[result.models.length - 1]; -} - -/** - * @ignore - */ -function parseObject (lineItems, result) -{ - var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName; - - result.models.push({ - faces: [], - name: modelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); - - currentGroup = ''; -} - -/** - * @ignore - */ -function parseGroup (lineItems) -{ - if (lineItems.length === 2) - { - currentGroup = lineItems[1]; - } -} - -/** - * @ignore - */ -function parseVertexCoords (lineItems, result) -{ - var len = lineItems.length; - - var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - currentModel(result).vertices.push({ x: x, y: y, z: z }); -} - -/** - * @ignore - */ -function parseTextureCoords (lineItems, result) -{ - var len = lineItems.length; - - var u = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var v = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var w = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - if (isNaN(u)) - { - u = 0; - } - - if (isNaN(v)) - { - v = 0; - } - - if (isNaN(w)) - { - w = 0; - } - - if (flip) - { - v = 1 - v; - } - - currentModel(result).textureCoords.push({ u: u, v: v, w: w }); -} - -/** - * @ignore - */ -function parseVertexNormal (lineItems, result) -{ - var len = lineItems.length; - - var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - currentModel(result).vertexNormals.push({ x: x, y: y, z: z }); -} - -/** - * @ignore - */ -function parsePolygon (lineItems, result) -{ - var totalVertices = lineItems.length - 1; - - if (totalVertices < 3) - { - return; - } - - var face = { - group: currentGroup, - material: currentMaterial, - vertices: [] - }; - - for (var i = 0; i < totalVertices; i++) - { - var vertexString = lineItems[i + 1]; - var vertexValues = vertexString.split('/'); - var vvLen = vertexValues.length; - - if (vvLen < 1 || vvLen > 3) - { - continue; - } - - var vertexIndex = 0; - var textureCoordsIndex = 0; - var vertexNormalIndex = 0; - - vertexIndex = parseInt(vertexValues[0], 10); - - if (vvLen > 1 && vertexValues[1] !== '') - { - textureCoordsIndex = parseInt(vertexValues[1], 10); - } - - if (vvLen > 2) - { - vertexNormalIndex = parseInt(vertexValues[2], 10); - } - - if (vertexIndex !== 0) - { - // Negative vertex indices refer to the nth last defined vertex - // convert these to postive indices for simplicity - if (vertexIndex < 0) - { - vertexIndex = currentModel(result).vertices.length + 1 + vertexIndex; - } - - textureCoordsIndex -= 1; - vertexIndex -= 1; - vertexNormalIndex -= 1; - - face.vertices.push({ - textureCoordsIndex: textureCoordsIndex, - vertexIndex: vertexIndex, - vertexNormalIndex: vertexNormalIndex - }); - } - } - - currentModel(result).faces.push(face); -} - -/** - * @ignore - */ -function parseMtlLib (lineItems, result) -{ - if (lineItems.length >= 2) - { - result.materialLibraries.push(lineItems[1]); - } -} - -/** - * @ignore - */ -function parseUseMtl (lineItems) -{ - if (lineItems.length >= 2) - { - currentMaterial = lineItems[1]; - } -} - -/** - * Parses a Wavefront OBJ File, extracting the models from it and returning them in an array. - * - * The model data *must* be triangulated for a Mesh Game Object to be able to render it. - * - * @function Phaser.Geom.Mesh.ParseObj - * @since 3.50.0 - * - * @param {string} data - The OBJ File data as a raw string. - * @param {boolean} [flipUV=true] - Flip the UV coordinates? - * - * @return {Phaser.Types.Geom.Mesh.OBJData} The parsed model and material data. - */ -var ParseObj = function (data, flipUV) -{ - if (flipUV === undefined) { flipUV = true; } - - flip = flipUV; - - // Store results in here - var result = { - materials: {}, - materialLibraries: [], - models: [] - }; - - currentGroup = ''; - currentMaterial = ''; - - var lines = data.split('\n'); - - for (var i = 0; i < lines.length; i++) - { - var line = stripComments(lines[i]); - - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) - { - case 'o': - // Start A New Model - parseObject(lineItems, result); - break; - - case 'g': - // Start a new polygon group - parseGroup(lineItems); - break; - - case 'v': - // Define a vertex for the current model - parseVertexCoords(lineItems, result); - break; - - case 'vt': - // Texture Coords - parseTextureCoords(lineItems, result); - break; - - case 'vn': - // Define a vertex normal for the current model - parseVertexNormal(lineItems, result); - break; - - case 'f': - // Define a Face/Polygon - parsePolygon(lineItems, result); - break; - - case 'mtllib': - // Reference to a material library file (.mtl) - parseMtlLib(lineItems, result); - break; - - case 'usemtl': - // Sets the current material to be applied to polygons defined from this point forward - parseUseMtl(lineItems); - break; - } - } - - return result; -}; - -module.exports = ParseObj; - - -/***/ }), -/* 477 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetColor = __webpack_require__(100); - -/** - * Takes a Wavefront Material file and extracts the diffuse reflectivity of the named - * materials, converts them to integer color values and returns them. - * - * This is used internally by the `addOBJ` and `addModel` methods, but is exposed for - * public consumption as well. - * - * Note this only works with diffuse values, specified in the `Kd r g b` format, where - * `g` and `b` are optional, but `r` is required. It does not support spectral rfl files, - * or any other material statement (such as `Ka` or `Ks`) - * - * @method Phaser.Geom.Mesh.ParseObjMaterial - * @since 3.50.0 - * - * @param {string} mtl - The OBJ MTL file as a raw string, i.e. loaded via `this.load.text`. - * - * @return {object} The parsed material colors, where each property of the object matches the material name. - */ -var ParseObjMaterial = function (mtl) -{ - var output = {}; - - var lines = mtl.split('\n'); - - var currentMaterial = ''; - - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if (line.indexOf('#') === 0 || line === '') - { - continue; - } - - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) - { - case 'newmtl': - { - currentMaterial = lineItems[1]; - break; - } - - // The diffuse reflectivity of the current material - // Support r, [g], [b] format, where g and b are optional - case 'kd': - { - var r = Math.floor(lineItems[1] * 255); - var g = (lineItems.length >= 2) ? Math.floor(lineItems[2] * 255) : r; - var b = (lineItems.length >= 3) ? Math.floor(lineItems[3] * 255) : r; - - output[currentMaterial] = GetColor(r, g, b); - - break; - } - } - } - - return output; -}; - -module.exports = ParseObjMaterial; - - -/***/ }), -/* 478 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Calculate the magnitude of the point, which equivalent to the length of the line from the origin to this point. - * - * @function Phaser.Geom.Point.GetMagnitude - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - The point to calculate the magnitude for - * - * @return {number} The resulting magnitude - */ -var GetMagnitude = function (point) -{ - return Math.sqrt((point.x * point.x) + (point.y * point.y)); -}; - -module.exports = GetMagnitude; - - -/***/ }), -/* 479 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Calculates the square of magnitude of given point.(Can be used for fast magnitude calculation of point) - * - * @function Phaser.Geom.Point.GetMagnitudeSq - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - Returns square of the magnitude/length of given point. - * - * @return {number} Returns square of the magnitude of given point. - */ -var GetMagnitudeSq = function (point) -{ - return (point.x * point.x) + (point.y * point.y); -}; - -module.exports = GetMagnitudeSq; - - -/***/ }), -/* 480 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -Rectangle.Area = __webpack_require__(1261); -Rectangle.Ceil = __webpack_require__(1262); -Rectangle.CeilAll = __webpack_require__(1263); -Rectangle.CenterOn = __webpack_require__(186); -Rectangle.Clone = __webpack_require__(1264); -Rectangle.Contains = __webpack_require__(56); -Rectangle.ContainsPoint = __webpack_require__(1265); -Rectangle.ContainsRect = __webpack_require__(481); -Rectangle.CopyFrom = __webpack_require__(1266); -Rectangle.Decompose = __webpack_require__(468); -Rectangle.Equals = __webpack_require__(1267); -Rectangle.FitInside = __webpack_require__(1268); -Rectangle.FitOutside = __webpack_require__(1269); -Rectangle.Floor = __webpack_require__(1270); -Rectangle.FloorAll = __webpack_require__(1271); -Rectangle.FromPoints = __webpack_require__(194); -Rectangle.FromXY = __webpack_require__(1272); -Rectangle.GetAspectRatio = __webpack_require__(232); -Rectangle.GetCenter = __webpack_require__(1273); -Rectangle.GetPoint = __webpack_require__(166); -Rectangle.GetPoints = __webpack_require__(300); -Rectangle.GetSize = __webpack_require__(1274); -Rectangle.Inflate = __webpack_require__(1275); -Rectangle.Intersection = __webpack_require__(1276); -Rectangle.MarchingAnts = __webpack_require__(310); -Rectangle.MergePoints = __webpack_require__(1277); -Rectangle.MergeRect = __webpack_require__(1278); -Rectangle.MergeXY = __webpack_require__(1279); -Rectangle.Offset = __webpack_require__(1280); -Rectangle.OffsetPoint = __webpack_require__(1281); -Rectangle.Overlaps = __webpack_require__(1282); -Rectangle.Perimeter = __webpack_require__(128); -Rectangle.PerimeterPoint = __webpack_require__(1283); -Rectangle.Random = __webpack_require__(169); -Rectangle.RandomOutside = __webpack_require__(1284); -Rectangle.SameDimensions = __webpack_require__(1285); -Rectangle.Scale = __webpack_require__(1286); -Rectangle.Union = __webpack_require__(419); - -module.exports = Rectangle; - - -/***/ }), -/* 481 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Tests if one rectangle fully contains another. - * - * @function Phaser.Geom.Rectangle.ContainsRect - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rectA - The first rectangle. - * @param {Phaser.Geom.Rectangle} rectB - The second rectangle. - * - * @return {boolean} True only if rectA fully contains rectB. - */ -var ContainsRect = function (rectA, rectB) -{ - // Volume check (if rectB volume > rectA then rectA cannot contain it) - if ((rectB.width * rectB.height) > (rectA.width * rectA.height)) - { - return false; - } - - return ( - (rectB.x > rectA.x && rectB.x < rectA.right) && - (rectB.right > rectA.x && rectB.right < rectA.right) && - (rectB.y > rectA.y && rectB.y < rectA.bottom) && - (rectB.bottom > rectA.y && rectB.bottom < rectA.bottom) - ); -}; - -module.exports = ContainsRect; - - -/***/ }), -/* 482 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); - -// The three medians (the lines drawn from the vertices to the bisectors of the opposite sides) -// meet in the centroid or center of mass (center of gravity). -// The centroid divides each median in a ratio of 2:1 - -/** - * Calculates the position of a Triangle's centroid, which is also its center of mass (center of gravity). - * - * The centroid is the point in a Triangle at which its three medians (the lines drawn from the vertices to the bisectors of the opposite sides) meet. It divides each one in a 2:1 ratio. - * - * @function Phaser.Geom.Triangle.Centroid - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the coordinates in. - * - * @return {(Phaser.Geom.Point|object)} The `out` object with modified `x` and `y` properties, or a new Point if none was provided. - */ -var Centroid = function (triangle, out) -{ - if (out === undefined) { out = new Point(); } - - out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; - out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; - - return out; -}; - -module.exports = Centroid; - - -/***/ }), -/* 483 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Moves each point (vertex) of a Triangle by a given offset, thus moving the entire Triangle by that offset. - * - * @function Phaser.Geom.Triangle.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to move. - * @param {number} x - The horizontal offset (distance) by which to move each point. Can be positive or negative. - * @param {number} y - The vertical offset (distance) by which to move each point. Can be positive or negative. - * - * @return {Phaser.Geom.Triangle} The modified Triangle. - */ -var Offset = function (triangle, x, y) -{ - triangle.x1 += x; - triangle.y1 += y; - - triangle.x2 += x; - triangle.y2 += y; - - triangle.x3 += x; - triangle.y3 += y; - - return triangle; -}; - -module.exports = Offset; - - -/***/ }), -/* 484 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); - -// The three angle bisectors of a triangle meet in one point called the incenter. -// It is the center of the incircle, the circle inscribed in the triangle. - -function getLength (x1, y1, x2, y2) -{ - var x = x1 - x2; - var y = y1 - y2; - var magnitude = (x * x) + (y * y); - - return Math.sqrt(magnitude); -} - -/** - * Calculates the position of the incenter of a Triangle object. This is the point where its three angle bisectors meet and it's also the center of the incircle, which is the circle inscribed in the triangle. - * - * @function Phaser.Geom.Triangle.InCenter - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to find the incenter of. - * @param {Phaser.Geom.Point} [out] - An optional Point in which to store the coordinates. - * - * @return {Phaser.Geom.Point} Point (x, y) of the center pixel of the triangle. - */ -var InCenter = function (triangle, out) -{ - if (out === undefined) { out = new Point(); } - - var x1 = triangle.x1; - var y1 = triangle.y1; - - var x2 = triangle.x2; - var y2 = triangle.y2; - - var x3 = triangle.x3; - var y3 = triangle.y3; - - var d1 = getLength(x3, y3, x2, y2); - var d2 = getLength(x1, y1, x3, y3); - var d3 = getLength(x2, y2, x1, y1); - - var p = d1 + d2 + d3; - - out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p; - out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p; - - return out; -}; - -module.exports = InCenter; - - -/***/ }), -/* 485 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Creates a new Pixel Perfect Handler function. - * - * Access via `InputPlugin.makePixelPerfect` rather than calling it directly. - * - * @function Phaser.Input.CreatePixelPerfectHandler - * @since 3.10.0 - * - * @param {Phaser.Textures.TextureManager} textureManager - A reference to the Texture Manager. - * @param {number} alphaTolerance - The alpha level that the pixel should be above to be included as a successful interaction. - * - * @return {function} The new Pixel Perfect Handler function. - */ -var CreatePixelPerfectHandler = function (textureManager, alphaTolerance) -{ - return function (hitArea, x, y, gameObject) - { - var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); - - return (alpha && alpha >= alphaTolerance); - }; -}; - -module.exports = CreatePixelPerfectHandler; - - -/***/ }), -/* 486 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Creates a new Interactive Object. - * - * This is called automatically by the Input Manager when you enable a Game Object for input. - * - * The resulting Interactive Object is mapped to the Game Object's `input` property. - * - * @function Phaser.Input.CreateInteractiveObject - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to which this Interactive Object is bound. - * @param {any} hitArea - The hit area for this Interactive Object. Typically a geometry shape, like a Rectangle or Circle. - * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - The 'contains' check callback that the hit area shape will use for all hit tests. - * - * @return {Phaser.Types.Input.InteractiveObject} The new Interactive Object. - */ -var CreateInteractiveObject = function (gameObject, hitArea, hitAreaCallback) -{ - return { - - gameObject: gameObject, - - enabled: true, - alwaysEnabled: false, - draggable: false, - dropZone: false, - cursor: false, - - target: null, - - camera: null, - - hitArea: hitArea, - hitAreaCallback: hitAreaCallback, - hitAreaDebug: null, - - // Has the dev specified their own shape, or is this bound to the texture size? - customHitArea: false, - - localX: 0, - localY: 0, - - // 0 = Not being dragged - // 1 = Being checked for dragging - // 2 = Being dragged - dragState: 0, - - dragStartX: 0, - dragStartY: 0, - dragStartXGlobal: 0, - dragStartYGlobal: 0, - - dragX: 0, - dragY: 0 - - }; -}; - -module.exports = CreateInteractiveObject; - - -/***/ }), -/* 487 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * Contains information about a specific Gamepad Axis. - * Axis objects are created automatically by the Gamepad as they are needed. - * - * @class Axis - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Axis belongs to. - * @param {number} index - The index of this Axis. - */ -var Axis = new Class({ - - initialize: - - function Axis (pad, index) - { - /** - * A reference to the Gamepad that this Axis belongs to. - * - * @name Phaser.Input.Gamepad.Axis#pad - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.0.0 - */ - this.pad = pad; - - /** - * An event emitter to use to emit the axis events. - * - * @name Phaser.Input.Gamepad.Axis#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = pad.events; - - /** - * The index of this Axis. - * - * @name Phaser.Input.Gamepad.Axis#index - * @type {number} - * @since 3.0.0 - */ - this.index = index; - - /** - * The raw axis value, between -1 and 1 with 0 being dead center. - * Use the method `getValue` to get a normalized value with the threshold applied. - * - * @name Phaser.Input.Gamepad.Axis#value - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.value = 0; - - /** - * Movement tolerance threshold below which axis values are ignored in `getValue`. - * - * @name Phaser.Input.Gamepad.Axis#threshold - * @type {number} - * @default 0.1 - * @since 3.0.0 - */ - this.threshold = 0.1; - }, - - /** - * Internal update handler for this Axis. - * Called automatically by the Gamepad as part of its update. - * - * @method Phaser.Input.Gamepad.Axis#update - * @private - * @since 3.0.0 - * - * @param {number} value - The value of the axis movement. - */ - update: function (value) - { - this.value = value; - }, - - /** - * Applies the `threshold` value to the axis and returns it. - * - * @method Phaser.Input.Gamepad.Axis#getValue - * @since 3.0.0 - * - * @return {number} The axis value, adjusted for the movement threshold. - */ - getValue: function () - { - return (Math.abs(this.value) < this.threshold) ? 0 : this.value; - }, - - /** - * Destroys this Axis instance and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Axis#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.pad = null; - this.events = null; - } - -}); - -module.exports = Axis; - - -/***/ }), -/* 488 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(234); - -/** - * @classdesc - * Contains information about a specific button on a Gamepad. - * Button objects are created automatically by the Gamepad as they are needed. - * - * @class Button - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Button belongs to. - * @param {number} index - The index of this Button. - */ -var Button = new Class({ - - initialize: - - function Button (pad, index) - { - /** - * A reference to the Gamepad that this Button belongs to. - * - * @name Phaser.Input.Gamepad.Button#pad - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.0.0 - */ - this.pad = pad; - - /** - * An event emitter to use to emit the button events. - * - * @name Phaser.Input.Gamepad.Button#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = pad.manager; - - /** - * The index of this Button. - * - * @name Phaser.Input.Gamepad.Button#index - * @type {number} - * @since 3.0.0 - */ - this.index = index; - - /** - * Between 0 and 1. - * - * @name Phaser.Input.Gamepad.Button#value - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.value = 0; - - /** - * Can be set for analogue buttons to enable a 'pressure' threshold, - * before a button is considered as being 'pressed'. - * - * @name Phaser.Input.Gamepad.Button#threshold - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.threshold = 1; - - /** - * Is the Button being pressed down or not? - * - * @name Phaser.Input.Gamepad.Button#pressed - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.pressed = false; - }, - - /** - * Internal update handler for this Button. - * Called automatically by the Gamepad as part of its update. - * - * @method Phaser.Input.Gamepad.Button#update - * @fires Phaser.Input.Gamepad.Events#BUTTON_DOWN - * @fires Phaser.Input.Gamepad.Events#BUTTON_UP - * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN - * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP - * @private - * @since 3.0.0 - * - * @param {number} value - The value of the button. Between 0 and 1. - */ - update: function (value) - { - this.value = value; - - var pad = this.pad; - var index = this.index; - - if (value >= this.threshold) - { - if (!this.pressed) - { - this.pressed = true; - this.events.emit(Events.BUTTON_DOWN, pad, this, value); - this.pad.emit(Events.GAMEPAD_BUTTON_DOWN, index, value, this); - } - } - else if (this.pressed) - { - this.pressed = false; - this.events.emit(Events.BUTTON_UP, pad, this, value); - this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this); - } - }, - - /** - * Destroys this Button instance and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Button#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.pad = null; - this.events = null; - } - -}); - -module.exports = Button; - - -/***/ }), -/* 489 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Axis = __webpack_require__(487); -var Button = __webpack_require__(488); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A single Gamepad. - * - * These are created, updated and managed by the Gamepad Plugin. - * - * @class Gamepad - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.GamepadPlugin} manager - A reference to the Gamepad Plugin. - * @param {Phaser.Types.Input.Gamepad.Pad} pad - The Gamepad object, as extracted from GamepadEvent. - */ -var Gamepad = new Class({ - - Extends: EventEmitter, - - initialize: - - function Gamepad (manager, pad) - { - EventEmitter.call(this); - - /** - * A reference to the Gamepad Plugin. - * - * @name Phaser.Input.Gamepad.Gamepad#manager - * @type {Phaser.Input.Gamepad.GamepadPlugin} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * A reference to the native Gamepad object that is connected to the browser. - * - * @name Phaser.Input.Gamepad.Gamepad#pad - * @type {any} - * @since 3.10.0 - */ - this.pad = pad; - - /** - * A string containing some information about the controller. - * - * This is not strictly specified, but in Firefox it will contain three pieces of information - * separated by dashes (-): two 4-digit hexadecimal strings containing the USB vendor and - * product id of the controller, and the name of the controller as provided by the driver. - * In Chrome it will contain the name of the controller as provided by the driver, - * followed by vendor and product 4-digit hexadecimal strings. - * - * @name Phaser.Input.Gamepad.Gamepad#id - * @type {string} - * @since 3.0.0 - */ - this.id = pad.id; - - /** - * An integer that is unique for each Gamepad currently connected to the system. - * This can be used to distinguish multiple controllers. - * Note that disconnecting a device and then connecting a new device may reuse the previous index. - * - * @name Phaser.Input.Gamepad.Gamepad#index - * @type {number} - * @since 3.0.0 - */ - this.index = pad.index; - - var buttons = []; - - for (var i = 0; i < pad.buttons.length; i++) - { - buttons.push(new Button(this, i)); - } - - /** - * An array of Gamepad Button objects, corresponding to the different buttons available on the Gamepad. - * - * @name Phaser.Input.Gamepad.Gamepad#buttons - * @type {Phaser.Input.Gamepad.Button[]} - * @since 3.0.0 - */ - this.buttons = buttons; - - var axes = []; - - for (i = 0; i < pad.axes.length; i++) - { - axes.push(new Axis(this, i)); - } - - /** - * An array of Gamepad Axis objects, corresponding to the different axes available on the Gamepad, if any. - * - * @name Phaser.Input.Gamepad.Gamepad#axes - * @type {Phaser.Input.Gamepad.Axis[]} - * @since 3.0.0 - */ - this.axes = axes; - - /** - * The Gamepad's Haptic Actuator (Vibration / Rumble support). - * This is highly experimental and only set if both present on the device, - * and exposed by both the hardware and browser. - * - * @name Phaser.Input.Gamepad.Gamepad#vibration - * @type {GamepadHapticActuator} - * @since 3.10.0 - */ - this.vibration = pad.vibrationActuator; - - // https://w3c.github.io/gamepad/#remapping - - var _noButton = { value: 0, pressed: false }; - - /** - * A reference to the Left Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCLeft = (buttons[14]) ? buttons[14] : _noButton; - - /** - * A reference to the Right Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCRight = (buttons[15]) ? buttons[15] : _noButton; - - /** - * A reference to the Top Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCTop = (buttons[12]) ? buttons[12] : _noButton; - - /** - * A reference to the Bottom Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCBottom = (buttons[13]) ? buttons[13] : _noButton; - - /** - * A reference to the Left Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCLeft = (buttons[2]) ? buttons[2] : _noButton; - - /** - * A reference to the Right Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCRight = (buttons[1]) ? buttons[1] : _noButton; - - /** - * A reference to the Top Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCTop = (buttons[3]) ? buttons[3] : _noButton; - - /** - * A reference to the Bottom Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCBottom = (buttons[0]) ? buttons[0] : _noButton; - - /** - * A reference to the Top Left Front Button (L1 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBLeftTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBLeftTop = (buttons[4]) ? buttons[4] : _noButton; - - /** - * A reference to the Bottom Left Front Button (L2 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBLeftBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBLeftBottom = (buttons[6]) ? buttons[6] : _noButton; - - /** - * A reference to the Top Right Front Button (R1 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBRightTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBRightTop = (buttons[5]) ? buttons[5] : _noButton; - - /** - * A reference to the Bottom Right Front Button (R2 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBRightBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBRightBottom = (buttons[7]) ? buttons[7] : _noButton; - - var _noAxis = { value: 0 }; - - /** - * A reference to the Horizontal Axis for the Left Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_HAxisLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._HAxisLeft = (axes[0]) ? axes[0] : _noAxis; - - /** - * A reference to the Vertical Axis for the Left Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_VAxisLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._VAxisLeft = (axes[1]) ? axes[1] : _noAxis; - - /** - * A reference to the Horizontal Axis for the Right Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_HAxisRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._HAxisRight = (axes[2]) ? axes[2] : _noAxis; - - /** - * A reference to the Vertical Axis for the Right Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_VAxisRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._VAxisRight = (axes[3]) ? axes[3] : _noAxis; - - /** - * A Vector2 containing the most recent values from the Gamepad's left axis stick. - * This is updated automatically as part of the Gamepad.update cycle. - * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. - * The values are based on the Axis thresholds. - * If the Gamepad does not have a left axis stick, the values will always be zero. - * - * @name Phaser.Input.Gamepad.Gamepad#leftStick - * @type {Phaser.Math.Vector2} - * @since 3.10.0 - */ - this.leftStick = new Vector2(); - - /** - * A Vector2 containing the most recent values from the Gamepad's right axis stick. - * This is updated automatically as part of the Gamepad.update cycle. - * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. - * The values are based on the Axis thresholds. - * If the Gamepad does not have a right axis stick, the values will always be zero. - * - * @name Phaser.Input.Gamepad.Gamepad#rightStick - * @type {Phaser.Math.Vector2} - * @since 3.10.0 - */ - this.rightStick = new Vector2(); - - /** - * When was this Gamepad created? Used to avoid duplicate event spamming in the update loop. - * - * @name Phaser.Input.Gamepad.Gamepad#_created - * @type {number} - * @private - * @since 3.50.0 - */ - this._created = performance.now(); - }, - - /** - * Gets the total number of axis this Gamepad claims to support. - * - * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal - * @since 3.10.0 - * - * @return {number} The total number of axes this Gamepad claims to support. - */ - getAxisTotal: function () - { - return this.axes.length; - }, - - /** - * Gets the value of an axis based on the given index. - * The index must be valid within the range of axes supported by this Gamepad. - * The return value will be a float between 0 and 1. - * - * @method Phaser.Input.Gamepad.Gamepad#getAxisValue - * @since 3.10.0 - * - * @param {number} index - The index of the axes to get the value for. - * - * @return {number} The value of the axis, between 0 and 1. - */ - getAxisValue: function (index) - { - return this.axes[index].getValue(); - }, - - /** - * Sets the threshold value of all axis on this Gamepad. - * The value is a float between 0 and 1 and is the amount below which the axis is considered as not having been moved. - * - * @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold - * @since 3.10.0 - * - * @param {number} value - A value between 0 and 1. - */ - setAxisThreshold: function (value) - { - for (var i = 0; i < this.axes.length; i++) - { - this.axes[i].threshold = value; - } - }, - - /** - * Gets the total number of buttons this Gamepad claims to have. - * - * @method Phaser.Input.Gamepad.Gamepad#getButtonTotal - * @since 3.10.0 - * - * @return {number} The total number of buttons this Gamepad claims to have. - */ - getButtonTotal: function () - { - return this.buttons.length; - }, - - /** - * Gets the value of a button based on the given index. - * The index must be valid within the range of buttons supported by this Gamepad. - * - * The return value will be either 0 or 1 for an analogue button, or a float between 0 and 1 - * for a pressure-sensitive digital button, such as the shoulder buttons on a Dual Shock. - * - * @method Phaser.Input.Gamepad.Gamepad#getButtonValue - * @since 3.10.0 - * - * @param {number} index - The index of the button to get the value for. - * - * @return {number} The value of the button, between 0 and 1. - */ - getButtonValue: function (index) - { - return this.buttons[index].value; - }, - - /** - * Returns if the button is pressed down or not. - * The index must be valid within the range of buttons supported by this Gamepad. - * - * @method Phaser.Input.Gamepad.Gamepad#isButtonDown - * @since 3.10.0 - * - * @param {number} index - The index of the button to get the value for. - * - * @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`. - */ - isButtonDown: function (index) - { - return this.buttons[index].pressed; - }, - - /** - * Internal update handler for this Gamepad. - * Called automatically by the Gamepad Manager as part of its update. - * - * @method Phaser.Input.Gamepad.Gamepad#update - * @private - * @since 3.0.0 - */ - update: function (pad) - { - if (pad.timestamp < this._created) - { - return; - } - - var i; - - // Sync the button values - - var localButtons = this.buttons; - var gamepadButtons = pad.buttons; - - var len = localButtons.length; - - for (i = 0; i < len; i++) - { - localButtons[i].update(gamepadButtons[i].value); - } - - // Sync the axis values - - var localAxes = this.axes; - var gamepadAxes = pad.axes; - - len = localAxes.length; - - for (i = 0; i < len; i++) - { - localAxes[i].update(gamepadAxes[i]); - } - - if (len >= 2) - { - this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue()); - - if (len >= 4) - { - this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue()); - } - } - }, - - /** - * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Gamepad#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.manager = null; - this.pad = null; - - var i; - - for (i = 0; i < this.buttons.length; i++) - { - this.buttons[i].destroy(); - } - - for (i = 0; i < this.axes.length; i++) - { - this.axes[i].destroy(); - } - - this.buttons = []; - this.axes = []; - }, - - /** - * Is this Gamepad currently connected or not? - * - * @name Phaser.Input.Gamepad.Gamepad#connected - * @type {boolean} - * @default true - * @since 3.0.0 - */ - connected: { - - get: function () - { - return this.pad.connected; - } - - }, - - /** - * A timestamp containing the most recent time this Gamepad was updated. - * - * @name Phaser.Input.Gamepad.Gamepad#timestamp - * @type {number} - * @since 3.0.0 - */ - timestamp: { - - get: function () - { - return this.pad.timestamp; - } - - }, - - /** - * Is the Gamepad's Left button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad left button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#left - * @type {boolean} - * @since 3.10.0 - */ - left: { - - get: function () - { - return this._LCLeft.pressed; - } - - }, - - /** - * Is the Gamepad's Right button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad right button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#right - * @type {boolean} - * @since 3.10.0 - */ - right: { - - get: function () - { - return this._LCRight.pressed; - } - - }, - - /** - * Is the Gamepad's Up button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad up button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#up - * @type {boolean} - * @since 3.10.0 - */ - up: { - - get: function () - { - return this._LCTop.pressed; - } - - }, - - /** - * Is the Gamepad's Down button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad down button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#down - * @type {boolean} - * @since 3.10.0 - */ - down: { - - get: function () - { - return this._LCBottom.pressed; - } - - }, - - /** - * Is the Gamepad's bottom button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the X button. - * On an XBox controller it's the A button. - * - * @name Phaser.Input.Gamepad.Gamepad#A - * @type {boolean} - * @since 3.10.0 - */ - A: { - - get: function () - { - return this._RCBottom.pressed; - } - - }, - - /** - * Is the Gamepad's top button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Triangle button. - * On an XBox controller it's the Y button. - * - * @name Phaser.Input.Gamepad.Gamepad#Y - * @type {boolean} - * @since 3.10.0 - */ - Y: { - - get: function () - { - return this._RCTop.pressed; - } - - }, - - /** - * Is the Gamepad's left button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Square button. - * On an XBox controller it's the X button. - * - * @name Phaser.Input.Gamepad.Gamepad#X - * @type {boolean} - * @since 3.10.0 - */ - X: { - - get: function () - { - return this._RCLeft.pressed; - } - - }, - - /** - * Is the Gamepad's right button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Circle button. - * On an XBox controller it's the B button. - * - * @name Phaser.Input.Gamepad.Gamepad#B - * @type {boolean} - * @since 3.10.0 - */ - B: { - - get: function () - { - return this._RCRight.pressed; - } - - }, - - /** - * Returns the value of the Gamepad's top left shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the L1 button. - * On an XBox controller it's the LB button. - * - * @name Phaser.Input.Gamepad.Gamepad#L1 - * @type {number} - * @since 3.10.0 - */ - L1: { - - get: function () - { - return this._FBLeftTop.value; - } - - }, - - /** - * Returns the value of the Gamepad's bottom left shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the L2 button. - * On an XBox controller it's the LT button. - * - * @name Phaser.Input.Gamepad.Gamepad#L2 - * @type {number} - * @since 3.10.0 - */ - L2: { - - get: function () - { - return this._FBLeftBottom.value; - } - - }, - - /** - * Returns the value of the Gamepad's top right shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the R1 button. - * On an XBox controller it's the RB button. - * - * @name Phaser.Input.Gamepad.Gamepad#R1 - * @type {number} - * @since 3.10.0 - */ - R1: { - - get: function () - { - return this._FBRightTop.value; - } - - }, - - /** - * Returns the value of the Gamepad's bottom right shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the R2 button. - * On an XBox controller it's the RT button. - * - * @name Phaser.Input.Gamepad.Gamepad#R2 - * @type {number} - * @since 3.10.0 - */ - R2: { - - get: function () - { - return this._FBRightBottom.value; - } - - } - -}); - -module.exports = Gamepad; - - -/***/ }), -/* 490 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(151); - -/** - * @classdesc - * A generic Key object which can be passed to the Process functions (and so on) - * keycode must be an integer - * - * @class Key - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyboardPlugin} plugin - The Keyboard Plugin instance that owns this Key object. - * @param {number} keyCode - The keycode of this key. - */ -var Key = new Class({ - - Extends: EventEmitter, - - initialize: - - function Key (plugin, keyCode) - { - EventEmitter.call(this); - - /** - * The Keyboard Plugin instance that owns this Key object. - * - * @name Phaser.Input.Keyboard.Key#plugin - * @type {Phaser.Input.Keyboard.KeyboardPlugin} - * @since 3.17.0 - */ - this.plugin = plugin; - - /** - * The keycode of this key. - * - * @name Phaser.Input.Keyboard.Key#keyCode - * @type {number} - * @since 3.0.0 - */ - this.keyCode = keyCode; - - /** - * The original DOM event. - * - * @name Phaser.Input.Keyboard.Key#originalEvent - * @type {KeyboardEvent} - * @since 3.0.0 - */ - this.originalEvent = undefined; - - /** - * Can this Key be processed? - * - * @name Phaser.Input.Keyboard.Key#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down. - * - * @name Phaser.Input.Keyboard.Key#isDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isDown = false; - - /** - * The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up. - * - * @name Phaser.Input.Keyboard.Key#isUp - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.isUp = true; - - /** - * The down state of the ALT key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#altKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.altKey = false; - - /** - * The down state of the CTRL key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#ctrlKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.ctrlKey = false; - - /** - * The down state of the SHIFT key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#shiftKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shiftKey = false; - - /** - * The down state of the Meta key, if pressed at the same time as this key. - * On a Mac the Meta Key is the Command key. On Windows keyboards, it's the Windows key. - * - * @name Phaser.Input.Keyboard.Key#metaKey - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.metaKey = false; - - /** - * The location of the modifier key. 0 for standard (or unknown), 1 for left, 2 for right, 3 for numpad. - * - * @name Phaser.Input.Keyboard.Key#location - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.location = 0; - - /** - * The timestamp when the key was last pressed down. - * - * @name Phaser.Input.Keyboard.Key#timeDown - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeDown = 0; - - /** - * The number of milliseconds this key was held down for in the previous down - up sequence. - * This value isn't updated every game step, only when the Key changes state. - * To get the current duration use the `getDuration` method. - * - * @name Phaser.Input.Keyboard.Key#duration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.duration = 0; - - /** - * The timestamp when the key was last released. - * - * @name Phaser.Input.Keyboard.Key#timeUp - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeUp = 0; - - /** - * When a key is held down should it continuously fire the `down` event each time it repeats? - * - * By default it will emit the `down` event just once, but if you wish to receive the event - * for each repeat as well, enable this property. - * - * @name Phaser.Input.Keyboard.Key#emitOnRepeat - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.emitOnRepeat = false; - - /** - * If a key is held down this holds down the number of times the key has 'repeated'. - * - * @name Phaser.Input.Keyboard.Key#repeats - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeats = 0; - - /** - * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) - * - * @name Phaser.Input.Keyboard.Key#_justDown - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._justDown = false; - - /** - * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) - * - * @name Phaser.Input.Keyboard.Key#_justUp - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._justUp = false; - - /** - * Internal tick counter. - * - * @name Phaser.Input.Keyboard.Key#_tick - * @type {number} - * @private - * @since 3.11.0 - */ - this._tick = -1; - }, - - /** - * Controls if this Key will continuously emit a `down` event while being held down (true), - * or emit the event just once, on first press, and then skip future events (false). - * - * @method Phaser.Input.Keyboard.Key#setEmitOnRepeat - * @since 3.16.0 - * - * @param {boolean} value - Emit `down` events on repeated key down actions, or just once? - * - * @return {this} This Key instance. - */ - setEmitOnRepeat: function (value) - { - this.emitOnRepeat = value; - - return this; - }, - - /** - * Processes the Key Down action for this Key. - * Called automatically by the Keyboard Plugin. - * - * @method Phaser.Input.Keyboard.Key#onDown - * @fires Phaser.Input.Keyboard.Events#DOWN - * @since 3.16.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard event. - */ - onDown: function (event) - { - this.originalEvent = event; - - if (!this.enabled) - { - return; - } - - this.altKey = event.altKey; - this.ctrlKey = event.ctrlKey; - this.shiftKey = event.shiftKey; - this.metaKey = event.metaKey; - this.location = event.location; - - this.repeats++; - - if (!this.isDown) - { - this.isDown = true; - this.isUp = false; - this.timeDown = event.timeStamp; - this.duration = 0; - this._justDown = true; - this._justUp = false; - - this.emit(Events.DOWN, this, event); - } - else if (this.emitOnRepeat) - { - this.emit(Events.DOWN, this, event); - } - }, - - /** - * Processes the Key Up action for this Key. - * Called automatically by the Keyboard Plugin. - * - * @method Phaser.Input.Keyboard.Key#onUp - * @fires Phaser.Input.Keyboard.Events#UP - * @since 3.16.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard event. - */ - onUp: function (event) - { - this.originalEvent = event; - - if (!this.enabled) - { - return; - } - - this.isDown = false; - this.isUp = true; - this.timeUp = event.timeStamp; - this.duration = this.timeUp - this.timeDown; - this.repeats = 0; - - this._justDown = false; - this._justUp = true; - this._tick = -1; - - this.emit(Events.UP, this, event); - }, - - /** - * Resets this Key object back to its default un-pressed state. - * - * @method Phaser.Input.Keyboard.Key#reset - * @since 3.6.0 - * - * @return {this} This Key instance. - */ - reset: function () - { - this.preventDefault = true; - this.enabled = true; - this.isDown = false; - this.isUp = true; - this.altKey = false; - this.ctrlKey = false; - this.shiftKey = false; - this.metaKey = false; - this.timeDown = 0; - this.duration = 0; - this.timeUp = 0; - this.repeats = 0; - this._justDown = false; - this._justUp = false; - this._tick = -1; - - return this; - }, - - /** - * Returns the duration, in ms, that the Key has been held down for. - * - * If the key is not currently down it will return zero. - * - * The get the duration the Key was held down for in the previous up-down cycle, - * use the `Key.duration` property value instead. - * - * @method Phaser.Input.Keyboard.Key#getDuration - * @since 3.17.0 - * - * @return {number} The duration, in ms, that the Key has been held down for if currently down. - */ - getDuration: function () - { - if (this.isDown) - { - return (this.plugin.game.loop.time - this.timeDown); - } - else - { - return 0; - } - }, - - /** - * Removes any bound event handlers and removes local references. - * - * @method Phaser.Input.Keyboard.Key#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.originalEvent = null; - - this.plugin = null; - } - -}); - -module.exports = Key; - - -/***/ }), -/* 491 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(151); -var GetFastValue = __webpack_require__(2); -var ProcessKeyCombo = __webpack_require__(492); -var ResetKeyCombo = __webpack_require__(494); - -/** - * @classdesc - * A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them - * it will emit a `keycombomatch` event from the Keyboard Manager. - * - * The keys to be listened for can be defined as: - * - * A string (i.e. 'ATARI') - * An array of either integers (key codes) or strings, or a mixture of both - * An array of objects (such as Key objects) with a public 'keyCode' property - * - * For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter) - * you could pass the following array of key codes: - * - * ```javascript - * this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true }); - * - * this.input.keyboard.on('keycombomatch', function (event) { - * console.log('Konami Code entered!'); - * }); - * ``` - * - * Or, to listen for the user entering the word PHASER: - * - * ```javascript - * this.input.keyboard.createCombo('PHASER'); - * ``` - * - * @class KeyCombo - * @memberof Phaser.Input.Keyboard - * @constructor - * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyboardPlugin} keyboardPlugin - A reference to the Keyboard Plugin. - * @param {(string|number[]|object[])} keys - The keys that comprise this combo. - * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. - */ -var KeyCombo = new Class({ - - initialize: - - function KeyCombo (keyboardPlugin, keys, config) - { - if (config === undefined) { config = {}; } - - // Can't have a zero or single length combo (string or array based) - if (keys.length < 2) - { - return false; - } - - /** - * A reference to the Keyboard Manager - * - * @name Phaser.Input.Keyboard.KeyCombo#manager - * @type {Phaser.Input.Keyboard.KeyboardPlugin} - * @since 3.0.0 - */ - this.manager = keyboardPlugin; - - /** - * A flag that controls if this Key Combo is actively processing keys or not. - * - * @name Phaser.Input.Keyboard.KeyCombo#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * An array of the keycodes that comprise this combo. - * - * @name Phaser.Input.Keyboard.KeyCombo#keyCodes - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.keyCodes = []; - - // if 'keys' is a string we need to get the keycode of each character in it - - for (var i = 0; i < keys.length; i++) - { - var char = keys[i]; - - if (typeof char === 'string') - { - this.keyCodes.push(char.toUpperCase().charCodeAt(0)); - } - else if (typeof char === 'number') - { - this.keyCodes.push(char); - } - else if (char.hasOwnProperty('keyCode')) - { - this.keyCodes.push(char.keyCode); - } - } - - /** - * The current keyCode the combo is waiting for. - * - * @name Phaser.Input.Keyboard.KeyCombo#current - * @type {number} - * @since 3.0.0 - */ - this.current = this.keyCodes[0]; - - /** - * The current index of the key being waited for in the 'keys' string. - * - * @name Phaser.Input.Keyboard.KeyCombo#index - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.index = 0; - - /** - * The length of this combo (in keycodes) - * - * @name Phaser.Input.Keyboard.KeyCombo#size - * @type {number} - * @since 3.0.0 - */ - this.size = this.keyCodes.length; - - /** - * The time the previous key in the combo was matched. - * - * @name Phaser.Input.Keyboard.KeyCombo#timeLastMatched - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeLastMatched = 0; - - /** - * Has this Key Combo been matched yet? - * - * @name Phaser.Input.Keyboard.KeyCombo#matched - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.matched = false; - - /** - * The time the entire combo was matched. - * - * @name Phaser.Input.Keyboard.KeyCombo#timeMatched - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeMatched = 0; - - /** - * If they press the wrong key do we reset the combo? - * - * @name Phaser.Input.Keyboard.KeyCombo#resetOnWrongKey - * @type {boolean} - * @default 0 - * @since 3.0.0 - */ - this.resetOnWrongKey = GetFastValue(config, 'resetOnWrongKey', true); - - /** - * The max delay in ms between each key press. Above this the combo is reset. 0 means disabled. - * - * @name Phaser.Input.Keyboard.KeyCombo#maxKeyDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxKeyDelay = GetFastValue(config, 'maxKeyDelay', 0); - - /** - * If previously matched and they press the first key of the combo again, will it reset? - * - * @name Phaser.Input.Keyboard.KeyCombo#resetOnMatch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.resetOnMatch = GetFastValue(config, 'resetOnMatch', false); - - /** - * If the combo matches, will it delete itself? - * - * @name Phaser.Input.Keyboard.KeyCombo#deleteOnMatch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.deleteOnMatch = GetFastValue(config, 'deleteOnMatch', false); - - var _this = this; - - var onKeyDownHandler = function (event) - { - if (_this.matched || !_this.enabled) - { - return; - } - - var matched = ProcessKeyCombo(event, _this); - - if (matched) - { - _this.manager.emit(Events.COMBO_MATCH, _this, event); - - if (_this.resetOnMatch) - { - ResetKeyCombo(_this); - } - else if (_this.deleteOnMatch) - { - _this.destroy(); - } - } - }; - - /** - * The internal Key Down handler. - * - * @name Phaser.Input.Keyboard.KeyCombo#onKeyDown - * @private - * @type {KeyboardKeydownCallback} - * @fires Phaser.Input.Keyboard.Events#COMBO_MATCH - * @since 3.0.0 - */ - this.onKeyDown = onKeyDownHandler; - - this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown); - }, - - /** - * How far complete is this combo? A value between 0 and 1. - * - * @name Phaser.Input.Keyboard.KeyCombo#progress - * @type {number} - * @readonly - * @since 3.0.0 - */ - progress: { - - get: function () - { - return this.index / this.size; - } - - }, - - /** - * Destroys this Key Combo and all of its references. - * - * @method Phaser.Input.Keyboard.KeyCombo#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enabled = false; - this.keyCodes = []; - - this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown); - - this.manager = null; - } - -}); - -module.exports = KeyCombo; - - -/***/ }), -/* 492 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AdvanceKeyCombo = __webpack_require__(493); - -/** - * Used internally by the KeyCombo class. - * - * @function Phaser.Input.Keyboard.ProcessKeyCombo - * @private - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native Keyboard Event. - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to be processed. - * - * @return {boolean} `true` if the combo was matched, otherwise `false`. - */ -var ProcessKeyCombo = function (event, combo) -{ - if (combo.matched) - { - return true; - } - - var comboMatched = false; - var keyMatched = false; - - if (event.keyCode === combo.current) - { - // Key was correct - - if (combo.index > 0 && combo.maxKeyDelay > 0) - { - // We have to check to see if the delay between - // the new key and the old one was too long (if enabled) - - var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; - - // Check if they pressed it in time or not - if (event.timeStamp <= timeLimit) - { - keyMatched = true; - comboMatched = AdvanceKeyCombo(event, combo); - } - } - else - { - keyMatched = true; - - // We don't check the time for the first key pressed, so just advance it - comboMatched = AdvanceKeyCombo(event, combo); - } - } - - if (!keyMatched && combo.resetOnWrongKey) - { - // Wrong key was pressed - combo.index = 0; - combo.current = combo.keyCodes[0]; - } - - if (comboMatched) - { - combo.timeLastMatched = event.timeStamp; - combo.matched = true; - combo.timeMatched = event.timeStamp; - } - - return comboMatched; -}; - -module.exports = ProcessKeyCombo; - - -/***/ }), -/* 493 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Used internally by the KeyCombo class. - * Return `true` if it reached the end of the combo, `false` if not. - * - * @function Phaser.Input.Keyboard.AdvanceKeyCombo - * @private - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native Keyboard Event. - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. - * - * @return {boolean} `true` if it reached the end of the combo, `false` if not. - */ -var AdvanceKeyCombo = function (event, combo) -{ - combo.timeLastMatched = event.timeStamp; - combo.index++; - - if (combo.index === combo.size) - { - return true; - } - else - { - combo.current = combo.keyCodes[combo.index]; - return false; - } -}; - -module.exports = AdvanceKeyCombo; - - -/***/ }), -/* 494 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Used internally by the KeyCombo class. - * - * @function Phaser.Input.Keyboard.ResetKeyCombo - * @private - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo to reset. - * - * @return {Phaser.Input.Keyboard.KeyCombo} The KeyCombo. - */ -var ResetKeyCombo = function (combo) -{ - combo.current = combo.keyCodes[0]; - combo.index = 0; - combo.timeLastMatched = 0; - combo.matched = false; - combo.timeMatched = 0; - - return combo; -}; - -module.exports = ResetKeyCombo; - - -/***/ }), -/* 495 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var MergeXHRSettings = __webpack_require__(235); - -/** - * 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; - - -/***/ }), -/* 496 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var HTML5AudioFile = __webpack_require__(497); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Audio File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. - * - * @class AudioFile - * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {any} [urlConfig] - The absolute or relative URL to load this file from in a config object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - * @param {AudioContext} [audioContext] - The AudioContext this file will use to process itself. - */ -var AudioFile = new Class({ - - Extends: File, - - initialize: - - // URL is an object created by AudioFile.findAudioURL - function AudioFile (loader, key, urlConfig, xhrSettings, audioContext) - { - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - audioContext = GetFastValue(config, 'context', audioContext); - } - - var fileConfig = { - type: 'audio', - cache: loader.cacheManager.audio, - extension: urlConfig.type, - responseType: 'arraybuffer', - key: key, - url: urlConfig.url, - xhrSettings: xhrSettings, - config: { context: audioContext } - }; - - 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.AudioFile#onProcess - * @since 3.0.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; - - var _this = this; - - // interesting read https://github.com/WebAudio/web-audio-api/issues/1305 - this.config.context.decodeAudioData(this.xhrLoader.response, - function (audioBuffer) - { - _this.data = audioBuffer; - - _this.onProcessComplete(); - }, - function (e) - { - // eslint-disable-next-line no-console - console.error('Error decoding audio: ' + _this.key + ' - ', e ? e.message : null); - - _this.onProcessError(); - } - ); - - this.config.context = null; - } - -}); - -AudioFile.create = function (loader, key, urls, config, xhrSettings) -{ - var game = loader.systems.game; - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - // url may be inside key, which may be an object - if (IsPlainObject(key)) - { - urls = GetFastValue(key, 'url', []); - config = GetFastValue(key, 'config', {}); - } - - var urlConfig = AudioFile.getAudioURL(game, urls); - - if (!urlConfig) - { - return null; - } - - // https://developers.google.com/web/updates/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs - // var stream = GetFastValue(config, 'stream', false); - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - return new AudioFile(loader, key, urlConfig, xhrSettings, game.sound.context); - } - else - { - return new HTML5AudioFile(loader, key, urlConfig, config); - } -}; - -AudioFile.getAudioURL = function (game, urls) -{ - if (!Array.isArray(urls)) - { - urls = [ urls ]; - } - - for (var i = 0; i < urls.length; i++) - { - var url = GetFastValue(urls[i], 'url', urls[i]); - - if (url.indexOf('blob:') === 0 || url.indexOf('data:') === 0) - { - return { - url: url, - type: '' - }; - } - - var audioType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); - - audioType = GetFastValue(urls[i], 'type', (audioType) ? audioType[1] : '').toLowerCase(); - - if (game.device.audio[audioType]) - { - return { - url: url, - type: audioType - }; - } - } - - return null; -}; - -/** - * Adds an Audio or HTML5Audio file, or array of audio 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.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); - * } - * ``` - * - * 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 Audio Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Audio 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 Audio Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.audio({ - * key: 'title', - * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ] - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AudioFileConfig` for more details. - * - * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. - * - * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats. - * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on - * browser support. - * - * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded. - * - * Note: The ability to load this type of file will only be available if the Audio 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#audio - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.AudioFileConfig|Phaser.Types.Loader.FileTypes.AudioFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {(string|string[])} [urls] - The absolute or relative URL to load the audio files from. - * @param {any} [config] - An object containing an `instances` property for HTML5Audio. Defaults to 1. - * @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('audio', function (key, urls, config, xhrSettings) -{ - var game = this.systems.game; - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - // Sounds are disabled, so skip loading audio - return this; - } - - var audioFile; - - 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 - audioFile = AudioFile.create(this, key[i]); - - if (audioFile) - { - this.addFile(audioFile); - } - } - } - else - { - audioFile = AudioFile.create(this, key, urls, config, xhrSettings); - - if (audioFile) - { - this.addFile(audioFile); - } - } - - return this; -}); - -module.exports = AudioFile; - - -/***/ }), -/* 497 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(90); -var File = __webpack_require__(23); -var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(152); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Audio File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. - * - * @class HTML5AudioFile - * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string} [urlConfig] - The absolute or relative URL to load this file from. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var HTML5AudioFile = new Class({ - - Extends: File, - - initialize: - - function HTML5AudioFile (loader, key, urlConfig, audioConfig) - { - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - audioConfig = GetFastValue(config, 'config', audioConfig); - } - - var fileConfig = { - type: 'audio', - cache: loader.cacheManager.audio, - extension: urlConfig.type, - key: key, - url: urlConfig.url, - config: audioConfig - }; - - File.call(this, loader, fileConfig); - - // New properties specific to this class - this.locked = 'ontouchstart' in window; - this.loaded = false; - this.filesLoaded = 0; - this.filesTotal = 0; - }, - - /** - * Called when the file finishes loading. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad - * @since 3.0.0 - */ - onLoad: function () - { - if (this.loaded) - { - return; - } - - this.loaded = true; - - this.loader.nextFile(this, true); - }, - - /** - * Called if the file errors while loading. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onError - * @since 3.0.0 - */ - onError: function () - { - for (var i = 0; i < this.data.length; i++) - { - var audio = this.data[i]; - - audio.oncanplaythrough = null; - audio.onerror = null; - } - - this.loader.nextFile(this, false); - }, - - /** - * Called during the file load progress. Is sent a DOM ProgressEvent. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress - * @fires Phaser.Loader.Events#FILE_PROGRESS - * @since 3.0.0 - */ - onProgress: function (event) - { - var audio = event.target; - - audio.oncanplaythrough = null; - audio.onerror = null; - - this.filesLoaded++; - - this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1); - - this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); - - if (this.filesLoaded === this.filesTotal) - { - this.onLoad(); - } - }, - - /** - * 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.FileTypes.HTML5AudioFile#load - * @since 3.0.0 - */ - load: function () - { - this.data = []; - - var instances = (this.config && this.config.instances) || 1; - - this.filesTotal = instances; - this.filesLoaded = 0; - this.percentComplete = 0; - - for (var i = 0; i < instances; i++) - { - var audio = new Audio(); - - if (!audio.dataset) - { - audio.dataset = {}; - } - - audio.dataset.name = this.key + ('0' + i).slice(-2); - audio.dataset.used = 'false'; - - if (this.locked) - { - audio.dataset.locked = 'true'; - } - else - { - audio.dataset.locked = 'false'; - - audio.preload = 'auto'; - audio.oncanplaythrough = this.onProgress.bind(this); - audio.onerror = this.onError.bind(this); - } - - this.data.push(audio); - } - - for (i = 0; i < this.data.length; i++) - { - audio = this.data[i]; - audio.src = GetURL(this, this.loader.baseURL); - - if (!this.locked) - { - audio.load(); - } - } - - if (this.locked) - { - // This is super-dangerous but works. Race condition potential high. - // Is there another way? - setTimeout(this.onLoad.bind(this)); - } - } - -}); - -module.exports = HTML5AudioFile; - - -/***/ }), -/* 498 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Script File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#script method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#script. - * - * @class ScriptFile - * @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.ScriptFileConfig)} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var ScriptFile = new Class({ - - Extends: File, - - initialize: - - function ScriptFile (loader, key, url, xhrSettings) - { - var extension = 'js'; - - 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: 'script', - cache: false, - 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.ScriptFile#onProcess - * @since 3.7.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; - - this.data = document.createElement('script'); - this.data.language = 'javascript'; - this.data.type = 'text/javascript'; - this.data.defer = false; - this.data.text = this.xhrLoader.responseText; - - document.head.appendChild(this.data); - - this.onProcessComplete(); - } - -}); - -/** - * Adds a Script file, or array of Script 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.script('aliens', 'lib/aliens.js'); - * } - * ``` - * - * 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 and not already in-use by another file in the Loader. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.script({ - * key: 'aliens', - * url: 'lib/aliens.js' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.ScriptFileConfig` for more details. - * - * Once the file has finished loading it will automatically be converted into a script element - * via `document.createElement('script')`. It will have its language set to JavaScript, `defer` set to - * false and then the resulting element will be appended to `document.head`. Any code then in the - * script will be executed. - * - * 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.js". It will always add `.js` 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 Script 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#script - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.ScriptFileConfig|Phaser.Types.Loader.FileTypes.ScriptFileConfig[])} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". - * @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('script', 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 ScriptFile(this, key[i])); - } - } - else - { - this.addFile(new ScriptFile(this, key, url, xhrSettings)); - } - - return this; -}); - -module.exports = ScriptFile; - - -/***/ }), -/* 499 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeImage = __webpack_require__(500); -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var PhysicsGroup = __webpack_require__(502); -var StaticPhysicsGroup = __webpack_require__(503); - -/** - * @classdesc - * The Arcade Physics Factory allows you to easily create Arcade Physics enabled Game Objects. - * Objects that are created by this Factory are automatically added to the physics world. - * - * @class Factory - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics World instance. - */ -var Factory = new Class({ - - initialize: - - function Factory (world) - { - /** - * A reference to the Arcade Physics World. - * - * @name Phaser.Physics.Arcade.Factory#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * A reference to the Scene this Arcade Physics instance belongs to. - * - * @name Phaser.Physics.Arcade.Factory#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = world.scene; - - /** - * A reference to the Scene.Systems this Arcade Physics instance belongs to. - * - * @name Phaser.Physics.Arcade.Factory#sys - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.sys = world.scene.sys; - }, - - /** - * Creates a new Arcade Physics Collider object. - * - * @method Phaser.Physics.Arcade.Factory#collider - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for collision. - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - collider: function (object1, object2, collideCallback, processCallback, callbackContext) - { - return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext); - }, - - /** - * Creates a new Arcade Physics Collider Overlap object. - * - * @method Phaser.Physics.Arcade.Factory#overlap - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for overlap. - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for overlap. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - overlap: function (object1, object2, collideCallback, processCallback, callbackContext) - { - return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext); - }, - - /** - * Adds an Arcade Physics Body to the given Game Object. - * - * @method Phaser.Physics.Arcade.Factory#existing - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - A Game Object. - * @param {boolean} [isStatic=false] - Create a Static body (true) or Dynamic body (false). - * - * @return {Phaser.Types.Physics.Arcade.GameObjectWithBody} The Game Object. - */ - existing: function (gameObject, isStatic) - { - var type = (isStatic) ? CONST.STATIC_BODY : CONST.DYNAMIC_BODY; - - this.world.enableBody(gameObject, type); - - return gameObject; - }, - - /** - * Creates a new Arcade Image object with a Static body. - * - * @method Phaser.Physics.Arcade.Factory#staticImage - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.ImageWithStaticBody} The Image object that was created. - */ - staticImage: function (x, y, key, frame) - { - var image = new ArcadeImage(this.scene, x, y, key, frame); - - this.sys.displayList.add(image); - - this.world.enableBody(image, CONST.STATIC_BODY); - - return image; - }, - - /** - * Creates a new Arcade Image object with a Dynamic body. - * - * @method Phaser.Physics.Arcade.Factory#image - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.ImageWithDynamicBody} The Image object that was created. - */ - image: function (x, y, key, frame) - { - var image = new ArcadeImage(this.scene, x, y, key, frame); - - this.sys.displayList.add(image); - - this.world.enableBody(image, CONST.DYNAMIC_BODY); - - return image; - }, - - /** - * Creates a new Arcade Sprite object with a Static body. - * - * @method Phaser.Physics.Arcade.Factory#staticSprite - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created. - */ - staticSprite: function (x, y, key, frame) - { - var sprite = new ArcadeSprite(this.scene, x, y, key, frame); - - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); - - this.world.enableBody(sprite, CONST.STATIC_BODY); - - return sprite; - }, - - /** - * Creates a new Arcade Sprite object with a Dynamic body. - * - * @method Phaser.Physics.Arcade.Factory#sprite - * @since 3.0.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 Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.SpriteWithDynamicBody} The Sprite object that was created. - */ - sprite: function (x, y, key, frame) - { - var sprite = new ArcadeSprite(this.scene, x, y, key, frame); - - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); - - this.world.enableBody(sprite, CONST.DYNAMIC_BODY); - - return sprite; - }, - - /** - * Creates a Static Physics Group object. - * All Game Objects created by this Group will automatically be static Arcade Physics objects. - * - * @method Phaser.Physics.Arcade.Factory#staticGroup - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - * - * @return {Phaser.Physics.Arcade.StaticGroup} The Static Group object that was created. - */ - staticGroup: function (children, config) - { - return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config)); - }, - - /** - * Creates a Physics Group object. - * All Game Objects created by this Group will automatically be dynamic Arcade Physics objects. - * - * @method Phaser.Physics.Arcade.Factory#group - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - * - * @return {Phaser.Physics.Arcade.Group} The Group object that was created. - */ - group: function (children, config) - { - return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config)); - }, - - /** - * Destroys this Factory. - * - * @method Phaser.Physics.Arcade.Factory#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.world = null; - this.scene = null; - this.sys = null; - } - -}); - -module.exports = Factory; - - -/***/ }), -/* 500 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(238); -var Image = __webpack_require__(124); - -/** - * @classdesc - * An Arcade Physics Image is an Image with an Arcade Physics body and related components. - * The body can be dynamic or static. - * - * The main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image. - * - * @class Image - * @extends Phaser.GameObjects.Image - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @extends Phaser.Physics.Arcade.Components.Acceleration - * @extends Phaser.Physics.Arcade.Components.Angular - * @extends Phaser.Physics.Arcade.Components.Bounce - * @extends Phaser.Physics.Arcade.Components.Debug - * @extends Phaser.Physics.Arcade.Components.Drag - * @extends Phaser.Physics.Arcade.Components.Enable - * @extends Phaser.Physics.Arcade.Components.Friction - * @extends Phaser.Physics.Arcade.Components.Gravity - * @extends Phaser.Physics.Arcade.Components.Immovable - * @extends Phaser.Physics.Arcade.Components.Mass - * @extends Phaser.Physics.Arcade.Components.Pushable - * @extends Phaser.Physics.Arcade.Components.Size - * @extends Phaser.Physics.Arcade.Components.Velocity - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Tint - * @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 - 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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - */ -var ArcadeImage = new Class({ - - Extends: Image, - - Mixins: [ - Components.Acceleration, - Components.Angular, - Components.Bounce, - Components.Debug, - Components.Drag, - Components.Enable, - Components.Friction, - Components.Gravity, - Components.Immovable, - Components.Mass, - Components.Pushable, - Components.Size, - Components.Velocity - ], - - initialize: - - function ArcadeImage (scene, x, y, texture, frame) - { - Image.call(this, scene, x, y, texture, frame); - - /** - * This Game Object's Physics Body. - * - * @name Phaser.Physics.Arcade.Image#body - * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} - * @default null - * @since 3.0.0 - */ - this.body = null; - } - -}); - -module.exports = ArcadeImage; - - -/***/ }), -/* 501 */ -/***/ (function(module, exports, __webpack_require__) { - -var OverlapRect = __webpack_require__(239); -var Circle = __webpack_require__(61); -var CircleToCircle = __webpack_require__(226); -var CircleToRectangle = __webpack_require__(149); - -/** - * This method will search the given circular area and return an array of all physics bodies that - * overlap with it. It can return either Dynamic, Static bodies or a mixture of both. - * - * A body only has to intersect with the search area to be considered, it doesn't have to be fully - * contained within it. - * - * If Arcade Physics is set to use the RTree (which it is by default) then the search is rather fast, - * otherwise the search is O(N) for Dynamic Bodies. - * - * @function Phaser.Physics.Arcade.Components.OverlapCirc - * @since 3.21.0 - * - * @param {number} x - The x coordinate of the center of the area to search within. - * @param {number} y - The y coordinate of the center of the area to search within. - * @param {number} radius - The radius of the area to search within. - * @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies? - * @param {boolean} [includeStatic=false] - Should the search include Static Bodies? - * - * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. - */ -var OverlapCirc = function (world, x, y, radius, includeDynamic, includeStatic) -{ - var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); - - if (bodiesInRect.length === 0) - { - return bodiesInRect; - } - - var area = new Circle(x, y, radius); - var circFromBody = new Circle(); - var bodiesInArea = []; - - for (var i = 0; i < bodiesInRect.length; i++) - { - var body = bodiesInRect[i]; - - if (body.isCircle) - { - circFromBody.setTo(body.center.x, body.center.y, body.halfWidth); - - if (CircleToCircle(area, circFromBody)) - { - bodiesInArea.push(body); - } - } - else if (CircleToRectangle(area, body)) - { - bodiesInArea.push(body); - } - } - - return bodiesInArea; -}; - -module.exports = OverlapCirc; - - -/***/ }), -/* 502 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(108); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * An Arcade Physics Group object. - * - * The primary use of a Physics Group is a way to collect together physics enable objects - * that share the same intrinsic structure into a single pool. They can they be easily - * compared against other Groups, or Game Objects. - * - * All Game Objects created by, or added to this Group will automatically be given **dynamic** - * Arcade Physics bodies (if they have no body already) and the bodies will receive the - * Groups {@link Phaser.Physics.Arcade.Group#defaults default values}. - * - * You should not pass objects into this Group that should not receive a body. For example, - * do not add basic Geometry or Tilemap Layers into a Group, as they will not behave in the - * way you may expect. Groups should all ideally have objects of the same type in them. - * - * If you wish to create a Group filled with Static Bodies, please see {@link Phaser.Physics.Arcade.StaticGroup}. - * - * @class Group - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The physics simulation. - * @param {Phaser.Scene} scene - The scene this group belongs to. - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - */ -var PhysicsGroup = new Class({ - - Extends: Group, - - initialize: - - function PhysicsGroup (world, scene, children, config) - { - if (!children && !config) - { - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - else if (IsPlainObject(children)) - { - // children is a plain object, so swizzle them: - config = children; - children = null; - - config.internalCreateCallback = this.createCallbackHandler; - config.internalRemoveCallback = this.removeCallbackHandler; - } - else if (Array.isArray(children) && IsPlainObject(children[0])) - { - // children is an array of plain objects (i.e., configs) - config = children[0]; - - var _this = this; - - children.forEach(function (singleConfig) - { - singleConfig.internalCreateCallback = _this.createCallbackHandler; - singleConfig.internalRemoveCallback = _this.removeCallbackHandler; - }); - - children = null; - } - else - { - // config is not defined and children is not a plain object nor an array of plain objects - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - - /** - * The physics simulation. - * - * @name Phaser.Physics.Arcade.Group#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The class to create new Group members from. - * - * This should be either `Phaser.Physics.Arcade.Image`, `Phaser.Physics.Arcade.Sprite`, or a class extending one of those. - * - * @name Phaser.Physics.Arcade.Group#classType - * @type {Function} - * @default ArcadeSprite - * @since 3.0.0 - */ - config.classType = GetFastValue(config, 'classType', ArcadeSprite); - - /** - * The physics type of the Group's members. - * - * @name Phaser.Physics.Arcade.Group#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.DYNAMIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.DYNAMIC_BODY; - - /** - * Default physics properties applied to Game Objects added to the Group or created by the Group. Derived from the `config` argument. - * - * You can remove the default values by setting this property to `{}`. - * - * @name Phaser.Physics.Arcade.Group#defaults - * @type {Phaser.Types.Physics.Arcade.PhysicsGroupDefaults} - * @since 3.0.0 - */ - this.defaults = { - setCollideWorldBounds: GetFastValue(config, 'collideWorldBounds', false), - setBoundsRectangle: GetFastValue(config, 'customBoundsRectangle', null), - setAccelerationX: GetFastValue(config, 'accelerationX', 0), - setAccelerationY: GetFastValue(config, 'accelerationY', 0), - setAllowDrag: GetFastValue(config, 'allowDrag', true), - setAllowGravity: GetFastValue(config, 'allowGravity', true), - setAllowRotation: GetFastValue(config, 'allowRotation', true), - setBounceX: GetFastValue(config, 'bounceX', 0), - setBounceY: GetFastValue(config, 'bounceY', 0), - setDragX: GetFastValue(config, 'dragX', 0), - setDragY: GetFastValue(config, 'dragY', 0), - setEnable: GetFastValue(config, 'enable', true), - setGravityX: GetFastValue(config, 'gravityX', 0), - setGravityY: GetFastValue(config, 'gravityY', 0), - setFrictionX: GetFastValue(config, 'frictionX', 0), - setFrictionY: GetFastValue(config, 'frictionY', 0), - setMaxVelocityX: GetFastValue(config, 'maxVelocityX', 10000), - setMaxVelocityY: GetFastValue(config, 'maxVelocityY', 10000), - setVelocityX: GetFastValue(config, 'velocityX', 0), - setVelocityY: GetFastValue(config, 'velocityY', 0), - setAngularVelocity: GetFastValue(config, 'angularVelocity', 0), - setAngularAcceleration: GetFastValue(config, 'angularAcceleration', 0), - setAngularDrag: GetFastValue(config, 'angularDrag', 0), - setMass: GetFastValue(config, 'mass', 1), - setImmovable: GetFastValue(config, 'immovable', false) - }; - - Group.call(this, scene, children, config); - - /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.Physics.Arcade.Group#type - * @type {string} - * @default 'PhysicsGroup' - * @since 3.21.0 - */ - this.type = 'PhysicsGroup'; - }, - - /** - * Enables a Game Object's Body and assigns `defaults`. Called when a Group member is added or created. - * - * @method Phaser.Physics.Arcade.Group#createCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object being added. - */ - createCallbackHandler: function (child) - { - if (!child.body) - { - this.world.enableBody(child, CONST.DYNAMIC_BODY); - } - - var body = child.body; - - for (var key in this.defaults) - { - body[key](this.defaults[key]); - } - }, - - /** - * Disables a Game Object's Body. Called when a Group member is removed. - * - * @method Phaser.Physics.Arcade.Group#removeCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object being removed. - */ - removeCallbackHandler: function (child) - { - if (child.body) - { - this.world.disableBody(child); - } - }, - - /** - * Sets the velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity. - * @param {number} y - The vertical velocity. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x, y), the second (x + step, y + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocity: function (x, y, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.set(x + (i * step), y + (i * step)); - } - - return this; - }, - - /** - * Sets the horizontal velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocityX - * @since 3.0.0 - * - * @param {number} value - The velocity value. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x), the second (x + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocityX: function (value, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.x = value + (i * step); - } - - return this; - }, - - /** - * Sets the vertical velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocityY - * @since 3.0.0 - * - * @param {number} value - The velocity value. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (y), the second (y + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocityY: function (value, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.y = value + (i * step); - } - - return this; - } - -}); - -module.exports = PhysicsGroup; - - -/***/ }), -/* 503 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(108); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * An Arcade Physics Static Group object. - * - * All Game Objects created by or added to this Group will automatically be given static Arcade Physics bodies, if they have no body. - * - * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Group}. - * - * @class StaticGroup - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The physics simulation. - * @param {Phaser.Scene} scene - The scene this group belongs to. - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - */ -var StaticPhysicsGroup = new Class({ - - Extends: Group, - - initialize: - - function StaticPhysicsGroup (world, scene, children, config) - { - if (!children && !config) - { - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler, - createMultipleCallback: this.createMultipleCallbackHandler, - classType: ArcadeSprite - }; - } - else if (IsPlainObject(children)) - { - // children is a plain object, so swizzle them: - config = children; - children = null; - - config.internalCreateCallback = this.createCallbackHandler; - config.internalRemoveCallback = this.removeCallbackHandler; - config.createMultipleCallback = this.createMultipleCallbackHandler; - config.classType = GetFastValue(config, 'classType', ArcadeSprite); - } - else if (Array.isArray(children) && IsPlainObject(children[0])) - { - // children is an array of plain objects - config = children; - children = null; - - config.forEach(function (singleConfig) - { - singleConfig.internalCreateCallback = this.createCallbackHandler; - singleConfig.internalRemoveCallback = this.removeCallbackHandler; - singleConfig.createMultipleCallback = this.createMultipleCallbackHandler; - singleConfig.classType = GetFastValue(singleConfig, 'classType', ArcadeSprite); - }); - } - else - { - // config is not defined and children is not a plain object nor an array of plain objects - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - - /** - * The physics simulation. - * - * @name Phaser.Physics.Arcade.StaticGroup#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The scene this group belongs to. - * - * @name Phaser.Physics.Arcade.StaticGroup#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.STATIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.STATIC_BODY; - - Group.call(this, scene, children, config); - - /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.Physics.Arcade.StaticGroup#type - * @type {string} - * @default 'StaticPhysicsGroup' - * @since 3.21.0 - */ - this.type = 'StaticPhysicsGroup'; - }, - - /** - * Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation. - * - * @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The new group member. - * - * @see Phaser.Physics.Arcade.World#enableBody - */ - createCallbackHandler: function (child) - { - if (!child.body) - { - this.world.enableBody(child, CONST.STATIC_BODY); - } - }, - - /** - * Disables the group member's physics body, removing it from the simulation. - * - * @method Phaser.Physics.Arcade.StaticGroup#removeCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The group member being removed. - * - * @see Phaser.Physics.Arcade.World#disableBody - */ - removeCallbackHandler: function (child) - { - if (child.body) - { - this.world.disableBody(child); - } - }, - - /** - * Refreshes the group. - * - * @method Phaser.Physics.Arcade.StaticGroup#createMultipleCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject[]} entries - The newly created group members. - * - * @see Phaser.Physics.Arcade.StaticGroup#refresh - */ - createMultipleCallbackHandler: function () - { - this.refresh(); - }, - - /** - * Resets each Body to the position of its parent Game Object. - * Body sizes aren't changed (use {@link Phaser.Physics.Arcade.Components.Enable#refreshBody} for that). - * - * @method Phaser.Physics.Arcade.StaticGroup#refresh - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.StaticGroup} This group. - * - * @see Phaser.Physics.Arcade.StaticBody#reset - */ - refresh: function () - { - var children = this.children.entries; - - for (var i = 0; i < children.length; i++) - { - children[i].body.reset(); - } - - return this; - } - -}); - -module.exports = StaticPhysicsGroup; - - -/***/ }), -/* 504 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AngleBetweenPoints = __webpack_require__(344); -var Body = __webpack_require__(505); -var Clamp = __webpack_require__(17); -var Class = __webpack_require__(0); -var Collider = __webpack_require__(506); -var CONST = __webpack_require__(59); -var DistanceBetween = __webpack_require__(48); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(240); -var FuzzyEqual = __webpack_require__(121); -var FuzzyGreaterThan = __webpack_require__(348); -var FuzzyLessThan = __webpack_require__(349); -var GetOverlapX = __webpack_require__(241); -var GetOverlapY = __webpack_require__(242); -var GetTilesWithinWorldXY = __webpack_require__(507); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); -var ProcessQueue = __webpack_require__(206); -var ProcessTileCallbacks = __webpack_require__(508); -var Rectangle = __webpack_require__(10); -var RTree = __webpack_require__(509); -var SeparateTile = __webpack_require__(510); -var SeparateX = __webpack_require__(515); -var SeparateY = __webpack_require__(516); -var Set = __webpack_require__(147); -var StaticBody = __webpack_require__(517); -var TileIntersectsBody = __webpack_require__(243); -var TransformMatrix = __webpack_require__(25); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * The Arcade Physics World. - * - * The World is responsible for creating, managing, colliding and updating all of the bodies within it. - * - * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. - * - * @class World - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to which this World instance belongs. - * @param {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} config - An Arcade Physics Configuration object. - */ -var World = new Class({ - - Extends: EventEmitter, - - initialize: - - function World (scene, config) - { - EventEmitter.call(this); - - /** - * The Scene this simulation belongs to. - * - * @name Phaser.Physics.Arcade.World#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * Dynamic Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#bodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.bodies = new Set(); - - /** - * Static Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#staticBodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.staticBodies = new Set(); - - /** - * Static Bodies marked for deletion. - * - * @name Phaser.Physics.Arcade.World#pendingDestroy - * @type {Phaser.Structs.Set.<(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)>} - * @since 3.1.0 - */ - this.pendingDestroy = new Set(); - - /** - * This simulation's collision processors. - * - * @name Phaser.Physics.Arcade.World#colliders - * @type {Phaser.Structs.ProcessQueue.} - * @since 3.0.0 - */ - this.colliders = new ProcessQueue(); - - /** - * Acceleration of Bodies due to gravity, in pixels per second. - * - * @name Phaser.Physics.Arcade.World#gravity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.gravity = new Vector2(GetValue(config, 'gravity.x', 0), GetValue(config, 'gravity.y', 0)); - - /** - * A boundary constraining Bodies. - * - * @name Phaser.Physics.Arcade.World#bounds - * @type {Phaser.Geom.Rectangle} - * @since 3.0.0 - */ - this.bounds = new Rectangle( - GetValue(config, 'x', 0), - GetValue(config, 'y', 0), - GetValue(config, 'width', scene.sys.scale.width), - GetValue(config, 'height', scene.sys.scale.height) - ); - - /** - * The boundary edges that Bodies can collide with. - * - * @name Phaser.Physics.Arcade.World#checkCollision - * @type {Phaser.Types.Physics.Arcade.CheckCollisionObject} - * @since 3.0.0 - */ - this.checkCollision = { - up: GetValue(config, 'checkCollision.up', true), - down: GetValue(config, 'checkCollision.down', true), - left: GetValue(config, 'checkCollision.left', true), - right: GetValue(config, 'checkCollision.right', true) - }; - - /** - * The number of physics steps to be taken per second. - * - * This property is read-only. Use the `setFPS` method to modify it at run-time. - * - * @name Phaser.Physics.Arcade.World#fps - * @readonly - * @type {number} - * @default 60 - * @since 3.10.0 - */ - this.fps = GetValue(config, 'fps', 60); - - /** - * Should Physics use a fixed update time-step (true) or sync to the render fps (false)?. - * False value of this property disables fps and timeScale properties. - * - * @name Phaser.Physics.Arcade.World#fixedStep - * @type {boolean} - * @default true - * @since 3.23.0 - */ - this.fixedStep = GetValue(config, 'fixedStep', true); - - /** - * The amount of elapsed ms since the last frame. - * - * @name Phaser.Physics.Arcade.World#_elapsed - * @private - * @type {number} - * @since 3.10.0 - */ - this._elapsed = 0; - - /** - * Internal frame time value. - * - * @name Phaser.Physics.Arcade.World#_frameTime - * @private - * @type {number} - * @since 3.10.0 - */ - this._frameTime = 1 / this.fps; - - /** - * Internal frame time ms value. - * - * @name Phaser.Physics.Arcade.World#_frameTimeMS - * @private - * @type {number} - * @since 3.10.0 - */ - this._frameTimeMS = 1000 * this._frameTime; - - /** - * The number of steps that took place in the last frame. - * - * @name Phaser.Physics.Arcade.World#stepsLastFrame - * @readonly - * @type {number} - * @since 3.10.0 - */ - this.stepsLastFrame = 0; - - /** - * Scaling factor applied to the frame rate. - * - * - 1.0 = normal speed - * - 2.0 = half speed - * - 0.5 = double speed - * - * @name Phaser.Physics.Arcade.World#timeScale - * @type {number} - * @default 1 - * @since 3.10.0 - */ - this.timeScale = GetValue(config, 'timeScale', 1); - - /** - * The maximum absolute difference of a Body's per-step velocity and its overlap with another Body that will result in separation on *each axis*. - * Larger values favor separation. - * Smaller values favor no separation. - * - * @name Phaser.Physics.Arcade.World#OVERLAP_BIAS - * @type {number} - * @default 4 - * @since 3.0.0 - */ - this.OVERLAP_BIAS = GetValue(config, 'overlapBias', 4); - - /** - * The maximum absolute value of a Body's overlap with a tile that will result in separation on *each axis*. - * Larger values favor separation. - * Smaller values favor no separation. - * The optimum value may be similar to the tile size. - * - * @name Phaser.Physics.Arcade.World#TILE_BIAS - * @type {number} - * @default 16 - * @since 3.0.0 - */ - this.TILE_BIAS = GetValue(config, 'tileBias', 16); - - /** - * Always separate overlapping Bodies horizontally before vertically. - * False (the default) means Bodies are first separated on the axis of greater gravity, or the vertical axis if neither is greater. - * - * @name Phaser.Physics.Arcade.World#forceX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.forceX = GetValue(config, 'forceX', false); - - /** - * Whether the simulation advances with the game loop. - * - * @name Phaser.Physics.Arcade.World#isPaused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isPaused = GetValue(config, 'isPaused', false); - - /** - * Temporary total of colliding Bodies. - * - * @name Phaser.Physics.Arcade.World#_total - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._total = 0; - - /** - * Enables the debug display. - * - * @name Phaser.Physics.Arcade.World#drawDebug - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.drawDebug = GetValue(config, 'debug', false); - - /** - * The graphics object drawing the debug display. - * - * @name Phaser.Physics.Arcade.World#debugGraphic - * @type {Phaser.GameObjects.Graphics} - * @since 3.0.0 - */ - this.debugGraphic; - - /** - * Default debug display settings for new Bodies. - * - * @name Phaser.Physics.Arcade.World#defaults - * @type {Phaser.Types.Physics.Arcade.ArcadeWorldDefaults} - * @since 3.0.0 - */ - this.defaults = { - debugShowBody: GetValue(config, 'debugShowBody', true), - debugShowStaticBody: GetValue(config, 'debugShowStaticBody', true), - debugShowVelocity: GetValue(config, 'debugShowVelocity', true), - bodyDebugColor: GetValue(config, 'debugBodyColor', 0xff00ff), - staticBodyDebugColor: GetValue(config, 'debugStaticBodyColor', 0x0000ff), - velocityDebugColor: GetValue(config, 'debugVelocityColor', 0x00ff00) - }; - - /** - * The maximum number of items per node on the RTree. - * - * This is ignored if `useTree` is `false`. If you have a large number of bodies in - * your world then you may find search performance improves by increasing this value, - * to allow more items per node and less node division. - * - * @name Phaser.Physics.Arcade.World#maxEntries - * @type {number} - * @default 16 - * @since 3.0.0 - */ - this.maxEntries = GetValue(config, 'maxEntries', 16); - - /** - * Should this Arcade Physics World use an RTree for Dynamic bodies? - * - * An RTree is a fast way of spatially sorting of all the bodies in the world. - * However, at certain limits, the cost of clearing and inserting the bodies into the - * tree every frame becomes more expensive than the search speed gains it provides. - * - * If you have a large number of dynamic bodies in your world then it may be best to - * disable the use of the RTree by setting this property to `false` in the physics config. - * - * The number it can cope with depends on browser and device, but a conservative estimate - * of around 5,000 bodies should be considered the max before disabling it. - * - * This only applies to dynamic bodies. Static bodies are always kept in an RTree, - * because they don't have to be cleared every frame, so you benefit from the - * massive search speeds all the time. - * - * @name Phaser.Physics.Arcade.World#useTree - * @type {boolean} - * @default true - * @since 3.10.0 - */ - this.useTree = GetValue(config, 'useTree', true); - - /** - * The spatial index of Dynamic Bodies. - * - * @name Phaser.Physics.Arcade.World#tree - * @type {Phaser.Structs.RTree} - * @since 3.0.0 - */ - this.tree = new RTree(this.maxEntries); - - /** - * The spatial index of Static Bodies. - * - * @name Phaser.Physics.Arcade.World#staticTree - * @type {Phaser.Structs.RTree} - * @since 3.0.0 - */ - this.staticTree = new RTree(this.maxEntries); - - /** - * Recycled input for tree searches. - * - * @name Phaser.Physics.Arcade.World#treeMinMax - * @type {Phaser.Types.Physics.Arcade.ArcadeWorldTreeMinMax} - * @since 3.0.0 - */ - this.treeMinMax = { minX: 0, minY: 0, maxX: 0, maxY: 0 }; - - /** - * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. - * - * @name Phaser.Physics.Arcade.World#_tempMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix = new TransformMatrix(); - - /** - * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. - * - * @name Phaser.Physics.Arcade.World#_tempMatrix2 - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - if (this.drawDebug) - { - this.createDebugGraphic(); - } - }, - - /** - * Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group. - * - * The difference between this and the `enableBody` method is that you can pass arrays or Groups - * to this method. - * - * You can specify if the bodies are to be Dynamic or Static. A dynamic body can move via velocity and - * acceleration. A static body remains fixed in place and as such is able to use an optimized search - * tree, making it ideal for static elements such as level objects. You can still collide and overlap - * with static bodies. - * - * Normally, rather than calling this method directly, you'd use the helper methods available in the - * Arcade Physics Factory, such as: - * - * ```javascript - * this.physics.add.image(x, y, textureKey); - * this.physics.add.sprite(x, y, textureKey); - * ``` - * - * Calling factory methods encapsulates the creation of a Game Object and the creation of its - * body at the same time. If you are creating custom classes then you can pass them to this - * method to have their bodies created. - * - * @method Phaser.Physics.Arcade.World#enable - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to create the bodies. - * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. - */ - enable: function (object, bodyType) - { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!Array.isArray(object)) - { - object = [ object ]; - } - - for (var i = 0; i < object.length; i++) - { - var entry = object[i]; - - if (entry.isParent) - { - var children = entry.getChildren(); - - for (var c = 0; c < children.length; c++) - { - var child = children[c]; - - if (child.isParent) - { - // Handle Groups nested inside of Groups - this.enable(child, bodyType); - } - else - { - this.enableBody(child, bodyType); - } - } - } - else - { - this.enableBody(entry, bodyType); - } - } - }, - - /** - * Creates an Arcade Physics Body on a single Game Object. - * - * If the Game Object already has a body, this method will simply add it back into the simulation. - * - * You can specify if the body is Dynamic or Static. A dynamic body can move via velocity and - * acceleration. A static body remains fixed in place and as such is able to use an optimized search - * tree, making it ideal for static elements such as level objects. You can still collide and overlap - * with static bodies. - * - * Normally, rather than calling this method directly, you'd use the helper methods available in the - * Arcade Physics Factory, such as: - * - * ```javascript - * this.physics.add.image(x, y, textureKey); - * this.physics.add.sprite(x, y, textureKey); - * ``` - * - * Calling factory methods encapsulates the creation of a Game Object and the creation of its - * body at the same time. If you are creating custom classes then you can pass them to this - * method to have their bodies created. - * - * @method Phaser.Physics.Arcade.World#enableBody - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} object - The Game Object on which to create the body. - * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. - * - * @return {Phaser.GameObjects.GameObject} The Game Object on which the body was created. - */ - enableBody: function (object, bodyType) - { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!object.body) - { - if (bodyType === CONST.DYNAMIC_BODY) - { - object.body = new Body(this, object); - } - else if (bodyType === CONST.STATIC_BODY) - { - object.body = new StaticBody(this, object); - } - } - - this.add(object.body); - - return object; - }, - - /** - * Adds an existing Arcade Physics Body or StaticBody to the simulation. - * - * The body is enabled and added to the local search trees. - * - * @method Phaser.Physics.Arcade.World#add - * @since 3.10.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be added to the simulation. - * - * @return {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} The Body that was added to the simulation. - */ - add: function (body) - { - if (body.physicsType === CONST.DYNAMIC_BODY) - { - this.bodies.set(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - this.staticBodies.set(body); - - this.staticTree.insert(body); - } - - body.enable = true; - - return body; - }, - - /** - * Disables the Arcade Physics Body of a Game Object, an array of Game Objects, or the children of a Group. - * - * The difference between this and the `disableBody` method is that you can pass arrays or Groups - * to this method. - * - * The body itself is not deleted, it just has its `enable` property set to false, which - * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. - * - * @method Phaser.Physics.Arcade.World#disable - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to disable the bodies. - */ - disable: function (object) - { - if (!Array.isArray(object)) - { - object = [ object ]; - } - - for (var i = 0; i < object.length; i++) - { - var entry = object[i]; - - if (entry.isParent) - { - var children = entry.getChildren(); - - for (var c = 0; c < children.length; c++) - { - var child = children[c]; - - if (child.isParent) - { - // Handle Groups nested inside of Groups - this.disable(child); - } - else - { - this.disableBody(child.body); - } - } - } - else - { - this.disableBody(entry.body); - } - } - }, - - /** - * Disables an existing Arcade Physics Body or StaticBody and removes it from the simulation. - * - * The body is disabled and removed from the local search trees. - * - * The body itself is not deleted, it just has its `enable` property set to false, which - * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. - * - * @method Phaser.Physics.Arcade.World#disableBody - * @since 3.0.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be disabled. - */ - disableBody: function (body) - { - this.remove(body); - - body.enable = false; - }, - - /** - * Removes an existing Arcade Physics Body or StaticBody from the simulation. - * - * The body is disabled and removed from the local search trees. - * - * The body itself is not deleted, it just has its `enabled` property set to false, which - * means you can re-enable it again at any point by passing it to enable `enable` or `add`. - * - * @method Phaser.Physics.Arcade.World#remove - * @since 3.0.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation. - */ - remove: function (body) - { - if (body.physicsType === CONST.DYNAMIC_BODY) - { - this.tree.remove(body); - this.bodies.delete(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - this.staticBodies.delete(body); - this.staticTree.remove(body); - } - }, - - /** - * Creates a Graphics Game Object that the world will use to render the debug display to. - * - * This is called automatically when the World is instantiated if the `debug` config property - * was set to `true`. However, you can call it at any point should you need to display the - * debug Graphic from a fixed point. - * - * You can control which objects are drawn to the Graphics object, and the colors they use, - * by setting the debug properties in the physics config. - * - * You should not typically use this in a production game. Use it to aid during debugging. - * - * @method Phaser.Physics.Arcade.World#createDebugGraphic - * @since 3.0.0 - * - * @return {Phaser.GameObjects.Graphics} The Graphics object that was created for use by the World. - */ - createDebugGraphic: function () - { - var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); - - graphic.setDepth(Number.MAX_VALUE); - - this.debugGraphic = graphic; - - this.drawDebug = true; - - return graphic; - }, - - /** - * Sets the position, size and properties of the World boundary. - * - * The World boundary is an invisible rectangle that defines the edges of the World. - * If a Body is set to collide with the world bounds then it will automatically stop - * when it reaches any of the edges. You can optionally set which edges of the boundary - * should be checked against. - * - * @method Phaser.Physics.Arcade.World#setBounds - * @since 3.0.0 - * - * @param {number} x - The top-left x coordinate of the boundary. - * @param {number} y - The top-left y coordinate of the boundary. - * @param {number} width - The width of the boundary. - * @param {number} height - The height of the boundary. - * @param {boolean} [checkLeft] - Should bodies check against the left edge of the boundary? - * @param {boolean} [checkRight] - Should bodies check against the right edge of the boundary? - * @param {boolean} [checkUp] - Should bodies check against the top edge of the boundary? - * @param {boolean} [checkDown] - Should bodies check against the bottom edge of the boundary? - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - setBounds: function (x, y, width, height, checkLeft, checkRight, checkUp, checkDown) - { - this.bounds.setTo(x, y, width, height); - - if (checkLeft !== undefined) - { - this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); - } - - return this; - }, - - /** - * Enables or disables collisions on each edge of the World boundary. - * - * @method Phaser.Physics.Arcade.World#setBoundsCollision - * @since 3.0.0 - * - * @param {boolean} [left=true] - Should bodies check against the left edge of the boundary? - * @param {boolean} [right=true] - Should bodies check against the right edge of the boundary? - * @param {boolean} [up=true] - Should bodies check against the top edge of the boundary? - * @param {boolean} [down=true] - Should bodies check against the bottom edge of the boundary? - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - setBoundsCollision: function (left, right, up, down) - { - if (left === undefined) { left = true; } - if (right === undefined) { right = true; } - if (up === undefined) { up = true; } - if (down === undefined) { down = true; } - - this.checkCollision.left = left; - this.checkCollision.right = right; - this.checkCollision.up = up; - this.checkCollision.down = down; - - return this; - }, - - /** - * Pauses the simulation. - * - * A paused simulation does not update any existing bodies, or run any Colliders. - * - * However, you can still enable and disable bodies within it, or manually run collide or overlap - * checks. - * - * @method Phaser.Physics.Arcade.World#pause - * @fires Phaser.Physics.Arcade.Events#PAUSE - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - pause: function () - { - this.isPaused = true; - - this.emit(Events.PAUSE); - - return this; - }, - - /** - * Resumes the simulation, if paused. - * - * @method Phaser.Physics.Arcade.World#resume - * @fires Phaser.Physics.Arcade.Events#RESUME - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - resume: function () - { - this.isPaused = false; - - this.emit(Events.RESUME); - - return this; - }, - - /** - * Creates a new Collider object and adds it to the simulation. - * - * A Collider is a way to automatically perform collision checks between two objects, - * calling the collide and process callbacks if they occur. - * - * Colliders are run as part of the World update, after all of the Bodies have updated. - * - * By creating a Collider you don't need then call `World.collide` in your `update` loop, - * as it will be handled for you automatically. - * - * @method Phaser.Physics.Arcade.World#addCollider - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#collide - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - addCollider: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); - - this.colliders.add(collider); - - return collider; - }, - - /** - * Creates a new Overlap Collider object and adds it to the simulation. - * - * A Collider is a way to automatically perform overlap checks between two objects, - * calling the collide and process callbacks if they occur. - * - * Colliders are run as part of the World update, after all of the Bodies have updated. - * - * By creating a Collider you don't need then call `World.overlap` in your `update` loop, - * as it will be handled for you automatically. - * - * @method Phaser.Physics.Arcade.World#addOverlap - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects overlap. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - addOverlap: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); - - this.colliders.add(collider); - - return collider; - }, - - /** - * Removes a Collider from the simulation so it is no longer processed. - * - * This method does not destroy the Collider. If you wish to add it back at a later stage you can call - * `World.colliders.add(Collider)`. - * - * If you no longer need the Collider you can call the `Collider.destroy` method instead, which will - * automatically clear all of its references and then remove it from the World. If you call destroy on - * a Collider you _don't_ need to pass it to this method too. - * - * @method Phaser.Physics.Arcade.World#removeCollider - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Collider} collider - The Collider to remove from the simulation. - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - removeCollider: function (collider) - { - this.colliders.remove(collider); - - return this; - }, - - /** - * Sets the frame rate to run the simulation at. - * - * The frame rate value is used to simulate a fixed update time step. This fixed - * time step allows for a straightforward implementation of a deterministic game state. - * - * This frame rate is independent of the frequency at which the game is rendering. The - * higher you set the fps, the more physics simulation steps will occur per game step. - * Conversely, the lower you set it, the less will take place. - * - * You can optionally advance the simulation directly yourself by calling the `step` method. - * - * @method Phaser.Physics.Arcade.World#setFPS - * @since 3.10.0 - * - * @param {number} framerate - The frame rate to advance the simulation at. - * - * @return {this} This World object. - */ - setFPS: function (framerate) - { - this.fps = framerate; - this._frameTime = 1 / this.fps; - this._frameTimeMS = 1000 * this._frameTime; - - return this; - }, - - /** - * Advances the simulation based on the elapsed time and fps rate. - * - * This is called automatically by your Scene and does not need to be invoked directly. - * - * @method Phaser.Physics.Arcade.World#update - * @fires Phaser.Physics.Arcade.Events#WORLD_STEP - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - update: function (time, delta) - { - if (this.isPaused || this.bodies.size === 0) - { - return; - } - - var i; - var fixedDelta = this._frameTime; - var msPerFrame = this._frameTimeMS * this.timeScale; - - this._elapsed += delta; - - // Update all active bodies - var body; - var bodies = this.bodies.entries; - - // Will a step happen this frame? - var willStep = (this._elapsed >= msPerFrame); - - if (!this.fixedStep) - { - fixedDelta = delta * 0.001; - willStep = true; - this._elapsed = 0; - } - - for (i = 0; i < bodies.length; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.preUpdate(willStep, fixedDelta); - } - } - - // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs - if (willStep) - { - this._elapsed -= msPerFrame; - this.stepsLastFrame = 1; - - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } - - // Process any colliders - var colliders = this.colliders.update(); - - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; - - if (collider.active) - { - collider.update(); - } - } - - this.emit(Events.WORLD_STEP, fixedDelta); - } - - // Process any additional steps this frame - while (this._elapsed >= msPerFrame) - { - this._elapsed -= msPerFrame; - - this.step(fixedDelta); - } - }, - - /** - * Advances the simulation by a time increment. - * - * @method Phaser.Physics.Arcade.World#step - * @fires Phaser.Physics.Arcade.Events#WORLD_STEP - * @since 3.10.0 - * - * @param {number} delta - The delta time amount, in seconds, by which to advance the simulation. - */ - step: function (delta) - { - // Update all active bodies - var i; - var body; - var bodies = this.bodies.entries; - var len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.update(delta); - } - } - - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } - - // Process any colliders - var colliders = this.colliders.update(); - - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; - - if (collider.active) - { - collider.update(); - } - } - - this.emit(Events.WORLD_STEP, delta); - - this.stepsLastFrame++; - }, - - /** - * Updates bodies, draws the debug display, and handles pending queue operations. - * - * @method Phaser.Physics.Arcade.World#postUpdate - * @since 3.0.0 - */ - postUpdate: function () - { - var i; - var body; - var bodies = this.bodies.entries; - var len = bodies.length; - - var dynamic = this.bodies; - var staticBodies = this.staticBodies; - - // We don't need to postUpdate if there wasn't a step this frame - if (this.stepsLastFrame) - { - this.stepsLastFrame = 0; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.postUpdate(); - } - } - } - - if (this.drawDebug) - { - var graphics = this.debugGraphic; - - graphics.clear(); - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - - bodies = staticBodies.entries; - len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - } - - var pending = this.pendingDestroy; - - if (pending.size > 0) - { - var dynamicTree = this.tree; - var staticTree = this.staticTree; - - bodies = pending.entries; - len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.physicsType === CONST.DYNAMIC_BODY) - { - dynamicTree.remove(body); - dynamic.delete(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - staticTree.remove(body); - staticBodies.delete(body); - } - - body.world = undefined; - body.gameObject = undefined; - } - - pending.clear(); - } - }, - - /** - * Calculates a Body's velocity and updates its position. - * - * @method Phaser.Physics.Arcade.World#updateMotion - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to be updated. - * @param {number} delta - The delta value to be used in the motion calculations, in seconds. - */ - updateMotion: function (body, delta) - { - if (body.allowRotation) - { - this.computeAngularVelocity(body, delta); - } - - this.computeVelocity(body, delta); - }, - - /** - * Calculates a Body's angular velocity. - * - * @method Phaser.Physics.Arcade.World#computeAngularVelocity - * @since 3.10.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. - * @param {number} delta - The delta value to be used in the calculation, in seconds. - */ - computeAngularVelocity: function (body, delta) - { - var velocity = body.angularVelocity; - var acceleration = body.angularAcceleration; - var drag = body.angularDrag; - var max = body.maxAngular; - - if (acceleration) - { - velocity += acceleration * delta; - } - else if (body.allowDrag && drag) - { - drag *= delta; - - if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) - { - velocity -= drag; - } - else if (FuzzyLessThan(velocity + drag, 0, 0.1)) - { - velocity += drag; - } - else - { - velocity = 0; - } - } - - velocity = Clamp(velocity, -max, max); - - var velocityDelta = velocity - body.angularVelocity; - - body.angularVelocity += velocityDelta; - body.rotation += (body.angularVelocity * delta); - }, - - /** - * Calculates a Body's per-axis velocity. - * - * @method Phaser.Physics.Arcade.World#computeVelocity - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. - * @param {number} delta - The delta value to be used in the calculation, in seconds. - */ - computeVelocity: function (body, delta) - { - var velocityX = body.velocity.x; - var accelerationX = body.acceleration.x; - var dragX = body.drag.x; - var maxX = body.maxVelocity.x; - - var velocityY = body.velocity.y; - var accelerationY = body.acceleration.y; - var dragY = body.drag.y; - var maxY = body.maxVelocity.y; - - var speed = body.speed; - var maxSpeed = body.maxSpeed; - var allowDrag = body.allowDrag; - var useDamping = body.useDamping; - - if (body.allowGravity) - { - velocityX += (this.gravity.x + body.gravity.x) * delta; - velocityY += (this.gravity.y + body.gravity.y) * delta; - } - - if (accelerationX) - { - velocityX += accelerationX * delta; - } - else if (allowDrag && dragX) - { - if (useDamping) - { - // Damping based deceleration - dragX = Math.pow(dragX, delta); - - velocityX *= dragX; - - speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); - - if (FuzzyEqual(speed, 0, 0.001)) - { - velocityX = 0; - } - } - else - { - // Linear deceleration - dragX *= delta; - - if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) - { - velocityX -= dragX; - } - else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) - { - velocityX += dragX; - } - else - { - velocityX = 0; - } - } - } - - if (accelerationY) - { - velocityY += accelerationY * delta; - } - else if (allowDrag && dragY) - { - if (useDamping) - { - // Damping based deceleration - dragY = Math.pow(dragY, delta); - - velocityY *= dragY; - - speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); - - if (FuzzyEqual(speed, 0, 0.001)) - { - velocityY = 0; - } - } - else - { - // Linear deceleration - dragY *= delta; - - if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) - { - velocityY -= dragY; - } - else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) - { - velocityY += dragY; - } - else - { - velocityY = 0; - } - } - } - - velocityX = Clamp(velocityX, -maxX, maxX); - velocityY = Clamp(velocityY, -maxY, maxY); - - body.velocity.set(velocityX, velocityY); - - if (maxSpeed > -1 && speed > maxSpeed) - { - body.velocity.normalize().scale(maxSpeed); - speed = maxSpeed; - } - - body.speed = speed; - }, - - /** - * Separates two Bodies. - * - * @method Phaser.Physics.Arcade.World#separate - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. - * @param {ArcadePhysicsCallback} [processCallback] - The process callback. - * @param {*} [callbackContext] - The context in which to invoke the callback. - * @param {boolean} [overlapOnly] - If this a collide or overlap check? - * @param {boolean} [intersects] - Assert that the bodies intersect and should not be tested before separation. - * - * @return {boolean} True if separation occurred, otherwise false. - */ - separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects) - { - if ( - !intersects && - !body1.enable || - !body2.enable || - body1.checkCollision.none || - body2.checkCollision.none || - !this.intersects(body1, body2)) - { - return false; - } - - // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort. - if (processCallback && processCallback.call(callbackContext, body1.gameObject, body2.gameObject) === false) - { - return false; - } - - // Circle vs. Circle quick bail out - if (body1.isCircle && body2.isCircle) - { - return this.separateCircle(body1, body2, overlapOnly); - } - - // We define the behavior of bodies in a collision circle and rectangle - // If a collision occurs in the corner points of the rectangle, the body behave like circles - - // Either body1 or body2 is a circle - if (body1.isCircle !== body2.isCircle) - { - var bodyRect = (body1.isCircle) ? body2 : body1; - var bodyCircle = (body1.isCircle) ? body1 : body2; - - var rect = { - x: bodyRect.x, - y: bodyRect.y, - right: bodyRect.right, - bottom: bodyRect.bottom - }; - - var circle = bodyCircle.center; - - if (circle.y < rect.y || circle.y > rect.bottom) - { - if (circle.x < rect.x || circle.x > rect.right) - { - return this.separateCircle(body1, body2, overlapOnly); - } - } - } - - var resultX = false; - var resultY = false; - - // Do we separate on x first or y first or both? - if (overlapOnly) - { - // No separation but we need to calculate overlapX, overlapY, etc. - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - else if (this.forceX || Math.abs(this.gravity.y + body1.gravity.y) < Math.abs(this.gravity.x + body1.gravity.x)) - { - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - - // Are they still intersecting? Let's do the other axis then - if (this.intersects(body1, body2)) - { - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - } - else - { - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - - // Are they still intersecting? Let's do the other axis then - if (this.intersects(body1, body2)) - { - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - } - - var result = (resultX || resultY); - - if (result) - { - if (overlapOnly) - { - if (body1.onOverlap || body2.onOverlap) - { - this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); - } - } - else if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } - } - - return result; - }, - - /** - * Separates two Bodies, when both are circular. - * - * @method Phaser.Physics.Arcade.World#separateCircle - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. - * @param {boolean} [overlapOnly] - If this a collide or overlap check? - * @param {number} [bias] - A small value added to the calculations. - * - * @return {boolean} True if separation occurred, otherwise false. - */ - separateCircle: function (body1, body2, overlapOnly, bias) - { - // Set the bounding box overlap values into the bodies themselves (hence we don't use the return values here) - GetOverlapX(body1, body2, false, bias); - GetOverlapY(body1, body2, false, bias); - - var overlap = 0; - - if (body1.isCircle !== body2.isCircle) - { - var rect = { - x: (body2.isCircle) ? body1.position.x : body2.position.x, - y: (body2.isCircle) ? body1.position.y : body2.position.y, - right: (body2.isCircle) ? body1.right : body2.right, - bottom: (body2.isCircle) ? body1.bottom : body2.bottom - }; - - var circle = { - x: (body1.isCircle) ? body1.center.x : body2.center.x, - y: (body1.isCircle) ? body1.center.y : body2.center.y, - radius: (body1.isCircle) ? body1.halfWidth : body2.halfWidth - }; - - if (circle.y < rect.y) - { - if (circle.x < rect.x) - { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.y) - circle.radius; - } - else if (circle.x > rect.right) - { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.y) - circle.radius; - } - } - else if (circle.y > rect.bottom) - { - if (circle.x < rect.x) - { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.bottom) - circle.radius; - } - else if (circle.x > rect.right) - { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.bottom) - circle.radius; - } - } - - overlap *= -1; - } - else - { - overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y); - } - - body1.overlapR = overlap; - body2.overlapR = overlap; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1.immovable && body2.immovable) || body1.customSeparateX || body2.customSeparateX) - { - if (overlap !== 0 && (body1.onOverlap || body2.onOverlap)) - { - this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); - } - - // return true if there was some overlap, otherwise false - return (overlap !== 0); - } - - var dx = body1.center.x - body2.center.x; - var dy = body1.center.y - body2.center.y; - var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - var nx = ((body2.center.x - body1.center.x) / d) || 0; - var ny = ((body2.center.y - body1.center.y) / d) || 0; - var p = 2 * (body1.velocity.x * nx + body1.velocity.y * ny - body2.velocity.x * nx - body2.velocity.y * ny) / (body1.mass + body2.mass); - - if (body1.immovable || body2.immovable) - { - p *= 2; - } - - if (!body1.immovable) - { - body1.velocity.x = (body1.velocity.x - p / body1.mass * nx); - body1.velocity.y = (body1.velocity.y - p / body1.mass * ny); - } - - if (!body2.immovable) - { - body2.velocity.x = (body2.velocity.x + p / body2.mass * nx); - body2.velocity.y = (body2.velocity.y + p / body2.mass * ny); - } - - if (!body1.immovable && !body2.immovable) - { - overlap /= 2; - } - - // Note: This is inadequate for circle-rectangle separation - - var angle = AngleBetweenPoints(body1.center, body2.center); - var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle); - var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle); - - if (!body1.immovable) - { - body1.x -= overlapX; - body1.y -= overlapY; - - body1.updateCenter(); - } - - if (!body2.immovable) - { - body2.x += overlapX; - body2.y += overlapY; - - body2.updateCenter(); - } - - body1.velocity.x *= body1.bounce.x; - body1.velocity.y *= body1.bounce.y; - body2.velocity.x *= body2.bounce.x; - body2.velocity.y *= body2.bounce.y; - - if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } - - return true; - }, - - /** - * Checks to see if two Bodies intersect at all. - * - * @method Phaser.Physics.Arcade.World#intersects - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first body to check. - * @param {Phaser.Physics.Arcade.Body} body2 - The second body to check. - * - * @return {boolean} True if the two bodies intersect, otherwise false. - */ - intersects: function (body1, body2) - { - if (body1 === body2) - { - return false; - } - - if (!body1.isCircle && !body2.isCircle) - { - // Rect vs. Rect - return !( - body1.right <= body2.position.x || - body1.bottom <= body2.position.y || - body1.position.x >= body2.right || - body1.position.y >= body2.bottom - ); - } - else if (body1.isCircle) - { - if (body2.isCircle) - { - // Circle vs. Circle - return DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y) <= (body1.halfWidth + body2.halfWidth); - } - else - { - // Circle vs. Rect - return this.circleBodyIntersects(body1, body2); - } - } - else - { - // Rect vs. Circle - return this.circleBodyIntersects(body2, body1); - } - }, - - /** - * Tests if a circular Body intersects with another Body. - * - * @method Phaser.Physics.Arcade.World#circleBodyIntersects - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} circle - The circular body to test. - * @param {Phaser.Physics.Arcade.Body} body - The rectangular body to test. - * - * @return {boolean} True if the two bodies intersect, otherwise false. - */ - circleBodyIntersects: function (circle, body) - { - var x = Clamp(circle.center.x, body.left, body.right); - var y = Clamp(circle.center.y, body.top, body.bottom); - - var dx = (circle.center.x - x) * (circle.center.x - x); - var dy = (circle.center.y - y) * (circle.center.y - y); - - return (dx + dy) <= (circle.halfWidth * circle.halfWidth); - }, - - /** - * Tests if Game Objects overlap. - * - * See details in {@link Phaser.Physics.Arcade.World#collide}. - * - * @method Phaser.Physics.Arcade.World#overlap - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `overlapCallback` will only be called if this callback returns `true`. - * @param {*} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if at least one Game Object overlaps another. - * - * @see Phaser.Physics.Arcade.World#collide - */ - overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) - { - if (overlapCallback === undefined) { overlapCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = overlapCallback; } - - return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true); - }, - - /** - * Performs a collision check and separation between the two physics enabled objects given, which can be single - * Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups. - * - * If you don't require separation then use {@link Phaser.Physics.Arcade.World#overlap} instead. - * - * If two Groups or arrays are passed, each member of one will be tested against each member of the other. - * - * If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members. - * - * If **only** one Array is passed, the array is iterated and every element in it is tested against the others. - * - * Two callbacks can be provided; they receive the colliding game objects as arguments. - * If an overlap is detected, the `processCallback` is called first. It can cancel the collision by returning false. - * Next the objects are separated and `collideCallback` is invoked. - * - * Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable - * for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other. - * The separation that stops two objects penetrating may create a new penetration against a different object. If you - * require a high level of stability please consider using an alternative physics system, such as Matter.js. - * - * @method Phaser.Physics.Arcade.World#collide - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} `true` if any overlapping Game Objects were separated, otherwise `false`. - */ - collide: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); - }, - - /** - * Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideObjects - * @private - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideObjects: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) - { - var i; - var j; - - if (object1.isParent && object1.physicsType === undefined) - { - object1 = object1.children.entries; - } - - if (object2 && object2.isParent && object2.physicsType === undefined) - { - object2 = object2.children.entries; - } - - var object1isArray = Array.isArray(object1); - var object2isArray = Array.isArray(object2); - - this._total = 0; - - if (!object1isArray && !object2isArray) - { - // Neither of them are arrays - do this first as it's the most common use-case - this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (!object1isArray && object2isArray) - { - // Object 2 is an Array - for (i = 0; i < object2.length; i++) - { - this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - else if (object1isArray && !object2isArray) - { - // Object 1 is an Array - if (!object2) - { - // Special case for array vs. self - for (i = 0; i < object1.length; i++) - { - var child = object1[i]; - - for (j = i + 1; j < object1.length; j++) - { - if (i === j) - { - continue; - } - - this.collideHandler(child, object1[j], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - else - { - for (i = 0; i < object1.length; i++) - { - this.collideHandler(object1[i], object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - else - { - // They're both arrays - for (i = 0; i < object1.length; i++) - { - for (j = 0; j < object2.length; j++) - { - this.collideHandler(object1[i], object2[j], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - - return (this._total > 0); - }, - - /** - * Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead. - * - * @method Phaser.Physics.Arcade.World#collideHandler - * @private - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} callbackContext - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) - { - // Collide Group with Self - // Only collide valid objects - if (object2 === undefined && object1.isParent) - { - return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - - // If neither of the objects are set then bail out - if (!object1 || !object2) - { - return false; - } - - // A Body - if (object1.body) - { - if (object2.body) - { - return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isTilemap) - { - return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - - // GROUPS - else if (object1.isParent) - { - if (object2.body) - { - return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isTilemap) - { - return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - - // TILEMAP LAYERS - else if (object1.isTilemap) - { - if (object2.body) - { - return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - }, - - /** - * Internal handler for Sprite vs. Sprite collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsSprite - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite1 - The first object to check for collision. - * @param {Phaser.GameObjects.GameObject} sprite2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) - { - if (!sprite1.body || !sprite2.body) - { - return false; - } - - if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } - - this._total++; - } - - return true; - }, - - /** - * Internal handler for Sprite vs. Group collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsGroup - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.GameObjects.Group} group - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. - */ - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) - { - var bodyA = sprite.body; - - if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) - { - return; - } - - // Does sprite collide with anything? - - var i; - var len; - var bodyB; - - if (this.useTree || group.physicsType === CONST.STATIC_BODY) - { - var minMax = this.treeMinMax; - - minMax.minX = bodyA.left; - minMax.minY = bodyA.top; - minMax.maxX = bodyA.right; - minMax.maxY = bodyA.bottom; - - var results = (group.physicsType === CONST.DYNAMIC_BODY) ? this.tree.search(minMax) : this.staticTree.search(minMax); - - len = results.length; - - for (i = 0; i < len; i++) - { - bodyB = results[i]; - - if (bodyA === bodyB || !bodyB.enable || bodyB.checkCollision.none || !group.contains(bodyB.gameObject)) - { - // Skip if comparing against itself, or if bodyB isn't collidable, or if bodyB isn't actually part of the Group - continue; - } - - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } - - this._total++; - } - } - } - else - { - var children = group.getChildren(); - var skipIndex = group.children.entries.indexOf(sprite); - - len = children.length; - - for (i = 0; i < len; i++) - { - bodyB = children[i].body; - - if (!bodyB || i === skipIndex || !bodyB.enable) - { - continue; - } - - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } - - this._total++; - } - } - } - }, - - /** - * Internal handler for Group vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Group} group - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} callbackContext - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) - { - var children = group.getChildren(); - - if (children.length === 0) - { - return false; - } - - var didCollide = false; - - for (var i = 0; i < children.length; i++) - { - if (children[i].body) - { - if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) - { - didCollide = true; - } - } - } - - return didCollide; - }, - - /** - * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. - * - * You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform - * tile filtering and culling for you, as well as handle the interesting face collision automatically. - * - * This method is offered for those who would like to check for collision with specific Tiles in a layer, without - * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions - * on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, - * you should filter them before passing them to this method. - * - * Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have - * say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the - * tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on - * dynamic maps, this method can prove very useful. - * - * @method Phaser.Physics.Arcade.World#collideTiles - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) - { - if (!sprite.body.enable || tiles.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); - } - }, - - /** - * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. - * - * You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform - * tile filtering and culling for you, as well as handle the interesting face collision automatically. - * - * This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without - * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap - * tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, - * you should filter them before passing them to this method. - * - * @method Phaser.Physics.Arcade.World#overlapTiles - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - overlapTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) - { - if (!sprite.body.enable || tiles.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); - } - }, - - /** - * Internal handler for Sprite vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsTilemapLayer - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) - { - var body = sprite.body; - - if (!body.enable || body.checkCollision.none) - { - return false; - } - - var x = body.position.x; - var y = body.position.y; - var w = body.width; - var h = body.height; - - var layerData = tilemapLayer.layer; - - if (layerData.tileWidth > layerData.baseTileWidth) - { - // The x origin of a tile is the left side, so x and width need to be adjusted. - var xDiff = (layerData.tileWidth - layerData.baseTileWidth) * tilemapLayer.scaleX; - x -= xDiff; - w += xDiff; - } - - if (layerData.tileHeight > layerData.baseTileHeight) - { - // The y origin of a tile is the bottom side, so just the height needs to be adjusted. - var yDiff = (layerData.tileHeight - layerData.baseTileHeight) * tilemapLayer.scaleY; - h += yDiff; - } - - var mapData = GetTilesWithinWorldXY(x, y, w, h, null, tilemapLayer.scene.cameras.main, tilemapLayer.layer); - - if (mapData.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); - } - }, - - /** - * Internal handler for Sprite vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @private - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. - * @param {boolean} [isLayer] - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) - { - var body = sprite.body; - - var tile; - var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 }; - var tilemapLayer; - var collision = false; - - for (var i = 0; i < tiles.length; i++) - { - tile = tiles[i]; - - tilemapLayer = tile.tilemapLayer; - - var point = tilemapLayer.tileToWorldXY(tile.x, tile.y); - - tileWorldRect.left = point.x; - tileWorldRect.top = point.y; - - // If the maps base tile size differs from the layer tile size, only the top of the rect - // needs to be adjusted since its origin is (0, 1). - if (tile.baseHeight !== tile.height) - { - tileWorldRect.top -= (tile.height - tile.baseHeight) * tilemapLayer.scaleY; - } - - tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; - tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; - - if (TileIntersectsBody(tileWorldRect, body) - && (!processCallback || processCallback.call(callbackContext, sprite, tile)) - && ProcessTileCallbacks(tile, sprite) - && (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS, isLayer))) - { - this._total++; - - collision = true; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, tile); - } - - if (overlapOnly && body.onOverlap) - { - this.emit(Events.TILE_OVERLAP, sprite, tile, body); - } - else if (body.onCollide) - { - this.emit(Events.TILE_COLLIDE, sprite, tile, body); - } - } - } - - return collision; - }, - - /** - * Internal helper for Group vs. Group collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideGroupVsGroup - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Group} group1 - The first object to check for collision. - * @param {Phaser.GameObjects.Group} group2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) - { - if (group1.length === 0 || group2.length === 0) - { - return; - } - - var children = group1.getChildren(); - - for (var i = 0; i < children.length; i++) - { - this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); - } - }, - - /** - * Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}. - * - * If the object is outside any boundary edge (left, top, right, bottom), it will be moved to the same offset from the opposite edge (the interior). - * - * @method Phaser.Physics.Arcade.World#wrap - * @since 3.3.0 - * - * @param {any} object - A Game Object, a Group, an object with `x` and `y` coordinates, or an array of such objects. - * @param {number} [padding=0] - An amount added to each boundary edge during the operation. - */ - wrap: function (object, padding) - { - if (object.body) - { - this.wrapObject(object, padding); - } - else if (object.getChildren) - { - this.wrapArray(object.getChildren(), padding); - } - else if (Array.isArray(object)) - { - this.wrapArray(object, padding); - } - else - { - this.wrapObject(object, padding); - } - }, - - /** - * Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. - * - * @method Phaser.Physics.Arcade.World#wrapArray - * @since 3.3.0 - * - * @param {Array.<*>} objects - An array of objects to be wrapped. - * @param {number} [padding=0] - An amount added to the boundary. - */ - wrapArray: function (objects, padding) - { - for (var i = 0; i < objects.length; i++) - { - this.wrapObject(objects[i], padding); - } - }, - - /** - * Wrap an object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. - * - * @method Phaser.Physics.Arcade.World#wrapObject - * @since 3.3.0 - * - * @param {*} object - A Game Object, a Physics Body, or any object with `x` and `y` coordinates - * @param {number} [padding=0] - An amount added to the boundary. - */ - wrapObject: function (object, padding) - { - if (padding === undefined) { padding = 0; } - - object.x = Wrap(object.x, this.bounds.left - padding, this.bounds.right + padding); - object.y = Wrap(object.y, this.bounds.top - padding, this.bounds.bottom + padding); - }, - - /** - * Shuts down the simulation, clearing physics data and removing listeners. - * - * @method Phaser.Physics.Arcade.World#shutdown - * @since 3.0.0 - */ - shutdown: function () - { - this.tree.clear(); - this.staticTree.clear(); - this.bodies.clear(); - this.staticBodies.clear(); - this.colliders.destroy(); - - this.removeAllListeners(); - }, - - /** - * Shuts down the simulation and disconnects it from the current scene. - * - * @method Phaser.Physics.Arcade.World#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - - this.scene = null; - } - -}); - -module.exports = World; - - -/***/ }), -/* 505 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Benjamin D. Richards - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var Events = __webpack_require__(240); -var RadToDeg = __webpack_require__(192); -var Rectangle = __webpack_require__(10); -var RectangleContains = __webpack_require__(56); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A Dynamic Arcade Body. - * - * Its static counterpart is {@link Phaser.Physics.Arcade.StaticBody}. - * - * @class Body - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Body belongs to. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. - */ -var Body = new Class({ - - initialize: - - function Body (world, gameObject) - { - var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; - var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; - - /** - * The Arcade Physics simulation this Body belongs to. - * - * @name Phaser.Physics.Arcade.Body#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The Game Object this Body belongs to. - * - * @name Phaser.Physics.Arcade.Body#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.gameObject = gameObject; - - /** - * Transformations applied to this Body. - * - * @name Phaser.Physics.Arcade.Body#transform - * @type {object} - * @since 3.4.0 - */ - this.transform = { - x: gameObject.x, - y: gameObject.y, - rotation: gameObject.angle, - scaleX: gameObject.scaleX, - scaleY: gameObject.scaleY, - displayOriginX: gameObject.displayOriginX, - displayOriginY: gameObject.displayOriginY - }; - - /** - * Whether the Body is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugShowBody - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowBody = world.defaults.debugShowBody; - - /** - * Whether the Body's velocity is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugShowVelocity - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowVelocity = world.defaults.debugShowVelocity; - - /** - * The color of this Body on the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugBodyColor - * @type {number} - * @since 3.0.0 - */ - this.debugBodyColor = world.defaults.bodyDebugColor; - - /** - * Whether this Body is updated by the physics simulation. - * - * @name Phaser.Physics.Arcade.Body#enable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enable = true; - - /** - * Whether this Body is circular (true) or rectangular (false). - * - * @name Phaser.Physics.Arcade.Body#isCircle - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setCircle - */ - this.isCircle = false; - - /** - * If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels. - * The true radius is equal to `halfWidth`. - * - * @name Phaser.Physics.Arcade.Body#radius - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setCircle - */ - this.radius = 0; - - /** - * The offset of this Body's position from its Game Object's position, in source pixels. - * - * @name Phaser.Physics.Arcade.Body#offset - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setOffset - */ - this.offset = new Vector2(); - - /** - * The position of this Body within the simulation. - * - * @name Phaser.Physics.Arcade.Body#position - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.position = new Vector2( - gameObject.x - gameObject.scaleX * gameObject.displayOriginX, - gameObject.y - gameObject.scaleY * gameObject.displayOriginY - ); - - /** - * The position of this Body during the previous step. - * - * @name Phaser.Physics.Arcade.Body#prev - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.prev = this.position.clone(); - - /** - * The position of this Body during the previous frame. - * - * @name Phaser.Physics.Arcade.Body#prevFrame - * @type {Phaser.Math.Vector2} - * @since 3.20.0 - */ - this.prevFrame = this.position.clone(); - - /** - * Whether this Body's `rotation` is affected by its angular acceleration and angular velocity. - * - * @name Phaser.Physics.Arcade.Body#allowRotation - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.allowRotation = true; - - /** - * This body's rotation, in degrees, based on its angular acceleration and angular velocity. - * The Body's rotation controls the `angle` of its Game Object. - * It doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle. - * - * @name Phaser.Physics.Arcade.Body#rotation - * @type {number} - * @since 3.0.0 - */ - this.rotation = gameObject.angle; - - /** - * The Body rotation, in degrees, during the previous step. - * - * @name Phaser.Physics.Arcade.Body#preRotation - * @type {number} - * @since 3.0.0 - */ - this.preRotation = gameObject.angle; - - /** - * The width of the Body, in pixels. - * If the Body is circular, this is also the diameter. - * If you wish to change the width use the `Body.setSize` method. - * - * @name Phaser.Physics.Arcade.Body#width - * @type {number} - * @readonly - * @default 64 - * @since 3.0.0 - */ - this.width = width; - - /** - * The height of the Body, in pixels. - * If the Body is circular, this is also the diameter. - * If you wish to change the height use the `Body.setSize` method. - * - * @name Phaser.Physics.Arcade.Body#height - * @type {number} - * @readonly - * @default 64 - * @since 3.0.0 - */ - this.height = height; - - /** - * The unscaled width of the Body, in source pixels, as set by setSize(). - * The default is the width of the Body's Game Object's texture frame. - * - * @name Phaser.Physics.Arcade.Body#sourceWidth - * @type {number} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setSize - */ - this.sourceWidth = width; - - /** - * The unscaled height of the Body, in source pixels, as set by setSize(). - * The default is the height of the Body's Game Object's texture frame. - * - * @name Phaser.Physics.Arcade.Body#sourceHeight - * @type {number} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setSize - */ - this.sourceHeight = height; - - if (gameObject.frame) - { - this.sourceWidth = gameObject.frame.realWidth; - this.sourceHeight = gameObject.frame.realHeight; - } - - /** - * Half the Body's width, in pixels. - * - * @name Phaser.Physics.Arcade.Body#halfWidth - * @type {number} - * @since 3.0.0 - */ - this.halfWidth = Math.abs(width / 2); - - /** - * Half the Body's height, in pixels. - * - * @name Phaser.Physics.Arcade.Body#halfHeight - * @type {number} - * @since 3.0.0 - */ - this.halfHeight = Math.abs(height / 2); - - /** - * The center of the Body. - * The midpoint of its `position` (top-left corner) and its bottom-right corner. - * - * @name Phaser.Physics.Arcade.Body#center - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - /** - * The Body's velocity, in pixels per second. - * - * @name Phaser.Physics.Arcade.Body#velocity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.velocity = new Vector2(); - - /** - * The Body's change in position (due to velocity) at the last step, in pixels. - * - * The size of this value depends on the simulation's step rate. - * - * @name Phaser.Physics.Arcade.Body#newVelocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.newVelocity = new Vector2(); - - /** - * The Body's absolute maximum change in position, in pixels per step. - * - * @name Phaser.Physics.Arcade.Body#deltaMax - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.deltaMax = new Vector2(); - - /** - * The Body's change in velocity, in pixels per second squared. - * - * @name Phaser.Physics.Arcade.Body#acceleration - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.acceleration = new Vector2(); - - /** - * Whether this Body's velocity is affected by its `drag`. - * - * @name Phaser.Physics.Arcade.Body#allowDrag - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.allowDrag = true; - - /** - * When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared. - * - * When `useDamping` is true, this is a damping multiplier between 0 and 1. - * A value of 0 means the Body stops instantly. - * A value of 0.01 mean the Body loses 99% of its velocity per second. - * A value of 0.1 means the Body loses 90% of its velocity per second. - * A value of 1 means the Body loses no velocity. - * - * The x and y components are applied separately. - * - * Drag is applied only when `acceleration` is zero. - * - * @name Phaser.Physics.Arcade.Body#drag - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.drag = new Vector2(); - - /** - * Whether this Body's position is affected by gravity (local or world). - * - * @name Phaser.Physics.Arcade.Body#allowGravity - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#gravity - * @see Phaser.Physics.Arcade.World#gravity - */ - this.allowGravity = true; - - /** - * Acceleration due to gravity (specific to this Body), in pixels per second squared. - * Total gravity is the sum of this vector and the simulation's `gravity`. - * - * @name Phaser.Physics.Arcade.Body#gravity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#gravity - */ - this.gravity = new Vector2(); - - /** - * Rebound following a collision, relative to 1. - * - * @name Phaser.Physics.Arcade.Body#bounce - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.bounce = new Vector2(); - - /** - * Rebound following a collision with the world boundary, relative to 1. - * If null, `bounce` is used instead. - * - * @name Phaser.Physics.Arcade.Body#worldBounce - * @type {?Phaser.Math.Vector2} - * @default null - * @since 3.0.0 - */ - this.worldBounce = null; - - /** - * The rectangle used for world boundary collisions. - * - * By default it is set to the world boundary rectangle. Or, if this Body was - * created by a Physics Group, then whatever rectangle that Group defined. - * - * You can also change it by using the `Body.setBoundsRectangle` method. - * - * @name Phaser.Physics.Arcade.Body#customBoundsRectangle - * @type {Phaser.Geom.Rectangle} - * @since 3.20 - */ - this.customBoundsRectangle = world.bounds; - - // If true this Body will dispatch events - - /** - * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). - * - * @name Phaser.Physics.Arcade.Body#onWorldBounds - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#WORLD_BOUNDS - */ - this.onWorldBounds = false; - - /** - * Whether the simulation emits a `collide` event when this Body collides with another. - * - * @name Phaser.Physics.Arcade.Body#onCollide - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#COLLIDE - */ - this.onCollide = false; - - /** - * Whether the simulation emits an `overlap` event when this Body overlaps with another. - * - * @name Phaser.Physics.Arcade.Body#onOverlap - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#OVERLAP - */ - this.onOverlap = false; - - /** - * The Body's absolute maximum velocity, in pixels per second. - * The horizontal and vertical components are applied separately. - * - * @name Phaser.Physics.Arcade.Body#maxVelocity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.maxVelocity = new Vector2(10000, 10000); - - /** - * The maximum speed this Body is allowed to reach, in pixels per second. - * - * If not negative it limits the scalar value of speed. - * - * Any negative value means no maximum is being applied (the default). - * - * @name Phaser.Physics.Arcade.Body#maxSpeed - * @type {number} - * @default -1 - * @since 3.16.0 - */ - this.maxSpeed = -1; - - /** - * If this Body is `immovable` and in motion, `friction` is the proportion of this Body's motion received by the riding Body on each axis, relative to 1. - * The horizontal component (x) is applied only when two colliding Bodies are separated vertically. - * The vertical component (y) is applied only when two colliding Bodies are separated horizontally. - * The default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all. - * - * @name Phaser.Physics.Arcade.Body#friction - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.friction = new Vector2(1, 0); - - /** - * If this Body is using `drag` for deceleration this property controls how the drag is applied. - * If set to `true` drag will use a damping effect rather than a linear approach. If you are - * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in - * the game Asteroids) then you will get a far smoother and more visually correct deceleration - * by using damping, avoiding the axis-drift that is prone with linear deceleration. - * - * If you enable this property then you should use far smaller `drag` values than with linear, as - * they are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow - * deceleration. - * - * @name Phaser.Physics.Arcade.Body#useDamping - * @type {boolean} - * @default false - * @since 3.10.0 - */ - this.useDamping = false; - - /** - * The rate of change of this Body's `rotation`, in degrees per second. - * - * @name Phaser.Physics.Arcade.Body#angularVelocity - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularVelocity = 0; - - /** - * The Body's angular acceleration (change in angular velocity), in degrees per second squared. - * - * @name Phaser.Physics.Arcade.Body#angularAcceleration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularAcceleration = 0; - - /** - * Loss of angular velocity due to angular movement, in degrees per second. - * - * Angular drag is applied only when angular acceleration is zero. - * - * @name Phaser.Physics.Arcade.Body#angularDrag - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularDrag = 0; - - /** - * The Body's maximum angular velocity, in degrees per second. - * - * @name Phaser.Physics.Arcade.Body#maxAngular - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.maxAngular = 1000; - - /** - * The Body's inertia, relative to a default unit (1). - * With `bounce`, this affects the exchange of momentum (velocities) during collisions. - * - * @name Phaser.Physics.Arcade.Body#mass - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.mass = 1; - - /** - * The calculated angle of this Body's velocity vector, in radians, during the last step. - * - * @name Phaser.Physics.Arcade.Body#angle - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angle = 0; - - /** - * The calculated magnitude of the Body's velocity, in pixels per second, during the last step. - * - * @name Phaser.Physics.Arcade.Body#speed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.speed = 0; - - /** - * The direction of the Body's velocity, as calculated during the last step. - * This is a numeric constant value (FACING_UP, FACING_DOWN, FACING_LEFT, FACING_RIGHT). - * If the Body is moving on both axes, this describes motion on the vertical axis only. - * - * @name Phaser.Physics.Arcade.Body#facing - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.FACING_UP - * @see Phaser.Physics.Arcade.FACING_DOWN - * @see Phaser.Physics.Arcade.FACING_LEFT - * @see Phaser.Physics.Arcade.FACING_RIGHT - */ - this.facing = CONST.FACING_NONE; - - /** - * Whether this Body can be moved by collisions with another Body. - * - * @name Phaser.Physics.Arcade.Body#immovable - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.immovable = false; - - /** - * Sets if this Body can be pushed by another Body. - * - * A body that cannot be pushed will reflect back all of the velocity it is given to the - * colliding body. If that body is also not pushable, then the separation will be split - * between them evenly. - * - * If you want your body to never move or seperate at all, see the `setImmovable` method. - * - * By default, Dynamic Bodies are always pushable. - * - * @name Phaser.Physics.Arcade.Body#pushable - * @type {boolean} - * @default true - * @since 3.50.0 - * @see Phaser.GameObjects.Components.Pushable#setPushable - */ - this.pushable = true; - - /** - * Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity. - * - * @name Phaser.Physics.Arcade.Body#moves - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.moves = true; - - /** - * A flag disabling the default horizontal separation of colliding bodies. - * Pass your own `collideCallback` to the collider. - * - * @name Phaser.Physics.Arcade.Body#customSeparateX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateX = false; - - /** - * A flag disabling the default vertical separation of colliding bodies. - * Pass your own `collideCallback` to the collider. - * - * @name Phaser.Physics.Arcade.Body#customSeparateY - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateY = false; - - /** - * The amount of horizontal overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.Body#overlapX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapX = 0; - - /** - * The amount of vertical overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.Body#overlapY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapY = 0; - - /** - * The amount of overlap (before separation), if this Body is circular and colliding with another circular body. - * - * @name Phaser.Physics.Arcade.Body#overlapR - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapR = 0; - - /** - * Whether this Body is overlapped with another and both are not moving, on at least one axis. - * - * @name Phaser.Physics.Arcade.Body#embedded - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.embedded = false; - - /** - * Whether this Body interacts with the world boundary. - * - * @name Phaser.Physics.Arcade.Body#collideWorldBounds - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.collideWorldBounds = false; - - /** - * Whether this Body is checked for collisions and for which directions. - * You can set `checkCollision.none = true` to disable collision checks. - * - * @name Phaser.Physics.Arcade.Body#checkCollision - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; - - /** - * Whether this Body is colliding with a Body or Static Body and in which direction. - * In a collision where both bodies have zero velocity, `embedded` will be set instead. - * - * @name Phaser.Physics.Arcade.Body#touching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#blocked - * @see Phaser.Physics.Arcade.Body#embedded - */ - this.touching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This Body's `touching` value during the previous step. - * - * @name Phaser.Physics.Arcade.Body#wasTouching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#touching - */ - this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * Whether this Body is colliding with a Static Body, a tile, or the world boundary. - * In a collision with a Static Body, if this Body has zero velocity then `embedded` will be set instead. - * - * @name Phaser.Physics.Arcade.Body#blocked - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#embedded - * @see Phaser.Physics.Arcade.Body#touching - */ - this.blocked = { none: true, up: false, down: false, left: false, right: false }; - - /** - * Whether to automatically synchronize this Body's dimensions to the dimensions of its Game Object's visual bounds. - * - * @name Phaser.Physics.Arcade.Body#syncBounds - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.GameObjects.Components.GetBounds#getBounds - */ - this.syncBounds = false; - - /** - * The Body's physics type (dynamic or static). - * - * @name Phaser.Physics.Arcade.Body#physicsType - * @type {number} - * @readonly - * @default Phaser.Physics.Arcade.DYNAMIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.DYNAMIC_BODY; - - /** - * Cached horizontal scale of the Body's Game Object. - * - * @name Phaser.Physics.Arcade.Body#_sx - * @type {number} - * @private - * @since 3.0.0 - */ - this._sx = gameObject.scaleX; - - /** - * Cached vertical scale of the Body's Game Object. - * - * @name Phaser.Physics.Arcade.Body#_sy - * @type {number} - * @private - * @since 3.0.0 - */ - this._sy = gameObject.scaleY; - - /** - * The calculated change in the Body's horizontal position during the last step. - * - * @name Phaser.Physics.Arcade.Body#_dx - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._dx = 0; - - /** - * The calculated change in the Body's vertical position during the last step. - * - * @name Phaser.Physics.Arcade.Body#_dy - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._dy = 0; - - /** - * The final calculated change in the Body's horizontal position as of `postUpdate`. - * - * @name Phaser.Physics.Arcade.Body#_tx - * @type {number} - * @private - * @default 0 - * @since 3.22.0 - */ - this._tx = 0; - - /** - * The final calculated change in the Body's vertical position as of `postUpdate`. - * - * @name Phaser.Physics.Arcade.Body#_ty - * @type {number} - * @private - * @default 0 - * @since 3.22.0 - */ - this._ty = 0; - - /** - * Stores the Game Object's bounds. - * - * @name Phaser.Physics.Arcade.Body#_bounds - * @type {Phaser.Geom.Rectangle} - * @private - * @since 3.0.0 - */ - this._bounds = new Rectangle(); - }, - - /** - * Updates the Body's `transform`, `width`, `height`, and `center` from its Game Object. - * The Body's `position` isn't changed. - * - * @method Phaser.Physics.Arcade.Body#updateBounds - * @since 3.0.0 - */ - updateBounds: function () - { - var sprite = this.gameObject; - - // Container? - - var transform = this.transform; - - if (sprite.parentContainer) - { - var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2); - - transform.x = matrix.tx; - transform.y = matrix.ty; - transform.rotation = RadToDeg(matrix.rotation); - transform.scaleX = matrix.scaleX; - transform.scaleY = matrix.scaleY; - transform.displayOriginX = sprite.displayOriginX; - transform.displayOriginY = sprite.displayOriginY; - } - else - { - transform.x = sprite.x; - transform.y = sprite.y; - transform.rotation = sprite.angle; - transform.scaleX = sprite.scaleX; - transform.scaleY = sprite.scaleY; - transform.displayOriginX = sprite.displayOriginX; - transform.displayOriginY = sprite.displayOriginY; - } - - var recalc = false; - - if (this.syncBounds) - { - var b = sprite.getBounds(this._bounds); - - this.width = b.width; - this.height = b.height; - recalc = true; - } - else - { - var asx = Math.abs(transform.scaleX); - var asy = Math.abs(transform.scaleY); - - if (this._sx !== asx || this._sy !== asy) - { - this.width = this.sourceWidth * asx; - this.height = this.sourceHeight * asy; - this._sx = asx; - this._sy = asy; - recalc = true; - } - } - - if (recalc) - { - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - this.updateCenter(); - } - }, - - /** - * Updates the Body's `center` from its `position`, `width`, and `height`. - * - * @method Phaser.Physics.Arcade.Body#updateCenter - * @since 3.0.0 - */ - updateCenter: function () - { - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - }, - - /** - * Updates the Body's `position`, `width`, `height`, and `center` from its Game Object and `offset`. - * - * You don't need to call this for Dynamic Bodies, as it happens automatically during the physics step. - * But you could use it if you have modified the Body offset or Game Object transform and need to immediately - * read the Body's new `position` or `center`. - * - * To resynchronize the Body with its Game Object, use `reset()` instead. - * - * @method Phaser.Physics.Arcade.Body#updateFromGameObject - * @since 3.24.0 - */ - updateFromGameObject: function () - { - this.updateBounds(); - - var transform = this.transform; - - this.position.x = transform.x + transform.scaleX * (this.offset.x - transform.displayOriginX); - this.position.y = transform.y + transform.scaleY * (this.offset.y - transform.displayOriginY); - - this.updateCenter(); - }, - - /** - * Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states. - * - * This method is only called if the physics world is going to run a step this frame. - * - * @method Phaser.Physics.Arcade.Body#resetFlags - * @since 3.18.0 - * - * @param {boolean} [clear=false] - Set the `wasTouching` values to their defaults. - */ - resetFlags: function (clear) - { - if (clear === undefined) - { - clear = false; - } - - // Store and reset collision flags - var wasTouching = this.wasTouching; - var touching = this.touching; - var blocked = this.blocked; - - if (clear) - { - wasTouching.none = true; - wasTouching.up = false; - wasTouching.down = false; - wasTouching.left = false; - wasTouching.right = false; - } - else - { - wasTouching.none = touching.none; - wasTouching.up = touching.up; - wasTouching.down = touching.down; - wasTouching.left = touching.left; - wasTouching.right = touching.right; - } - - touching.none = true; - touching.up = false; - touching.down = false; - touching.left = false; - touching.right = false; - - blocked.none = true; - blocked.up = false; - blocked.down = false; - blocked.left = false; - blocked.right = false; - - this.overlapR = 0; - this.overlapX = 0; - this.overlapY = 0; - - this.embedded = false; - }, - - /** - * Syncs the position body position with the parent Game Object. - * - * This method is called every game frame, regardless if the world steps or not. - * - * @method Phaser.Physics.Arcade.Body#preUpdate - * @since 3.17.0 - * - * @param {boolean} willStep - Will this Body run an update as well? - * @param {number} delta - The delta time, in seconds, elapsed since the last frame. - */ - preUpdate: function (willStep, delta) - { - if (willStep) - { - this.resetFlags(); - } - - this.updateFromGameObject(); - - this.rotation = this.transform.rotation; - this.preRotation = this.rotation; - - if (this.moves) - { - this.prev.x = this.position.x; - this.prev.y = this.position.y; - this.prevFrame.x = this.position.x; - this.prevFrame.y = this.position.y; - } - - if (willStep) - { - this.update(delta); - } - }, - - /** - * Performs a single physics step and updates the body velocity, angle, speed and other properties. - * - * This method can be called multiple times per game frame, depending on the physics step rate. - * - * The results are synced back to the Game Object in `postUpdate`. - * - * @method Phaser.Physics.Arcade.Body#update - * @fires Phaser.Physics.Arcade.Events#WORLD_BOUNDS - * @since 3.0.0 - * - * @param {number} delta - The delta time, in seconds, elapsed since the last frame. - */ - update: function (delta) - { - this.prev.x = this.position.x; - this.prev.y = this.position.y; - - if (this.moves) - { - this.world.updateMotion(this, delta); - - var vx = this.velocity.x; - var vy = this.velocity.y; - - this.newVelocity.set(vx * delta, vy * delta); - - this.position.add(this.newVelocity); - - this.updateCenter(); - - this.angle = Math.atan2(vy, vx); - this.speed = Math.sqrt(vx * vx + vy * vy); - - // Now the update will throw collision checks at the Body - // And finally we'll integrate the new position back to the Sprite in postUpdate - - if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) - { - this.world.emit(Events.WORLD_BOUNDS, this, this.blocked.up, this.blocked.down, this.blocked.left, this.blocked.right); - } - } - - this._dx = this.position.x - this.prev.x; - this._dy = this.position.y - this.prev.y; - }, - - /** - * Feeds the Body results back into the parent Game Object. - * - * This method is called every game frame, regardless if the world steps or not. - * - * @method Phaser.Physics.Arcade.Body#postUpdate - * @since 3.0.0 - */ - postUpdate: function () - { - var dx = this.position.x - this.prevFrame.x; - var dy = this.position.y - this.prevFrame.y; - - if (this.moves) - { - var mx = this.deltaMax.x; - var my = this.deltaMax.y; - - if (mx !== 0 && dx !== 0) - { - if (dx < 0 && dx < -mx) - { - dx = -mx; - } - else if (dx > 0 && dx > mx) - { - dx = mx; - } - } - - if (my !== 0 && dy !== 0) - { - if (dy < 0 && dy < -my) - { - dy = -my; - } - else if (dy > 0 && dy > my) - { - dy = my; - } - } - - this.gameObject.x += dx; - this.gameObject.y += dy; - } - - if (dx < 0) - { - this.facing = CONST.FACING_LEFT; - } - else if (dx > 0) - { - this.facing = CONST.FACING_RIGHT; - } - - if (dy < 0) - { - this.facing = CONST.FACING_UP; - } - else if (dy > 0) - { - this.facing = CONST.FACING_DOWN; - } - - if (this.allowRotation) - { - this.gameObject.angle += this.deltaZ(); - } - - this._tx = dx; - this._ty = dy; - }, - - /** - * Sets a custom collision boundary rectangle. Use if you want to have a custom - * boundary instead of the world boundaries. - * - * @method Phaser.Physics.Arcade.Body#setBoundsRectangle - * @since 3.20 - * - * @param {?Phaser.Geom.Rectangle} [bounds] - The new boundary rectangle. Pass `null` to use the World bounds. - * - * @return {this} This Body object. - */ - setBoundsRectangle: function (bounds) - { - this.customBoundsRectangle = (!bounds) ? this.world.bounds : bounds; - - return this; - }, - - /** - * Checks for collisions between this Body and the world boundary and separates them. - * - * @method Phaser.Physics.Arcade.Body#checkWorldBounds - * @since 3.0.0 - * - * @return {boolean} True if this Body is colliding with the world boundary. - */ - checkWorldBounds: function () - { - var pos = this.position; - var bounds = this.customBoundsRectangle; - var check = this.world.checkCollision; - - var bx = (this.worldBounce) ? -this.worldBounce.x : -this.bounce.x; - var by = (this.worldBounce) ? -this.worldBounce.y : -this.bounce.y; - - var wasSet = false; - - if (pos.x < bounds.x && check.left) - { - pos.x = bounds.x; - this.velocity.x *= bx; - this.blocked.left = true; - wasSet = true; - } - else if (this.right > bounds.right && check.right) - { - pos.x = bounds.right - this.width; - this.velocity.x *= bx; - this.blocked.right = true; - wasSet = true; - } - - if (pos.y < bounds.y && check.up) - { - pos.y = bounds.y; - this.velocity.y *= by; - this.blocked.up = true; - wasSet = true; - } - else if (this.bottom > bounds.bottom && check.down) - { - pos.y = bounds.bottom - this.height; - this.velocity.y *= by; - this.blocked.down = true; - wasSet = true; - } - - if (wasSet) - { - this.blocked.none = false; - this.updateCenter(); - } - - return wasSet; - }, - - /** - * Sets the offset of the Body's position from its Game Object's position. - * The Body's `position` isn't changed until the next `preUpdate`. - * - * @method Phaser.Physics.Arcade.Body#setOffset - * @since 3.0.0 - * - * @param {number} x - The horizontal offset, in source pixels. - * @param {number} [y=x] - The vertical offset, in source pixels. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setOffset: function (x, y) - { - if (y === undefined) { y = x; } - - this.offset.set(x, y); - - return this; - }, - - /** - * Sizes and positions this Body, as a rectangle. - * Modifies the Body `offset` if `center` is true (the default). - * Resets the width and height to match current frame, if no width and height provided and a frame is found. - * - * @method Phaser.Physics.Arcade.Body#setSize - * @since 3.0.0 - * - * @param {number} [width] - The width of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. - * @param {number} [height] - The height of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. - * @param {boolean} [center=true] - Modify the Body's `offset`, placing the Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setSize: function (width, height, center) - { - if (center === undefined) { center = true; } - - var gameObject = this.gameObject; - - if (!width && gameObject.frame) - { - width = gameObject.frame.realWidth; - } - - if (!height && gameObject.frame) - { - height = gameObject.frame.realHeight; - } - - this.sourceWidth = width; - this.sourceHeight = height; - - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.updateCenter(); - - if (center && gameObject.getCenter) - { - var ox = (gameObject.width - width) / 2; - var oy = (gameObject.height - height) / 2; - - this.offset.set(ox, oy); - } - - this.isCircle = false; - this.radius = 0; - - return this; - }, - - /** - * Sizes and positions this Body, as a circle. - * - * @method Phaser.Physics.Arcade.Body#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the Body, in source pixels. - * @param {number} [offsetX] - The horizontal offset of the Body from its Game Object, in source pixels. - * @param {number} [offsetY] - The vertical offset of the Body from its Game Object, in source pixels. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setCircle: function (radius, offsetX, offsetY) - { - if (offsetX === undefined) { offsetX = this.offset.x; } - if (offsetY === undefined) { offsetY = this.offset.y; } - - if (radius > 0) - { - this.isCircle = true; - this.radius = radius; - - this.sourceWidth = radius * 2; - this.sourceHeight = radius * 2; - - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.offset.set(offsetX, offsetY); - - this.updateCenter(); - } - else - { - this.isCircle = false; - } - - return this; - }, - - /** - * Sets this Body's parent Game Object to the given coordinates and resets this Body at the new coordinates. - * If the Body had any velocity or acceleration it is lost as a result of calling this. - * - * @method Phaser.Physics.Arcade.Body#reset - * @since 3.0.0 - * - * @param {number} x - The horizontal position to place the Game Object. - * @param {number} y - The vertical position to place the Game Object. - */ - reset: function (x, y) - { - this.stop(); - - var gameObject = this.gameObject; - - gameObject.setPosition(x, y); - - if (gameObject.getTopLeft) - { - gameObject.getTopLeft(this.position); - } - else - { - this.position.set(x, y); - } - - this.prev.copy(this.position); - this.prevFrame.copy(this.position); - - this.rotation = gameObject.angle; - this.preRotation = gameObject.angle; - - this.updateBounds(); - this.updateCenter(); - this.resetFlags(true); - }, - - /** - * Sets acceleration, velocity, and speed to zero. - * - * @method Phaser.Physics.Arcade.Body#stop - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - stop: function () - { - this.velocity.set(0); - this.acceleration.set(0); - this.speed = 0; - this.angularVelocity = 0; - this.angularAcceleration = 0; - - return this; - }, - - /** - * Copies the coordinates of this Body's edges into an object. - * - * @method Phaser.Physics.Arcade.Body#getBounds - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into. - * - * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}. - */ - getBounds: function (obj) - { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; - - return obj; - }, - - /** - * Tests if the coordinates are within this Body. - * - * @method Phaser.Physics.Arcade.Body#hitTest - * @since 3.0.0 - * - * @param {number} x - The horizontal coordinate. - * @param {number} y - The vertical coordinate. - * - * @return {boolean} True if (x, y) is within this Body. - */ - hitTest: function (x, y) - { - if (!this.isCircle) - { - return RectangleContains(this, x, y); - } - - // Check if x/y are within the bounds first - if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) - { - var dx = (this.center.x - x) * (this.center.x - x); - var dy = (this.center.y - y) * (this.center.y - y); - - return (dx + dy) <= (this.radius * this.radius); - } - - return false; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving down. - * - * @method Phaser.Physics.Arcade.Body#onFloor - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onFloor: function () - { - return this.blocked.down; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving up. - * - * @method Phaser.Physics.Arcade.Body#onCeiling - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onCeiling: function () - { - return this.blocked.up; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving left or right. - * - * @method Phaser.Physics.Arcade.Body#onWall - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onWall: function () - { - return (this.blocked.left || this.blocked.right); - }, - - /** - * The absolute (non-negative) change in this Body's horizontal position from the previous step. - * - * @method Phaser.Physics.Arcade.Body#deltaAbsX - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaAbsX: function () - { - return (this._dx > 0) ? this._dx : -this._dx; - }, - - /** - * The absolute (non-negative) change in this Body's vertical position from the previous step. - * - * @method Phaser.Physics.Arcade.Body#deltaAbsY - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaAbsY: function () - { - return (this._dy > 0) ? this._dy : -this._dy; - }, - - /** - * The change in this Body's horizontal position from the previous step. - * This value is set during the Body's update phase. - * - * As a Body can update multiple times per step this may not hold the final - * delta value for the Body. In this case, please see the `deltaXFinal` method. - * - * @method Phaser.Physics.Arcade.Body#deltaX - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaX: function () - { - return this._dx; - }, - - /** - * The change in this Body's vertical position from the previous step. - * This value is set during the Body's update phase. - * - * As a Body can update multiple times per step this may not hold the final - * delta value for the Body. In this case, please see the `deltaYFinal` method. - * - * @method Phaser.Physics.Arcade.Body#deltaY - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaY: function () - { - return this._dy; - }, - - /** - * The change in this Body's horizontal position from the previous game update. - * - * This value is set during the `postUpdate` phase and takes into account the - * `deltaMax` and final position of the Body. - * - * Because this value is not calculated until `postUpdate`, you must listen for it - * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will - * not be calculated by that point. If you _do_ use these values in `update` they - * will represent the delta from the _previous_ game frame. - * - * @method Phaser.Physics.Arcade.Body#deltaXFinal - * @since 3.22.0 - * - * @return {number} The final delta x value. - */ - deltaXFinal: function () - { - return this._tx; - }, - - /** - * The change in this Body's vertical position from the previous game update. - * - * This value is set during the `postUpdate` phase and takes into account the - * `deltaMax` and final position of the Body. - * - * Because this value is not calculated until `postUpdate`, you must listen for it - * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will - * not be calculated by that point. If you _do_ use these values in `update` they - * will represent the delta from the _previous_ game frame. - * - * @method Phaser.Physics.Arcade.Body#deltaYFinal - * @since 3.22.0 - * - * @return {number} The final delta y value. - */ - deltaYFinal: function () - { - return this._ty; - }, - - /** - * The change in this Body's rotation from the previous step, in degrees. - * - * @method Phaser.Physics.Arcade.Body#deltaZ - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaZ: function () - { - return this.rotation - this.preRotation; - }, - - /** - * Disables this Body and marks it for deletion by the simulation. - * - * @method Phaser.Physics.Arcade.Body#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enable = false; - - if (this.world) - { - this.world.pendingDestroy.set(this); - } - }, - - /** - * Draws this Body and its velocity, if enabled. - * - * @method Phaser.Physics.Arcade.Body#drawDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to draw on. - */ - drawDebug: function (graphic) - { - var pos = this.position; - - var x = pos.x + this.halfWidth; - var y = pos.y + this.halfHeight; - - if (this.debugShowBody) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor); - - if (this.isCircle) - { - graphic.strokeCircle(x, y, this.width / 2); - } - else - { - // Only draw the sides where checkCollision is true, similar to debugger in layer - if (this.checkCollision.up) - { - graphic.lineBetween(pos.x, pos.y, pos.x + this.width, pos.y); - } - - if (this.checkCollision.right) - { - graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); - } - - if (this.checkCollision.down) - { - graphic.lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height); - } - - if (this.checkCollision.left) - { - graphic.lineBetween(pos.x, pos.y, pos.x, pos.y + this.height); - } - } - } - - if (this.debugShowVelocity) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.world.defaults.velocityDebugColor, 1); - graphic.lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2); - } - }, - - /** - * Whether this Body will be drawn to the debug display. - * - * @method Phaser.Physics.Arcade.Body#willDrawDebug - * @since 3.0.0 - * - * @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled. - */ - willDrawDebug: function () - { - return (this.debugShowBody || this.debugShowVelocity); - }, - - /** - * Sets whether this Body collides with the world boundary. - * - * Optionally also sets the World Bounce and `onWorldBounds` values. - * - * @method Phaser.Physics.Arcade.Body#setCollideWorldBounds - * @since 3.0.0 - * - * @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`. - * @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value. - * @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value. - * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setCollideWorldBounds: function (value, bounceX, bounceY, onWorldBounds) - { - if (value === undefined) { value = true; } - - this.collideWorldBounds = value; - - var setBounceX = (bounceX !== undefined); - var setBounceY = (bounceY !== undefined); - - if (setBounceX || setBounceY) - { - if (!this.worldBounce) - { - this.worldBounce = new Vector2(); - } - - if (setBounceX) - { - this.worldBounce.x = bounceX; - } - - if (setBounceY) - { - this.worldBounce.y = bounceY; - } - } - - if (onWorldBounds !== undefined) - { - this.onWorldBounds = onWorldBounds; - } - - return this; - }, - - /** - * Sets the Body's velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity, in pixels per second. - * @param {number} [y=x] - The vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocity: function (x, y) - { - this.velocity.set(x, y); - - x = this.velocity.x; - y = this.velocity.y; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's horizontal velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocityX - * @since 3.0.0 - * - * @param {number} value - The velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocityX: function (value) - { - this.velocity.x = value; - - var x = value; - var y = this.velocity.y; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's vertical velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocityY - * @since 3.0.0 - * - * @param {number} value - The velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocityY: function (value) - { - this.velocity.y = value; - - var x = this.velocity.x; - var y = value; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's maximum velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocity - * @since 3.10.0 - * - * @param {number} x - The horizontal velocity, in pixels per second. - * @param {number} [y=x] - The vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocity: function (x, y) - { - this.maxVelocity.set(x, y); - - return this; - }, - - /** - * Sets the Body's maximum horizontal velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocityX - * @since 3.50.0 - * - * @param {number} value - The maximum horizontal velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocityX: function (value) - { - this.maxVelocity.x = value; - - return this; - }, - - /** - * Sets the Body's maximum vertical velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocityY - * @since 3.50.0 - * - * @param {number} value - The maximum vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocityY: function (value) - { - this.maxVelocity.y = value; - - return this; - }, - - /** - * Sets the maximum speed the Body can move. - * - * @method Phaser.Physics.Arcade.Body#setMaxSpeed - * @since 3.16.0 - * - * @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxSpeed: function (value) - { - this.maxSpeed = value; - - return this; - }, - - /** - * Sets the Body's bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounce - * @since 3.0.0 - * - * @param {number} x - The horizontal bounce, relative to 1. - * @param {number} y - The vertical bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounce: function (x, y) - { - this.bounce.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounceX - * @since 3.0.0 - * - * @param {number} value - The bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounceX: function (value) - { - this.bounce.x = value; - - return this; - }, - - /** - * Sets the Body's vertical bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounceY - * @since 3.0.0 - * - * @param {number} value - The bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounceY: function (value) - { - this.bounce.y = value; - - return this; - }, - - /** - * Sets the Body's acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAcceleration - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAcceleration: function (x, y) - { - this.acceleration.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAccelerationX - * @since 3.0.0 - * - * @param {number} value - The acceleration, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAccelerationX: function (value) - { - this.acceleration.x = value; - - return this; - }, - - /** - * Sets the Body's vertical acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAccelerationY - * @since 3.0.0 - * - * @param {number} value - The acceleration, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAccelerationY: function (value) - { - this.acceleration.y = value; - - return this; - }, - - /** - * Enables or disables drag. - * - * @method Phaser.Physics.Arcade.Body#setAllowDrag - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowDrag - * - * @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowDrag: function (value) - { - if (value === undefined) { value = true; } - - this.allowDrag = value; - - return this; - }, - - /** - * Enables or disables gravity's effect on this Body. - * - * @method Phaser.Physics.Arcade.Body#setAllowGravity - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowGravity - * - * @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowGravity: function (value) - { - if (value === undefined) { value = true; } - - this.allowGravity = value; - - return this; - }, - - /** - * Enables or disables rotation. - * - * @method Phaser.Physics.Arcade.Body#setAllowRotation - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowRotation - * - * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowRotation: function (value) - { - if (value === undefined) { value = true; } - - this.allowRotation = value; - - return this; - }, - - /** - * Sets the Body's drag. - * - * @method Phaser.Physics.Arcade.Body#setDrag - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDrag: function (x, y) - { - this.drag.set(x, y); - - return this; - }, - - /** - * If this Body is using `drag` for deceleration this property controls how the drag is applied. - * If set to `true` drag will use a damping effect rather than a linear approach. If you are - * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in - * the game Asteroids) then you will get a far smoother and more visually correct deceleration - * by using damping, avoiding the axis-drift that is prone with linear deceleration. - * - * If you enable this property then you should use far smaller `drag` values than with linear, as - * they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow - * deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately. - * - * @method Phaser.Physics.Arcade.Body#setDamping - * @since 3.50.0 - * - * @param {boolean} value - `true` to use damping, or `false` to use drag. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDamping: function (value) - { - this.useDamping = value; - - return this; - }, - - /** - * Sets the Body's horizontal drag. - * - * @method Phaser.Physics.Arcade.Body#setDragX - * @since 3.0.0 - * - * @param {number} value - The drag, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDragX: function (value) - { - this.drag.x = value; - - return this; - }, - - /** - * Sets the Body's vertical drag. - * - * @method Phaser.Physics.Arcade.Body#setDragY - * @since 3.0.0 - * - * @param {number} value - The drag, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDragY: function (value) - { - this.drag.y = value; - - return this; - }, - - /** - * Sets the Body's gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravity - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravity: function (x, y) - { - this.gravity.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravityX - * @since 3.0.0 - * - * @param {number} value - The gravity, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravityX: function (value) - { - this.gravity.x = value; - - return this; - }, - - /** - * Sets the Body's vertical gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravityY - * @since 3.0.0 - * - * @param {number} value - The gravity, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravityY: function (value) - { - this.gravity.y = value; - - return this; - }, - - /** - * Sets the Body's friction. - * - * @method Phaser.Physics.Arcade.Body#setFriction - * @since 3.0.0 - * - * @param {number} x - The horizontal component, relative to 1. - * @param {number} y - The vertical component, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFriction: function (x, y) - { - this.friction.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal friction. - * - * @method Phaser.Physics.Arcade.Body#setFrictionX - * @since 3.0.0 - * - * @param {number} value - The friction value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFrictionX: function (value) - { - this.friction.x = value; - - return this; - }, - - /** - * Sets the Body's vertical friction. - * - * @method Phaser.Physics.Arcade.Body#setFrictionY - * @since 3.0.0 - * - * @param {number} value - The friction value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFrictionY: function (value) - { - this.friction.y = value; - - return this; - }, - - /** - * Sets the Body's angular velocity. - * - * @method Phaser.Physics.Arcade.Body#setAngularVelocity - * @since 3.0.0 - * - * @param {number} value - The velocity, in degrees per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularVelocity: function (value) - { - this.angularVelocity = value; - - return this; - }, - - /** - * Sets the Body's angular acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAngularAcceleration - * @since 3.0.0 - * - * @param {number} value - The acceleration, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularAcceleration: function (value) - { - this.angularAcceleration = value; - - return this; - }, - - /** - * Sets the Body's angular drag. - * - * @method Phaser.Physics.Arcade.Body#setAngularDrag - * @since 3.0.0 - * - * @param {number} value - The drag, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularDrag: function (value) - { - this.angularDrag = value; - - return this; - }, - - /** - * Sets the Body's mass. - * - * @method Phaser.Physics.Arcade.Body#setMass - * @since 3.0.0 - * - * @param {number} value - The mass value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMass: function (value) - { - this.mass = value; - - return this; - }, - - /** - * Sets the Body's `immovable` property. - * - * @method Phaser.Physics.Arcade.Body#setImmovable - * @since 3.0.0 - * - * @param {boolean} [value=true] - The value to assign to `immovable`. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setImmovable: function (value) - { - if (value === undefined) { value = true; } - - this.immovable = value; - - return this; - }, - - /** - * Sets the Body's `enable` property. - * - * @method Phaser.Physics.Arcade.Body#setEnable - * @since 3.15.0 - * - * @param {boolean} [value=true] - The value to assign to `enable`. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setEnable: function (value) - { - if (value === undefined) { value = true; } - - this.enable = value; - - return this; - }, - - /** - * This is an internal handler, called by the `ProcessX` function as part - * of the collision step. You should almost never call this directly. - * - * @method Phaser.Physics.Arcade.Body#processX - * @since 3.50.0 - * - * @param {number} x - The amount to add to the Body position. - * @param {number} [vx] - The amount to add to the Body velocity. - * @param {boolean} [left] - Set the blocked.left value? - * @param {boolean} [right] - Set the blocked.right value? - */ - processX: function (x, vx, left, right) - { - this.x += x; - - this.updateCenter(); - - if (vx !== null) - { - this.velocity.x = vx; - } - - var blocked = this.blocked; - - if (left) - { - blocked.left = true; - } - - if (right) - { - blocked.right = true; - } - }, - - /** - * This is an internal handler, called by the `ProcessY` function as part - * of the collision step. You should almost never call this directly. - * - * @method Phaser.Physics.Arcade.Body#processY - * @since 3.50.0 - * - * @param {number} y - The amount to add to the Body position. - * @param {number} [vy] - The amount to add to the Body velocity. - * @param {boolean} [up] - Set the blocked.up value? - * @param {boolean} [down] - Set the blocked.down value? - */ - processY: function (y, vy, up, down) - { - this.y += y; - - this.updateCenter(); - - if (vy !== null) - { - this.velocity.y = vy; - } - - var blocked = this.blocked; - - if (up) - { - blocked.up = true; - } - - if (down) - { - blocked.down = true; - } - }, - - /** - * The Bodys horizontal position (left edge). - * - * @name Phaser.Physics.Arcade.Body#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.position.x = value; - } - - }, - - /** - * The Bodys vertical position (top edge). - * - * @name Phaser.Physics.Arcade.Body#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.position.y = value; - } - - }, - - /** - * The left edge of the Body. Identical to x. - * - * @name Phaser.Physics.Arcade.Body#left - * @type {number} - * @readonly - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.position.x; - } - - }, - - /** - * The right edge of the Body. - * - * @name Phaser.Physics.Arcade.Body#right - * @type {number} - * @readonly - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.position.x + this.width; - } - - }, - - /** - * The top edge of the Body. Identical to y. - * - * @name Phaser.Physics.Arcade.Body#top - * @type {number} - * @readonly - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.position.y; - } - - }, - - /** - * The bottom edge of this Body. - * - * @name Phaser.Physics.Arcade.Body#bottom - * @type {number} - * @readonly - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.position.y + this.height; - } - - } - -}); - -module.exports = Body; - - -/***/ }), -/* 506 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects - * every step. If a collision, or overlap, occurs it will invoke the given callbacks. - * - * @class Collider - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade physics World that will manage the collisions. - * @param {boolean} overlapOnly - Whether to check for collisions or overlap. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - */ -var Collider = new Class({ - - initialize: - - function Collider (world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) - { - /** - * The world in which the bodies will collide. - * - * @name Phaser.Physics.Arcade.Collider#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The name of the collider (unused by Phaser). - * - * @name Phaser.Physics.Arcade.Collider#name - * @type {string} - * @since 3.1.0 - */ - this.name = ''; - - /** - * Whether the collider is active. - * - * @name Phaser.Physics.Arcade.Collider#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Whether to check for collisions or overlaps. - * - * @name Phaser.Physics.Arcade.Collider#overlapOnly - * @type {boolean} - * @since 3.0.0 - */ - this.overlapOnly = overlapOnly; - - /** - * The first object to check for collision. - * - * @name Phaser.Physics.Arcade.Collider#object1 - * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} - * @since 3.0.0 - */ - this.object1 = object1; - - /** - * The second object to check for collision. - * - * @name Phaser.Physics.Arcade.Collider#object2 - * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} - * @since 3.0.0 - */ - this.object2 = object2; - - /** - * The callback to invoke when the two objects collide. - * - * @name Phaser.Physics.Arcade.Collider#collideCallback - * @type {ArcadePhysicsCallback} - * @since 3.0.0 - */ - this.collideCallback = collideCallback; - - /** - * If a processCallback exists it must return true or collision checking will be skipped. - * - * @name Phaser.Physics.Arcade.Collider#processCallback - * @type {ArcadePhysicsCallback} - * @since 3.0.0 - */ - this.processCallback = processCallback; - - /** - * The context the collideCallback and processCallback will run in. - * - * @name Phaser.Physics.Arcade.Collider#callbackContext - * @type {object} - * @since 3.0.0 - */ - this.callbackContext = callbackContext; - }, - - /** - * A name for the Collider. - * - * Phaser does not use this value, it's for your own reference. - * - * @method Phaser.Physics.Arcade.Collider#setName - * @since 3.1.0 - * - * @param {string} name - The name to assign to the Collider. - * - * @return {Phaser.Physics.Arcade.Collider} This Collider instance. - */ - setName: function (name) - { - this.name = name; - - return this; - }, - - /** - * Called by World as part of its step processing, initial operation of collision checking. - * - * @method Phaser.Physics.Arcade.Collider#update - * @since 3.0.0 - */ - update: function () - { - this.world.collideObjects( - this.object1, - this.object2, - this.collideCallback, - this.processCallback, - this.callbackContext, - this.overlapOnly - ); - }, - - /** - * Removes Collider from World and disposes of its resources. - * - * @method Phaser.Physics.Arcade.Collider#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.world.removeCollider(this); - - this.active = false; - - this.world = null; - - this.object1 = null; - this.object2 = null; - - this.collideCallback = null; - this.processCallback = null; - this.callbackContext = null; - } - -}); - -module.exports = Collider; - - -/***/ }), -/* 507 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTilesWithin = __webpack_require__(26); -var Vector2 = __webpack_require__(3); - -var pointStart = new Vector2(); -var pointEnd = new Vector2(); - -/** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * @function Phaser.Tilemaps.Components.GetTilesWithinWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} filteringOptions - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when factoring in which tiles to return. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. - */ -var GetTilesWithinWorldXY = function (worldX, worldY, width, height, filteringOptions, camera, layer) -{ - var worldToTileXY = layer.tilemapLayer.tilemap._convert.WorldToTileXY; - - // Top left corner of the rect, rounded down to include partial tiles - worldToTileXY(worldX, worldY, true, pointStart, camera, layer); - - var xStart = pointStart.x; - var yStart = pointStart.y; - - // Bottom right corner of the rect, rounded up to include partial tiles - worldToTileXY(worldX + width, worldY + height, false, pointEnd, camera, layer); - - var xEnd = Math.ceil(pointEnd.x); - var yEnd = Math.ceil(pointEnd.y); - - return GetTilesWithin(xStart, yStart, xEnd - xStart, yEnd - yStart, filteringOptions, layer); -}; - -module.exports = GetTilesWithinWorldXY; - - -/***/ }), -/* 508 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * A function to process the collision callbacks between a single tile and an Arcade Physics enabled Game Object. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileCallbacks - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.Tile} tile - The Tile to process. - * @param {Phaser.GameObjects.Sprite} sprite - The Game Object to process with the Tile. - * - * @return {boolean} The result of the callback, `true` for further processing, or `false` to skip this pair. - */ -var ProcessTileCallbacks = function (tile, sprite) -{ - // Tile callbacks take priority over layer level callbacks - if (tile.collisionCallback) - { - return !tile.collisionCallback.call(tile.collisionCallbackContext, sprite, tile); - } - else if (tile.layer.callbacks[tile.index]) - { - return !tile.layer.callbacks[tile.index].callback.call( - tile.layer.callbacks[tile.index].callbackContext, sprite, tile - ); - } - - return true; -}; - -module.exports = ProcessTileCallbacks; - - -/***/ }), -/* 509 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Vladimir Agafonkin - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var quickselect = __webpack_require__(414); - -/** - * @classdesc - * RBush is a high-performance JavaScript library for 2D spatial indexing of points and rectangles. - * It's based on an optimized R-tree data structure with bulk insertion support. - * - * Spatial index is a special data structure for points and rectangles that allows you to perform queries like - * "all items within this bounding box" very efficiently (e.g. hundreds of times faster than looping over all items). - * - * This version of RBush uses a fixed min/max accessor structure of `[ '.left', '.top', '.right', '.bottom' ]`. - * This is to avoid the eval like function creation that the original library used, which caused CSP policy violations. - * - * rbush is forked from https://github.com/mourner/rbush by Vladimir Agafonkin - * - * @class RTree - * @memberof Phaser.Structs - * @constructor - * @since 3.0.0 - */ - -function rbush (maxEntries) -{ - var format = [ '.left', '.top', '.right', '.bottom' ]; - - if (!(this instanceof rbush)) return new rbush(maxEntries, format); - - // max entries in a node is 9 by default; min node fill is 40% for best performance - this._maxEntries = Math.max(4, maxEntries || 9); - this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); - - this.clear(); -} - -rbush.prototype = { - - all: function () - { - return this._all(this.data, []); - }, - - search: function (bbox) - { - var node = this.data, - result = [], - toBBox = this.toBBox; - - if (!intersects(bbox, node)) return result; - - var nodesToSearch = [], - i, len, child, childBBox; - - while (node) { - for (i = 0, len = node.children.length; i < len; i++) { - - child = node.children[i]; - childBBox = node.leaf ? toBBox(child) : child; - - if (intersects(bbox, childBBox)) { - if (node.leaf) result.push(child); - else if (contains(bbox, childBBox)) this._all(child, result); - else nodesToSearch.push(child); - } - } - node = nodesToSearch.pop(); - } - - return result; - }, - - collides: function (bbox) - { - var node = this.data, - toBBox = this.toBBox; - - if (!intersects(bbox, node)) return false; - - var nodesToSearch = [], - i, len, child, childBBox; - - while (node) { - for (i = 0, len = node.children.length; i < len; i++) { - - child = node.children[i]; - childBBox = node.leaf ? toBBox(child) : child; - - if (intersects(bbox, childBBox)) { - if (node.leaf || contains(bbox, childBBox)) return true; - nodesToSearch.push(child); - } - } - node = nodesToSearch.pop(); - } - - return false; - }, - - load: function (data) - { - if (!(data && data.length)) return this; - - if (data.length < this._minEntries) { - for (var i = 0, len = data.length; i < len; i++) { - this.insert(data[i]); - } - return this; - } - - // recursively build the tree with the given data from scratch using OMT algorithm - var node = this._build(data.slice(), 0, data.length - 1, 0); - - if (!this.data.children.length) { - // save as is if tree is empty - this.data = node; - - } else if (this.data.height === node.height) { - // split root if trees have the same height - this._splitRoot(this.data, node); - - } else { - if (this.data.height < node.height) { - // swap trees if inserted one is bigger - var tmpNode = this.data; - this.data = node; - node = tmpNode; - } - - // insert the small tree into the large tree at appropriate level - this._insert(node, this.data.height - node.height - 1, true); - } - - return this; - }, - - insert: function (item) - { - if (item) this._insert(item, this.data.height - 1); - return this; - }, - - clear: function () - { - this.data = createNode([]); - return this; - }, - - remove: function (item, equalsFn) - { - if (!item) return this; - - var node = this.data, - bbox = this.toBBox(item), - path = [], - indexes = [], - i, parent, index, goingUp; - - // depth-first iterative tree traversal - while (node || path.length) { - - if (!node) { // go up - node = path.pop(); - parent = path[path.length - 1]; - i = indexes.pop(); - goingUp = true; - } - - if (node.leaf) { // check current node - index = findItem(item, node.children, equalsFn); - - if (index !== -1) { - // item found, remove the item and condense tree upwards - node.children.splice(index, 1); - path.push(node); - this._condense(path); - return this; - } - } - - if (!goingUp && !node.leaf && contains(node, bbox)) { // go down - path.push(node); - indexes.push(i); - i = 0; - parent = node; - node = node.children[0]; - - } else if (parent) { // go right - i++; - node = parent.children[i]; - goingUp = false; - - } else node = null; // nothing found - } - - return this; - }, - - toBBox: function (item) { return item; }, - - compareMinX: compareNodeMinX, - compareMinY: compareNodeMinY, - - toJSON: function () { return this.data; }, - - fromJSON: function (data) - { - this.data = data; - return this; - }, - - _all: function (node, result) - { - var nodesToSearch = []; - while (node) { - if (node.leaf) result.push.apply(result, node.children); - else nodesToSearch.push.apply(nodesToSearch, node.children); - - node = nodesToSearch.pop(); - } - return result; - }, - - _build: function (items, left, right, height) - { - var N = right - left + 1, - M = this._maxEntries, - node; - - if (N <= M) { - // reached leaf level; return leaf - node = createNode(items.slice(left, right + 1)); - calcBBox(node, this.toBBox); - return node; - } - - if (!height) { - // target height of the bulk-loaded tree - height = Math.ceil(Math.log(N) / Math.log(M)); - - // target number of root entries to maximize storage utilization - M = Math.ceil(N / Math.pow(M, height - 1)); - } - - node = createNode([]); - node.leaf = false; - node.height = height; - - // split the items into M mostly square tiles - - var N2 = Math.ceil(N / M), - N1 = N2 * Math.ceil(Math.sqrt(M)), - i, j, right2, right3; - - multiSelect(items, left, right, N1, this.compareMinX); - - for (i = left; i <= right; i += N1) { - - right2 = Math.min(i + N1 - 1, right); - - multiSelect(items, i, right2, N2, this.compareMinY); - - for (j = i; j <= right2; j += N2) { - - right3 = Math.min(j + N2 - 1, right2); - - // pack each entry recursively - node.children.push(this._build(items, j, right3, height - 1)); - } - } - - calcBBox(node, this.toBBox); - - return node; - }, - - _chooseSubtree: function (bbox, node, level, path) - { - var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; - - while (true) { - path.push(node); - - if (node.leaf || path.length - 1 === level) break; - - minArea = minEnlargement = Infinity; - - for (i = 0, len = node.children.length; i < len; i++) { - child = node.children[i]; - area = bboxArea(child); - enlargement = enlargedArea(bbox, child) - area; - - // choose entry with the least area enlargement - if (enlargement < minEnlargement) { - minEnlargement = enlargement; - minArea = area < minArea ? area : minArea; - targetNode = child; - - } else if (enlargement === minEnlargement) { - // otherwise choose one with the smallest area - if (area < minArea) { - minArea = area; - targetNode = child; - } - } - } - - node = targetNode || node.children[0]; - } - - return node; - }, - - _insert: function (item, level, isNode) - { - var toBBox = this.toBBox, - bbox = isNode ? item : toBBox(item), - insertPath = []; - - // find the best node for accommodating the item, saving all nodes along the path too - var node = this._chooseSubtree(bbox, this.data, level, insertPath); - - // put the item into the node - node.children.push(item); - extend(node, bbox); - - // split on node overflow; propagate upwards if necessary - while (level >= 0) { - if (insertPath[level].children.length > this._maxEntries) { - this._split(insertPath, level); - level--; - } else break; - } - - // adjust bboxes along the insertion path - this._adjustParentBBoxes(bbox, insertPath, level); - }, - - // split overflowed node into two - _split: function (insertPath, level) - { - var node = insertPath[level], - M = node.children.length, - m = this._minEntries; - - this._chooseSplitAxis(node, m, M); - - var splitIndex = this._chooseSplitIndex(node, m, M); - - var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); - newNode.height = node.height; - newNode.leaf = node.leaf; - - calcBBox(node, this.toBBox); - calcBBox(newNode, this.toBBox); - - if (level) insertPath[level - 1].children.push(newNode); - else this._splitRoot(node, newNode); - }, - - _splitRoot: function (node, newNode) - { - // split root node - this.data = createNode([node, newNode]); - this.data.height = node.height + 1; - this.data.leaf = false; - calcBBox(this.data, this.toBBox); - }, - - _chooseSplitIndex: function (node, m, M) - { - var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; - - minOverlap = minArea = Infinity; - - for (i = m; i <= M - m; i++) { - bbox1 = distBBox(node, 0, i, this.toBBox); - bbox2 = distBBox(node, i, M, this.toBBox); - - overlap = intersectionArea(bbox1, bbox2); - area = bboxArea(bbox1) + bboxArea(bbox2); - - // choose distribution with minimum overlap - if (overlap < minOverlap) { - minOverlap = overlap; - index = i; - - minArea = area < minArea ? area : minArea; - - } else if (overlap === minOverlap) { - // otherwise choose distribution with minimum area - if (area < minArea) { - minArea = area; - index = i; - } - } - } - - return index; - }, - - // sorts node children by the best axis for split - _chooseSplitAxis: function (node, m, M) - { - var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, - compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, - xMargin = this._allDistMargin(node, m, M, compareMinX), - yMargin = this._allDistMargin(node, m, M, compareMinY); - - // if total distributions margin value is minimal for x, sort by minX, - // otherwise it's already sorted by minY - if (xMargin < yMargin) node.children.sort(compareMinX); - }, - - // total margin of all possible split distributions where each node is at least m full - _allDistMargin: function (node, m, M, compare) - { - node.children.sort(compare); - - var toBBox = this.toBBox, - leftBBox = distBBox(node, 0, m, toBBox), - rightBBox = distBBox(node, M - m, M, toBBox), - margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), - i, child; - - for (i = m; i < M - m; i++) { - child = node.children[i]; - extend(leftBBox, node.leaf ? toBBox(child) : child); - margin += bboxMargin(leftBBox); - } - - for (i = M - m - 1; i >= m; i--) { - child = node.children[i]; - extend(rightBBox, node.leaf ? toBBox(child) : child); - margin += bboxMargin(rightBBox); - } - - return margin; - }, - - _adjustParentBBoxes: function (bbox, path, level) - { - // adjust bboxes along the given tree path - for (var i = level; i >= 0; i--) { - extend(path[i], bbox); - } - }, - - _condense: function (path) - { - // go through the path, removing empty nodes and updating bboxes - for (var i = path.length - 1, siblings; i >= 0; i--) { - if (path[i].children.length === 0) { - if (i > 0) { - siblings = path[i - 1].children; - siblings.splice(siblings.indexOf(path[i]), 1); - - } else this.clear(); - - } else calcBBox(path[i], this.toBBox); - } - }, - - compareMinX: function (a, b) - { - return a.left - b.left; - }, - - compareMinY: function (a, b) - { - return a.top - b.top; - }, - - toBBox: function (a) - { - return { - minX: a.left, - minY: a.top, - maxX: a.right, - maxY: a.bottom - }; - } -}; - -function findItem (item, items, equalsFn) -{ - if (!equalsFn) return items.indexOf(item); - - for (var i = 0; i < items.length; i++) { - if (equalsFn(item, items[i])) return i; - } - return -1; -} - -// calculate node's bbox from bboxes of its children -function calcBBox (node, toBBox) -{ - distBBox(node, 0, node.children.length, toBBox, node); -} - -// min bounding rectangle of node children from k to p-1 -function distBBox (node, k, p, toBBox, destNode) -{ - if (!destNode) destNode = createNode(null); - destNode.minX = Infinity; - destNode.minY = Infinity; - destNode.maxX = -Infinity; - destNode.maxY = -Infinity; - - for (var i = k, child; i < p; i++) { - child = node.children[i]; - extend(destNode, node.leaf ? toBBox(child) : child); - } - - return destNode; -} - -function extend (a, b) -{ - a.minX = Math.min(a.minX, b.minX); - a.minY = Math.min(a.minY, b.minY); - a.maxX = Math.max(a.maxX, b.maxX); - a.maxY = Math.max(a.maxY, b.maxY); - return a; -} - -function compareNodeMinX (a, b) { return a.minX - b.minX; } -function compareNodeMinY (a, b) { return a.minY - b.minY; } - -function bboxArea (a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } -function bboxMargin (a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } - -function enlargedArea (a, b) -{ - return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * - (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); -} - -function intersectionArea (a, b) -{ - var minX = Math.max(a.minX, b.minX), - minY = Math.max(a.minY, b.minY), - maxX = Math.min(a.maxX, b.maxX), - maxY = Math.min(a.maxY, b.maxY); - - return Math.max(0, maxX - minX) * - Math.max(0, maxY - minY); -} - -function contains (a, b) -{ - return a.minX <= b.minX && - a.minY <= b.minY && - b.maxX <= a.maxX && - b.maxY <= a.maxY; -} - -function intersects (a, b) -{ - return b.minX <= a.maxX && - b.minY <= a.maxY && - b.maxX >= a.minX && - b.maxY >= a.minY; -} - -function createNode (children) -{ - return { - children: children, - height: 1, - leaf: true, - minX: Infinity, - minY: Infinity, - maxX: -Infinity, - maxY: -Infinity - }; -} - -// sort an array so that items come in groups of n unsorted items, with groups sorted between each other; -// combines selection algorithm with binary divide & conquer approach - -function multiSelect (arr, left, right, n, compare) -{ - var stack = [left, right], - mid; - - while (stack.length) - { - right = stack.pop(); - left = stack.pop(); - - if (right - left <= n) continue; - - mid = left + Math.ceil((right - left) / n / 2) * n; - quickselect(arr, mid, left, right, compare); - - stack.push(left, mid, mid, right); - } -} - -module.exports = rbush; - -/***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TileCheckX = __webpack_require__(511); -var TileCheckY = __webpack_require__(513); -var TileIntersectsBody = __webpack_require__(243); - -/** - * The core separation function to separate a physics body and a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.SeparateTile - * @since 3.0.0 - * - * @param {number} i - The index of the tile within the map data. - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to collide against. - * @param {Phaser.Geom.Rectangle} tileWorldRect - A rectangle-like object defining the dimensions of the tile. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The tilemapLayer to collide against. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {boolean} `true` if the body was separated, otherwise `false`. - */ -var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) -{ - var tileLeft = tileWorldRect.left; - var tileTop = tileWorldRect.top; - var tileRight = tileWorldRect.right; - var tileBottom = tileWorldRect.bottom; - var faceHorizontal = tile.faceLeft || tile.faceRight; - var faceVertical = tile.faceTop || tile.faceBottom; - - if (!isLayer) - { - faceHorizontal = true; - faceVertical = true; - } - - // We don't need to go any further if this tile doesn't actually have any colliding faces. This - // could happen if the tile was meant to be collided with re: a callback, but otherwise isn't - // needed for separation. - if (!faceHorizontal && !faceVertical) - { - return false; - } - - var ox = 0; - var oy = 0; - var minX = 0; - var minY = 1; - - if (body.deltaAbsX() > body.deltaAbsY()) - { - // Moving faster horizontally, check X axis first - minX = -1; - } - else if (body.deltaAbsX() < body.deltaAbsY()) - { - // Moving faster vertically, check Y axis first - minY = -1; - } - - if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical) - { - // We only need do this if both axes have colliding faces AND we're moving in both - // directions - minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft)); - minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop)); - } - - if (minX < minY) - { - if (faceHorizontal) - { - ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); - - // That's horizontal done, check if we still intersects? If not then we can return now - if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) - { - return true; - } - } - - if (faceVertical) - { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - } - } - else - { - if (faceVertical) - { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - - // That's vertical done, check if we still intersects? If not then we can return now - if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) - { - return true; - } - } - - if (faceHorizontal) - { - ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); - } - } - - return (ox !== 0 || oy !== 0); -}; - -module.exports = SeparateTile; - - -/***/ }), -/* 511 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ProcessTileSeparationX = __webpack_require__(512); - -/** - * Check the body against the given tile on the X axis. - * Used internally by the SeparateTile function. - * - * @function Phaser.Physics.Arcade.Tilemap.TileCheckX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to check. - * @param {number} tileLeft - The left position of the tile within the tile world. - * @param {number} tileRight - The right position of the tile within the tile world. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {number} The amount of separation that occurred. - */ -var TileCheckX = function (body, tile, tileLeft, tileRight, tileBias, isLayer) -{ - var ox = 0; - - var faceLeft = tile.faceLeft; - var faceRight = tile.faceRight; - var collideLeft = tile.collideLeft; - var collideRight = tile.collideRight; - - if (!isLayer) - { - faceLeft = true; - faceRight = true; - collideLeft = true; - collideRight = true; - } - - if (body.deltaX() < 0 && collideRight && body.checkCollision.left) - { - // Body is moving LEFT - if (faceRight && body.x < tileRight) - { - ox = body.x - tileRight; - - if (ox < -tileBias) - { - ox = 0; - } - } - } - else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) - { - // Body is moving RIGHT - if (faceLeft && body.right > tileLeft) - { - ox = body.right - tileLeft; - - if (ox > tileBias) - { - ox = 0; - } - } - } - - if (ox !== 0) - { - if (body.customSeparateX) - { - body.overlapX = ox; - } - else - { - ProcessTileSeparationX(body, ox); - } - } - - return ox; -}; - -module.exports = TileCheckX; - - -/***/ }), -/* 512 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Internal function to process the separation of a physics body from a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {number} x - The x separation amount. - */ -var ProcessTileSeparationX = function (body, x) -{ - if (x < 0) - { - body.blocked.none = false; - body.blocked.left = true; - } - else if (x > 0) - { - body.blocked.none = false; - body.blocked.right = true; - } - - body.position.x -= x; - - if (body.bounce.x === 0) - { - body.velocity.x = 0; - } - else - { - body.velocity.x = -body.velocity.x * body.bounce.x; - } -}; - -module.exports = ProcessTileSeparationX; - - -/***/ }), -/* 513 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ProcessTileSeparationY = __webpack_require__(514); - -/** - * Check the body against the given tile on the Y axis. - * Used internally by the SeparateTile function. - * - * @function Phaser.Physics.Arcade.Tilemap.TileCheckY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to check. - * @param {number} tileTop - The top position of the tile within the tile world. - * @param {number} tileBottom - The bottom position of the tile within the tile world. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {number} The amount of separation that occurred. - */ -var TileCheckY = function (body, tile, tileTop, tileBottom, tileBias, isLayer) -{ - var oy = 0; - - var faceTop = tile.faceTop; - var faceBottom = tile.faceBottom; - var collideUp = tile.collideUp; - var collideDown = tile.collideDown; - - if (!isLayer) - { - faceTop = true; - faceBottom = true; - collideUp = true; - collideDown = true; - } - - if (body.deltaY() < 0 && collideDown && body.checkCollision.up) - { - // Body is moving UP - if (faceBottom && body.y < tileBottom) - { - oy = body.y - tileBottom; - - if (oy < -tileBias) - { - oy = 0; - } - } - } - else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) - { - // Body is moving DOWN - if (faceTop && body.bottom > tileTop) - { - oy = body.bottom - tileTop; - - if (oy > tileBias) - { - oy = 0; - } - } - } - - if (oy !== 0) - { - if (body.customSeparateY) - { - body.overlapY = oy; - } - else - { - ProcessTileSeparationY(body, oy); - } - } - - return oy; -}; - -module.exports = TileCheckY; - - -/***/ }), -/* 514 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Internal function to process the separation of a physics body from a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {number} y - The y separation amount. - */ -var ProcessTileSeparationY = function (body, y) -{ - if (y < 0) - { - body.blocked.none = false; - body.blocked.up = true; - } - else if (y > 0) - { - body.blocked.none = false; - body.blocked.down = true; - } - - body.position.y -= y; - - if (body.bounce.y === 0) - { - body.velocity.y = 0; - } - else - { - body.velocity.y = -body.velocity.y * body.bounce.y; - } -}; - -module.exports = ProcessTileSeparationY; - - -/***/ }), -/* 515 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetOverlapX = __webpack_require__(241); -var ProcessX = __webpack_require__(1383); - -/** - * Separates two overlapping bodies on the X-axis (horizontally). - * - * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. - * - * The bodies won't be separated if there is no horizontal overlap between them, if they are static, or if either one uses custom logic for its separation. - * - * @function Phaser.Physics.Arcade.SeparateX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. - * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. - * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. - * - * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. - */ -var SeparateX = function (body1, body2, overlapOnly, bias) -{ - var overlap = GetOverlapX(body1, body2, overlapOnly, bias); - - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateX || body2.customSeparateX) - { - // return true if there was some overlap, otherwise false - return (overlap !== 0) || (body1.embedded && body2.embedded); - } - - var blockedState = ProcessX.Set(body1, body2, overlap); - - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) - { - return true; - } - - return ProcessX.Check(); - } - else if (body1Immovable) - { - ProcessX.RunImmovableBody1(blockedState); - } - else if (body2Immovable) - { - ProcessX.RunImmovableBody2(blockedState); - } - - // If we got this far then there WAS overlap, and separation is complete, so return true - return true; -}; - -module.exports = SeparateX; - - -/***/ }), -/* 516 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetOverlapY = __webpack_require__(242); -var ProcessY = __webpack_require__(1384); - -/** - * Separates two overlapping bodies on the Y-axis (vertically). - * - * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. - * - * The bodies won't be separated if there is no vertical overlap between them, if they are static, or if either one uses custom logic for its separation. - * - * @function Phaser.Physics.Arcade.SeparateY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. - * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. - * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. - * - * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. - */ -var SeparateY = function (body1, body2, overlapOnly, bias) -{ - var overlap = GetOverlapY(body1, body2, overlapOnly, bias); - - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateY || body2.customSeparateY) - { - // return true if there was some overlap, otherwise false - return (overlap !== 0) || (body1.embedded && body2.embedded); - } - - var blockedState = ProcessY.Set(body1, body2, overlap); - - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) - { - return true; - } - - return ProcessY.Check(); - } - else if (body1Immovable) - { - ProcessY.RunImmovableBody1(blockedState); - } - else if (body2Immovable) - { - ProcessY.RunImmovableBody2(blockedState); - } - - // If we got this far then there WAS overlap, and separation is complete, so return true - return true; -}; - -module.exports = SeparateY; - - -/***/ }), -/* 517 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircleContains = __webpack_require__(62); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var RectangleContains = __webpack_require__(56); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A Static Arcade Physics Body. - * - * A Static Body never moves, and isn't automatically synchronized with its parent Game Object. - * That means if you make any change to the parent's origin, position, or scale after creating or adding the body, you'll need to update the Static Body manually. - * - * A Static Body can collide with other Bodies, but is never moved by collisions. - * - * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Body}. - * - * @class StaticBody - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Static Body belongs to. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Static Body belongs to. - */ -var StaticBody = new Class({ - - initialize: - - function StaticBody (world, gameObject) - { - var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; - var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; - - /** - * The Arcade Physics simulation this Static Body belongs to. - * - * @name Phaser.Physics.Arcade.StaticBody#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The Game Object this Static Body belongs to. - * - * @name Phaser.Physics.Arcade.StaticBody#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.gameObject = gameObject; - - /** - * Whether the Static Body's boundary is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.StaticBody#debugShowBody - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowBody = world.defaults.debugShowStaticBody; - - /** - * The color of this Static Body on the debug display. - * - * @name Phaser.Physics.Arcade.StaticBody#debugBodyColor - * @type {number} - * @since 3.0.0 - */ - this.debugBodyColor = world.defaults.staticBodyDebugColor; - - /** - * Whether this Static Body is updated by the physics simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#enable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enable = true; - - /** - * Whether this Static Body's boundary is circular (`true`) or rectangular (`false`). - * - * @name Phaser.Physics.Arcade.StaticBody#isCircle - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isCircle = false; - - /** - * If this Static Body is circular, this is the radius of the boundary, as set by {@link Phaser.Physics.Arcade.StaticBody#setCircle}, in pixels. - * Equal to `halfWidth`. - * - * @name Phaser.Physics.Arcade.StaticBody#radius - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.radius = 0; - - /** - * The offset set by {@link Phaser.Physics.Arcade.StaticBody#setCircle} or {@link Phaser.Physics.Arcade.StaticBody#setSize}. - * - * This doesn't affect the Static Body's position, because a Static Body does not follow its Game Object. - * - * @name Phaser.Physics.Arcade.StaticBody#offset - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.offset = new Vector2(); - - /** - * The position of this Static Body within the simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#position - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.position = new Vector2(gameObject.x - (width * gameObject.originX), gameObject.y - (height * gameObject.originY)); - - /** - * The width of the Static Body's boundary, in pixels. - * If the Static Body is circular, this is also the Static Body's diameter. - * - * @name Phaser.Physics.Arcade.StaticBody#width - * @type {number} - * @since 3.0.0 - */ - this.width = width; - - /** - * The height of the Static Body's boundary, in pixels. - * If the Static Body is circular, this is also the Static Body's diameter. - * - * @name Phaser.Physics.Arcade.StaticBody#height - * @type {number} - * @since 3.0.0 - */ - this.height = height; - - /** - * Half the Static Body's width, in pixels. - * If the Static Body is circular, this is also the Static Body's radius. - * - * @name Phaser.Physics.Arcade.StaticBody#halfWidth - * @type {number} - * @since 3.0.0 - */ - this.halfWidth = Math.abs(this.width / 2); - - /** - * Half the Static Body's height, in pixels. - * If the Static Body is circular, this is also the Static Body's radius. - * - * @name Phaser.Physics.Arcade.StaticBody#halfHeight - * @type {number} - * @since 3.0.0 - */ - this.halfHeight = Math.abs(this.height / 2); - - /** - * The center of the Static Body's boundary. - * This is the midpoint of its `position` (top-left corner) and its bottom-right corner. - * - * @name Phaser.Physics.Arcade.StaticBody#center - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - /** - * A constant zero velocity used by the Arcade Physics simulation for calculations. - * - * @name Phaser.Physics.Arcade.StaticBody#velocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.velocity = Vector2.ZERO; - - /** - * A constant `false` value expected by the Arcade Physics simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#allowGravity - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.allowGravity = false; - - /** - * Gravitational force applied specifically to this Body. Values are in pixels per second squared. Always zero for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#gravity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.gravity = Vector2.ZERO; - - /** - * Rebound, or restitution, following a collision, relative to 1. Always zero for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#bounce - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.bounce = Vector2.ZERO; - - // If true this Body will dispatch events - - /** - * Whether the simulation emits a `worldbounds` event when this StaticBody collides with the world boundary. - * Always false for a Static Body. (Static Bodies never collide with the world boundary and never trigger a `worldbounds` event.) - * - * @name Phaser.Physics.Arcade.StaticBody#onWorldBounds - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.onWorldBounds = false; - - /** - * Whether the simulation emits a `collide` event when this StaticBody collides with another. - * - * @name Phaser.Physics.Arcade.StaticBody#onCollide - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.onCollide = false; - - /** - * Whether the simulation emits an `overlap` event when this StaticBody overlaps with another. - * - * @name Phaser.Physics.Arcade.StaticBody#onOverlap - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.onOverlap = false; - - /** - * The StaticBody's inertia, relative to a default unit (1). With `bounce`, this affects the exchange of momentum (velocities) during collisions. - * - * @name Phaser.Physics.Arcade.StaticBody#mass - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.mass = 1; - - /** - * Whether this object can be moved by collisions with another body. - * - * @name Phaser.Physics.Arcade.StaticBody#immovable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.immovable = true; - - /** - * Sets if this Body can be pushed by another Body. - * - * A body that cannot be pushed will reflect back all of the velocity it is given to the - * colliding body. If that body is also not pushable, then the separation will be split - * between them evenly. - * - * If you want your body to never move or seperate at all, see the `setImmovable` method. - * - * By default, Static Bodies are not pushable. - * - * @name Phaser.Physics.Arcade.StaticBody#pushable - * @type {boolean} - * @default false - * @since 3.50.0 - * @see Phaser.GameObjects.Components.Pushable#setPushable - */ - this.pushable = false; - - /** - * A flag disabling the default horizontal separation of colliding bodies. Pass your own `collideHandler` to the collider. - * - * @name Phaser.Physics.Arcade.StaticBody#customSeparateX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateX = false; - - /** - * A flag disabling the default vertical separation of colliding bodies. Pass your own `collideHandler` to the collider. - * - * @name Phaser.Physics.Arcade.StaticBody#customSeparateY - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateY = false; - - /** - * The amount of horizontal overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapX = 0; - - /** - * The amount of vertical overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapY = 0; - - /** - * The amount of overlap (before separation), if this StaticBody is circular and colliding with another circular body. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapR - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapR = 0; - - /** - * Whether this StaticBody has ever overlapped with another while both were not moving. - * - * @name Phaser.Physics.Arcade.StaticBody#embedded - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.embedded = false; - - /** - * Whether this StaticBody interacts with the world boundary. - * Always false for a Static Body. (Static Bodies never collide with the world boundary.) - * - * @name Phaser.Physics.Arcade.StaticBody#collideWorldBounds - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.collideWorldBounds = false; - - /** - * Whether this StaticBody is checked for collisions and for which directions. You can set `checkCollision.none = false` to disable collision checks. - * - * @name Phaser.Physics.Arcade.StaticBody#checkCollision - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * - * @name Phaser.Physics.Arcade.StaticBody#touching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.touching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * The values are always false for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#wasTouching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * - * @name Phaser.Physics.Arcade.StaticBody#blocked - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.blocked = { none: true, up: false, down: false, left: false, right: false }; - - /** - * The StaticBody's physics type (static by default). - * - * @name Phaser.Physics.Arcade.StaticBody#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.STATIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.STATIC_BODY; - - /** - * The calculated change in the Static Body's horizontal position during the current step. - * For a static body this is always zero. - * - * @name Phaser.Physics.Arcade.StaticBody#_dx - * @type {number} - * @private - * @default 0 - * @since 3.10.0 - */ - this._dx = 0; - - /** - * The calculated change in the Static Body's vertical position during the current step. - * For a static body this is always zero. - * - * @name Phaser.Physics.Arcade.StaticBody#_dy - * @type {number} - * @private - * @default 0 - * @since 3.10.0 - */ - this._dy = 0; - }, - - /** - * Changes the Game Object this Body is bound to. - * First it removes its reference from the old Game Object, then sets the new one. - * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#setGameObject - * @since 3.1.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. - * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - * - * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject - */ - setGameObject: function (gameObject, update) - { - if (gameObject && gameObject !== this.gameObject) - { - // Remove this body from the old game object - this.gameObject.body = null; - - gameObject.body = this; - - // Update our reference - this.gameObject = gameObject; - } - - if (update) - { - this.updateFromGameObject(); - } - - return this; - }, - - /** - * Syncs the Static Body's position and size with its parent Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject - * @since 3.1.0 - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - updateFromGameObject: function () - { - this.world.staticTree.remove(this); - - var gameObject = this.gameObject; - - gameObject.getTopLeft(this.position); - - this.width = gameObject.displayWidth; - this.height = gameObject.displayHeight; - - this.halfWidth = Math.abs(this.width / 2); - this.halfHeight = Math.abs(this.height / 2); - - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Positions the Static Body at an offset from its Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#setOffset - * @since 3.4.0 - * - * @param {number} x - The horizontal offset of the Static Body from the Game Object's `x`. - * @param {number} y - The vertical offset of the Static Body from the Game Object's `y`. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setOffset: function (x, y) - { - if (y === undefined) { y = x; } - - this.world.staticTree.remove(this); - - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; - - this.offset.set(x, y); - - this.position.x += this.offset.x; - this.position.y += this.offset.y; - - this.updateCenter(); - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Sets the size of the Static Body. - * When `center` is true, also repositions it. - * Resets the width and height to match current frame, if no width and height provided and a frame is found. - * - * @method Phaser.Physics.Arcade.StaticBody#setSize - * @since 3.0.0 - * - * @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. - * @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. - * @param {boolean} [center=true] - Place the Static Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setSize: function (width, height, center) - { - if (center === undefined) { center = true; } - - var gameObject = this.gameObject; - - if (!width && gameObject.frame) - { - width = gameObject.frame.realWidth; - } - - if (!height && gameObject.frame) - { - height = gameObject.frame.realHeight; - } - - this.world.staticTree.remove(this); - - this.width = width; - this.height = height; - - this.halfWidth = Math.floor(width / 2); - this.halfHeight = Math.floor(height / 2); - - if (center && gameObject.getCenter) - { - var ox = gameObject.displayWidth / 2; - var oy = gameObject.displayHeight / 2; - - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; - - this.offset.set(ox - this.halfWidth, oy - this.halfHeight); - - this.position.x += this.offset.x; - this.position.y += this.offset.y; - } - - this.updateCenter(); - - this.isCircle = false; - this.radius = 0; - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Sets this Static Body to have a circular body and sets its size and position. - * - * @method Phaser.Physics.Arcade.StaticBody#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the StaticBody, in pixels. - * @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels. - * @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setCircle: function (radius, offsetX, offsetY) - { - if (offsetX === undefined) { offsetX = this.offset.x; } - if (offsetY === undefined) { offsetY = this.offset.y; } - - if (radius > 0) - { - this.world.staticTree.remove(this); - - this.isCircle = true; - - this.radius = radius; - - this.width = radius * 2; - this.height = radius * 2; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.offset.set(offsetX, offsetY); - - this.updateCenter(); - - this.world.staticTree.insert(this); - } - else - { - this.isCircle = false; - } - - return this; - }, - - /** - * Updates the StaticBody's `center` from its `position` and dimensions. - * - * @method Phaser.Physics.Arcade.StaticBody#updateCenter - * @since 3.0.0 - */ - updateCenter: function () - { - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - }, - - /** - * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. - * - * @method Phaser.Physics.Arcade.StaticBody#reset - * @since 3.0.0 - * - * @param {number} [x] - The x coordinate to reset the body to. If not given will use the parent Game Object's coordinate. - * @param {number} [y] - The y coordinate to reset the body to. If not given will use the parent Game Object's coordinate. - */ - reset: function (x, y) - { - var gameObject = this.gameObject; - - if (x === undefined) { x = gameObject.x; } - if (y === undefined) { y = gameObject.y; } - - this.world.staticTree.remove(this); - - gameObject.setPosition(x, y); - - gameObject.getTopLeft(this.position); - - this.updateCenter(); - - this.world.staticTree.insert(this); - }, - - /** - * NOOP function. A Static Body cannot be stopped. - * - * @method Phaser.Physics.Arcade.StaticBody#stop - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - stop: function () - { - return this; - }, - - /** - * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. - * - * @method Phaser.Physics.Arcade.StaticBody#getBounds - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. - * - * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody. - */ - getBounds: function (obj) - { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; - - return obj; - }, - - /** - * Checks to see if a given x,y coordinate is colliding with this Static Body. - * - * @method Phaser.Physics.Arcade.StaticBody#hitTest - * @since 3.0.0 - * - * @param {number} x - The x coordinate to check against this body. - * @param {number} y - The y coordinate to check against this body. - * - * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. - */ - hitTest: function (x, y) - { - return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); - }, - - /** - * NOOP - * - * @method Phaser.Physics.Arcade.StaticBody#postUpdate - * @since 3.12.0 - */ - postUpdate: function () - { - }, - - /** - * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX - * @since 3.0.0 - * - * @return {number} Always zero for a Static Body. - */ - deltaAbsX: function () - { - return 0; - }, - - /** - * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY - * @since 3.0.0 - * - * @return {number} Always zero for a Static Body. - */ - deltaAbsY: function () - { - return 0; - }, - - /** - * The change in this StaticBody's horizontal position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaX - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. - */ - deltaX: function () - { - return 0; - }, - - /** - * The change in this StaticBody's vertical position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaY - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. - */ - deltaY: function () - { - return 0; - }, - - /** - * The change in this StaticBody's rotation from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaZ - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. - */ - deltaZ: function () - { - return 0; - }, - - /** - * Disables this Body and marks it for destruction during the next step. - * - * @method Phaser.Physics.Arcade.StaticBody#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enable = false; - - this.world.pendingDestroy.set(this); - }, - - /** - * Draws a graphical representation of the StaticBody for visual debugging purposes. - * - * @method Phaser.Physics.Arcade.StaticBody#drawDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. - */ - drawDebug: function (graphic) - { - var pos = this.position; - - var x = pos.x + this.halfWidth; - var y = pos.y + this.halfHeight; - - if (this.debugShowBody) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor, 1); - - if (this.isCircle) - { - graphic.strokeCircle(x, y, this.width / 2); - } - else - { - graphic.strokeRect(pos.x, pos.y, this.width, this.height); - } - - } - }, - - /** - * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. - * - * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug - * @since 3.0.0 - * - * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. - */ - willDrawDebug: function () - { - return this.debugShowBody; - }, - - /** - * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. - * - * @method Phaser.Physics.Arcade.StaticBody#setMass - * @since 3.0.0 - * - * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setMass: function (value) - { - if (value <= 0) - { - // Causes havoc otherwise - value = 0.1; - } - - this.mass = value; - - return this; - }, - - /** - * The x coordinate of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.world.staticTree.remove(this); - - this.position.x = value; - - this.world.staticTree.insert(this); - } - - }, - - /** - * The y coordinate of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.world.staticTree.remove(this); - - this.position.y = value; - - this.world.staticTree.insert(this); - } - - }, - - /** - * Returns the left-most x coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#left - * @type {number} - * @readonly - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.position.x; - } - - }, - - /** - * The right-most x coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#right - * @type {number} - * @readonly - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.position.x + this.width; - } - - }, - - /** - * The highest y coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#top - * @type {number} - * @readonly - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.position.y; - } - - }, - - /** - * The lowest y coordinate of the area of the StaticBody. (y + height) - * - * @name Phaser.Physics.Arcade.StaticBody#bottom - * @type {number} - * @readonly - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.position.y + this.height; - } - - } - -}); - -module.exports = StaticBody; - - -/***/ }), -/* 518 */, -/* 519 */, -/* 520 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* @author Richard Davey -* @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; - - -/***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); - -/** - * Checks if the given tile coordinate is within the isometric layer bounds, or not. - * - * @function Phaser.Tilemaps.Components.CheckIsoBounds - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to check against. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. - * - * @return {boolean} Returns `true` if the coordinates are within the iso bounds. - */ -var CheckIsoBounds = function (tileX, tileY, layer, camera) -{ - var tilemapLayer = layer.tilemapLayer; - - var cullPaddingX = tilemapLayer.cullPaddingX; - var cullPaddingY = tilemapLayer.cullPaddingY; - - var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer); - - // we always subtract 1/2 of the tile's height/width to make the culling distance start from the center of the tiles. - return pos.x > camera.worldView.x + tilemapLayer.scaleX * layer.tileWidth * (-cullPaddingX - 0.5) - && pos.x < camera.worldView.right + tilemapLayer.scaleX * layer.tileWidth * (cullPaddingX - 0.5) - && pos.y > camera.worldView.y + tilemapLayer.scaleY * layer.tileHeight * (-cullPaddingY - 1.0) - && pos.y < camera.worldView.bottom + tilemapLayer.scaleY * layer.tileHeight * (cullPaddingY - 0.5); -}; - -module.exports = CheckIsoBounds; - - -/***/ }), -/* 522 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTilesWithin = __webpack_require__(26); - -/** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * @function Phaser.Tilemaps.Components.ReplaceByIndex - * @since 3.0.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var ReplaceByIndex = function (findIndex, newIndex, tileX, tileY, width, height, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - - for (var i = 0; i < tiles.length; i++) - { - if (tiles[i] && tiles[i].index === findIndex) - { - tiles[i].index = newIndex; - } - } -}; - -module.exports = ReplaceByIndex; - - -/***/ }), -/* 523 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -var bounds = new Rectangle(); - -/** - * Returns the bounds in the given orthogonal layer that are within the cameras viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.CullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {Phaser.Geom.Rectangle} A rectangle containing the culled bounds. If you wish to retain this object, clone it, as it's recycled internally. - */ -var CullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY; - - return bounds.setTo( - boundsLeft, - boundsTop, - (boundsRight - boundsLeft), - (boundsBottom - boundsTop) - ); -}; - -module.exports = CullBounds; - - -/***/ }), -/* 524 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(523); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.CullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var CullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - var bounds = CullBounds(layer, camera); - - if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) - { - bounds.left = 0; - bounds.right = layer.width; - bounds.top = 0; - bounds.bottom = layer.height; - } - - RunCull(layer, bounds, renderOrder, outputArray); - - return outputArray; -}; - -module.exports = CullTiles; - - -/***/ }), -/* 525 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(526); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.HexagonalCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var HexagonalCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) - { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - - var bounds = CullBounds(layer, camera); - - RunCull(layer, bounds, renderOrder, outputArray); - } - - return outputArray; -}; - -module.exports = HexagonalCullTiles; - - -/***/ }), -/* 526 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -/** - * Returns the bounds in the given layer that are within the camera's viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.HexagonalCullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. - */ -var HexagonalCullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var len = layer.hexSideLength; - var rowH = ((tileH - len) / 2 + len); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY; - - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; -}; - -module.exports = HexagonalCullBounds; - - -/***/ }), -/* 527 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CheckIsoBounds = __webpack_require__(521); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.IsometricCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; - - var drawLeft = 0; - var drawRight = mapWidth; - var drawTop = 0; - var drawBottom = mapHeight; - - if (!tilemapLayer.skipCull) - { - var x; - var y; - var tile; - - if (renderOrder === 0) - { - // right-down - - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 1) - { - // left-down - - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 2) - { - // right-up - - for (y = drawBottom; y >= drawTop; y--) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 3) - { - // left-up - - for (y = drawBottom; y >= drawTop; y--) - { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - } - - tilemapLayer.tilesDrawn = outputArray.length; - tilemapLayer.tilesTotal = mapWidth * mapHeight; - - return outputArray; -}; - -module.exports = IsometricCullTiles; - - -/***/ }), -/* 528 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(529); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.StaggeredCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var StaggeredCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) - { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - - var bounds = CullBounds(layer, camera); - - RunCull(layer, bounds, renderOrder, outputArray); - } - - return outputArray; -}; - -module.exports = StaggeredCullTiles; - - -/***/ }), -/* 529 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -/** - * Returns the bounds in the given layer that are within the camera's viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.StaggeredCullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. - */ -var StaggeredCullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH / 2, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH / 2, 0, true) + tilemapLayer.cullPaddingY; - - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; -}; - -module.exports = StaggeredCullBounds; - - -/***/ }), -/* 530 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from hexagonal tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.HexagonalTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = layer.hexSideLength; - var rowHeight = ((tileHeight - len) / 2 + len); - - // similar to staggered, because Tiled uses the oddr representation. - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * rowHeight; - - return point.set(x, y); -}; - -module.exports = HexagonalTileToWorldXY; - - -/***/ }), -/* 531 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from isometric tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.IsometricTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var IsometricTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); - var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); - - return point.set(x, y); -}; - -module.exports = IsometricTileToWorldXY; - - -/***/ }), -/* 532 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from staggered tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.StaggeredTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var StaggeredTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * (tileHeight / 2); - - return point.set(x, y); -}; - -module.exports = StaggeredTileToWorldXY; - - -/***/ }), -/* 533 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TileToWorldX = __webpack_require__(247); -var TileToWorldY = __webpack_require__(248); -var Vector2 = __webpack_require__(3); - -/** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.TileToWorldXY - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var TileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(0, 0); } - - point.x = TileToWorldX(tileX, camera, layer); - point.y = TileToWorldY(tileY, camera, layer); - - return point; -}; - -module.exports = TileToWorldXY; - - -/***/ }), -/* 534 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from hexagonal tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.HexagonalTileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in world coordinates. - */ -var HexagonalTileToWorldY = function (tileY, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = tilemapLayer.tilemap.hexSideLength; - - var rowHeight = ((tileHeight - len) / 2 + len); - - return layerWorldY + tileY * rowHeight; -}; - -module.exports = HexagonalTileToWorldY; - - -/***/ }), -/* 535 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from staggered tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.StaggeredTileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in world coordinates. - */ -var StaggeredTileToWorldY = function (tileY, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - return layerWorldY + tileY * (tileHeight / 2); -}; - -module.exports = StaggeredTileToWorldY; - - -/***/ }), -/* 536 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinates down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - var len = layer.hexSideLength; - var rowHeight = ((tileHeight - len) / 2 + len); - - // similar to staggered, because Tiled uses the oddr representation. - var y = (snapToFloor) ? Math.floor((worldY / rowHeight)) : (worldY / rowHeight); - var x = (snapToFloor) ? Math.floor((worldX - (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX - (y % 2) * 0.5 * tileWidth) / tileWidth; - - return point.set(x, y); -}; - -module.exports = HexagonalWorldToTileXY; - - -/***/ }), -/* 537 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to isometric tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.IsometricWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var IsometricWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - worldX -= tileWidth / 2; - - var x = (snapToFloor) ? Math.floor((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2) : ((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2); - var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2) : ((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2); - - return point.set(x, y); -}; - -module.exports = IsometricWorldToTileXY; - - -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to staggered tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var StaggeredWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2))) : (worldY / (tileHeight / 2)); - var x = (snapToFloor) ? Math.floor((worldX + (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX + (y % 2) * 0.5 * tileWidth) / tileWidth; - - return point.set(x, y); -}; - -module.exports = StaggeredWorldToTileXY; - - -/***/ }), -/* 539 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var WorldToTileX = __webpack_require__(249); -var WorldToTileY = __webpack_require__(250); -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.WorldToTileXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var WorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (snapToFloor === undefined) { snapToFloor = true; } - if (!point) { point = new Vector2(0, 0); } - - point.x = WorldToTileX(worldX, snapToFloor, camera, layer); - point.y = WorldToTileY(worldY, snapToFloor, camera, layer); - - return point; -}; - -module.exports = WorldToTileXY; - - -/***/ }), -/* 540 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from world Y coordinates (pixels) to hexagonal tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.HexagonalWorldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in tile units. - */ -var HexagonalWorldToTileY = function (worldY, snapToFloor, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = layer.hexSideLength; - - var rowHeight = ((tileHeight - len) / 2 + len); - - return (snapToFloor) ? Math.floor(worldY / rowHeight) : worldY / rowHeight; -}; - -module.exports = HexagonalWorldToTileY; - - -/***/ }), -/* 541 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from world Y coordinates (pixels) to staggered tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in tile units. - */ -var StaggeredWorldToTileY = function (worldY, snapToFloor, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - return (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); -}; - -module.exports = StaggeredWorldToTileY; - - -/***/ }), -/* 542 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var IsInLayerBounds = __webpack_require__(116); - -/** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @function Phaser.Tilemaps.Components.HasTileAt - * @since 3.0.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ -var HasTileAt = function (tileX, tileY, layer) -{ - if (IsInLayerBounds(tileX, tileY, layer)) - { - var tile = layer.data[tileY][tileX]; - - return (tile !== null && tile.index > -1); - } - else - { - return false; - } -}; - -module.exports = HasTileAt; - - -/***/ }), -/* 543 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tile = __webpack_require__(83); -var IsInLayerBounds = __webpack_require__(116); -var CalculateFacesAt = __webpack_require__(246); - -/** - * Removes the tile at the given tile coordinates in the specified layer and updates the layer's - * collision information. - * - * @function Phaser.Tilemaps.Components.RemoveTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. - * @param {boolean} replaceWithNull - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} recalculateFaces - `true` if the faces data should be recalculated. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was removed. - */ -var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) -{ - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - if (!IsInLayerBounds(tileX, tileY, layer)) - { - return null; - } - - var tile = layer.data[tileY][tileX]; - - if (!tile) - { - return null; - } - else - { - layer.data[tileY][tileX] = (replaceWithNull) ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight); - } - - // Recalculate faces only if the removed tile was a colliding tile - if (recalculateFaces && tile && tile.collides) - { - CalculateFacesAt(tileX, tileY, layer); - } - - return tile; -}; - -module.exports = RemoveTileAt; - - -/***/ }), -/* 544 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var Parse2DArray = __webpack_require__(253); -var ParseCSV = __webpack_require__(545); -var ParseJSONTiled = __webpack_require__(546); -var ParseWeltmeister = __webpack_require__(557); - -/** - * Parses raw data of a given Tilemap format into a new MapData object. If no recognized data format - * is found, returns `null`. When loading from CSV or a 2D array, you should specify the tileWidth & - * tileHeight. When parsing from a map from Tiled, the tileWidth & tileHeight will be pulled from - * the map data. - * - * @function Phaser.Tilemaps.Parsers.Parse - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {number} mapFormat - See ../Formats.js. - * @param {(number[][]|string|object)} data - 2D array, CSV string or Tiled JSON object. - * @param {number} tileWidth - The width of a tile in pixels. Required for 2D array and CSV, but - * ignored for Tiled JSON. - * @param {number} tileHeight - The height of a tile in pixels. Required for 2D array and CSV, but - * ignored for Tiled JSON. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {Phaser.Tilemaps.MapData} The created `MapData` object. - */ -var Parse = function (name, mapFormat, data, tileWidth, tileHeight, insertNull) -{ - var newMap; - - switch (mapFormat) - { - case (Formats.ARRAY_2D): - newMap = Parse2DArray(name, data, tileWidth, tileHeight, insertNull); - break; - case (Formats.CSV): - newMap = ParseCSV(name, data, tileWidth, tileHeight, insertNull); - break; - case (Formats.TILED_JSON): - newMap = ParseJSONTiled(name, data, insertNull); - break; - case (Formats.WELTMEISTER): - newMap = ParseWeltmeister(name, data, insertNull); - break; - default: - console.warn('Unrecognized tilemap data format: ' + mapFormat); - newMap = null; - } - - return newMap; -}; - -module.exports = Parse; - - -/***/ }), -/* 545 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var Parse2DArray = __webpack_require__(253); - -/** - * Parses a CSV string of tile indexes into a new MapData object with a single layer. - * - * @function Phaser.Tilemaps.Parsers.ParseCSV - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {string} data - CSV string of tile indexes. - * @param {number} tileWidth - The width of a tile in pixels. - * @param {number} tileHeight - The height of a tile in pixels. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {Phaser.Tilemaps.MapData} The resulting MapData object. - */ -var ParseCSV = function (name, data, tileWidth, tileHeight, insertNull) -{ - var array2D = data - .trim() - .split('\n') - .map(function (row) { return row.split(','); }); - - var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); - map.format = Formats.CSV; - - return map; -}; - -module.exports = ParseCSV; - - -/***/ }), -/* 546 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AssignTileProperties = __webpack_require__(547); -var BuildTilesetIndex = __webpack_require__(548); -var CONST = __webpack_require__(29); -var Formats = __webpack_require__(37); -var FromOrientationString = __webpack_require__(252); -var MapData = __webpack_require__(118); -var ParseImageLayers = __webpack_require__(549); -var ParseObjectLayers = __webpack_require__(550); -var ParseTileLayers = __webpack_require__(553); -var ParseTilesets = __webpack_require__(555); - -/** - * Parses a Tiled JSON object into a new MapData object. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {object} json - The Tiled JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. - */ -var ParseJSONTiled = function (name, json, insertNull) -{ - // Map data will consist of: layers, objects, images, tilesets, sizes - var mapData = new MapData({ - width: json.width, - height: json.height, - name: name, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - orientation: FromOrientationString(json.orientation), - format: Formats.TILED_JSON, - version: json.version, - properties: json.properties, - renderOrder: json.renderorder, - infinite: json.infinite - }); - - if (mapData.orientation === CONST.HEXAGONAL) - { - mapData.hexSideLength = json.hexsidelength; - } - - mapData.layers = ParseTileLayers(json, insertNull); - mapData.images = ParseImageLayers(json); - - var sets = ParseTilesets(json); - - mapData.tilesets = sets.tilesets; - mapData.imageCollections = sets.imageCollections; - - mapData.objects = ParseObjectLayers(json); - - mapData.tiles = BuildTilesetIndex(mapData); - - AssignTileProperties(mapData); - - return mapData; -}; - -module.exports = ParseJSONTiled; - - -/***/ }), -/* 547 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Extend = __webpack_require__(19); - -/** - * Copy properties from tileset to tiles. - * - * @function Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. - */ -var AssignTileProperties = function (mapData) -{ - var layerData; - var tile; - var sid; - var set; - var row; - - // go through each of the map data layers - for (var i = 0; i < mapData.layers.length; i++) - { - layerData = mapData.layers[i]; - - set = null; - - // rows of tiles - for (var j = 0; j < layerData.data.length; j++) - { - row = layerData.data[j]; - - // individual tiles - for (var k = 0; k < row.length; k++) - { - tile = row[k]; - - if (tile === null || tile.index < 0) - { - continue; - } - - // find the relevant tileset - sid = mapData.tiles[tile.index][2]; - set = mapData.tilesets[sid]; - - // Ensure that a tile's size matches its tileset - tile.width = set.tileWidth; - tile.height = set.tileHeight; - - // if that tile type has any properties, add them to the tile object - if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) - { - tile.properties = Extend( - tile.properties, set.tileProperties[tile.index - set.firstgid] - ); - } - } - } - } -}; - -module.exports = AssignTileProperties; - - -/***/ }), -/* 548 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); - -/** - * Master list of tiles -> x, y, index in tileset. - * - * @function Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. - * - * @return {array} An array of Tileset objects. - */ -var BuildTilesetIndex = function (mapData) -{ - var i; - var set; - var tiles = []; - - for (i = 0; i < mapData.imageCollections.length; i++) - { - var collection = mapData.imageCollections[i]; - var images = collection.images; - - for (var j = 0; j < images.length; j++) - { - var image = images[j]; - - set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); - - set.updateTileData(collection.imageWidth, collection.imageHeight); - - mapData.tilesets.push(set); - } - } - - for (i = 0; i < mapData.tilesets.length; i++) - { - set = mapData.tilesets[i]; - - var x = set.tileMargin; - var y = set.tileMargin; - - var count = 0; - var countX = 0; - var countY = 0; - - for (var t = set.firstgid; t < set.firstgid + set.total; t++) - { - // Can add extra properties here as needed - tiles[t] = [ x, y, i ]; - - x += set.tileWidth + set.tileSpacing; - - count++; - - if (count === set.total) - { - break; - } - - countX++; - - if (countX === set.columns) - { - x = set.tileMargin; - y += set.tileHeight + set.tileSpacing; - - countX = 0; - countY++; - - if (countY === set.rows) - { - break; - } - } - } - } - - return tiles; -}; - -module.exports = BuildTilesetIndex; - - -/***/ }), -/* 549 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var CreateGroupLayer = __webpack_require__(158); - -/** - * Parses a Tiled JSON object into an array of objects with details about the image layers. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * - * @return {array} Array of objects that include critical info about the map's image layers - */ -var ParseImageLayers = function (json) -{ - var images = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - // Get current layer and advance iterator - var curi = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - if (curi.type !== 'imagelayer') - { - if (curi.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curi, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - var layerOffsetX = GetFastValue(curi, 'offsetx', 0) + GetFastValue(curi, 'startx', 0); - var layerOffsetY = GetFastValue(curi, 'offsety', 0) + GetFastValue(curi, 'starty', 0); - images.push({ - name: (curGroupState.name + curi.name), - image: curi.image, - x: (curGroupState.x + layerOffsetX + curi.x), - y: (curGroupState.y + layerOffsetY + curi.y), - alpha: (curGroupState.opacity * curi.opacity), - visible: (curGroupState.visible && curi.visible), - properties: GetFastValue(curi, 'properties', {}) - }); - } - - return images; -}; - -module.exports = ParseImageLayers; - - -/***/ }), -/* 550 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var ParseObject = __webpack_require__(254); -var ObjectLayer = __webpack_require__(552); -var CreateGroupLayer = __webpack_require__(158); - -/** - * Parses a Tiled JSON object into an array of ObjectLayer objects. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * - * @return {array} An array of all object layers in the tilemap as `ObjectLayer`s. - */ -var ParseObjectLayers = function (json) -{ - var objectLayers = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - // Get current layer and advance iterator - var curo = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - // Modify inherited properties - curo.opacity *= curGroupState.opacity; - curo.visible = curGroupState.visible && curo.visible; - - if (curo.type !== 'objectgroup') - { - if (curo.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curo, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - curo.name = curGroupState.name + curo.name; - var offsetX = curGroupState.x + GetFastValue(curo, 'startx', 0) + GetFastValue(curo, 'offsetx', 0); - var offsetY = curGroupState.y + GetFastValue(curo, 'starty', 0) + GetFastValue(curo, 'offsety', 0); - - var objects = []; - for (var j = 0; j < curo.objects.length; j++) - { - var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); - - objects.push(parsedObject); - } - - var objectLayer = new ObjectLayer(curo); - objectLayer.objects = objects; - - objectLayers.push(objectLayer); - } - - return objectLayers; -}; - -module.exports = ParseObjectLayers; - - -/***/ }), -/* 551 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var HasValue = __webpack_require__(125); - -/** - * Returns a new object that only contains the `keys` that were found on the object provided. - * If no `keys` are found, an empty object is returned. - * - * @function Phaser.Utils.Objects.Pick - * @since 3.18.0 - * - * @param {object} object - The object to pick the provided keys from. - * @param {array} keys - An array of properties to retrieve from the provided object. - * - * @return {object} A new object that only contains the `keys` that were found on the provided object. If no `keys` were found, an empty object will be returned. - */ -var Pick = function (object, keys) -{ - var obj = {}; - - for (var i = 0; i < keys.length; i++) - { - var key = keys[i]; - - if (HasValue(object, key)) - { - obj[key] = object[key]; - } - } - - return obj; -}; - -module.exports = Pick; - - -/***/ }), -/* 552 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * A class for representing a Tiled object layer in a map. This mirrors the structure of a Tiled - * object layer, except: - * - "x" & "y" properties are ignored since these cannot be changed in Tiled. - * - "offsetx" & "offsety" are applied to the individual object coordinates directly, so they - * are ignored as well. - * - "draworder" is ignored. - * - * @class ObjectLayer - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.Tilemaps.ObjectLayerConfig} [config] - The data for the layer from the Tiled JSON object. - */ -var ObjectLayer = new Class({ - - initialize: - - function ObjectLayer (config) - { - if (config === undefined) { config = {}; } - - /** - * The name of the Object Layer. - * - * @name Phaser.Tilemaps.ObjectLayer#name - * @type {string} - * @since 3.0.0 - */ - this.name = GetFastValue(config, 'name', 'object layer'); - - /** - * The opacity of the layer, between 0 and 1. - * - * @name Phaser.Tilemaps.ObjectLayer#opacity - * @type {number} - * @since 3.0.0 - */ - this.opacity = GetFastValue(config, 'opacity', 1); - - /** - * The custom properties defined on the Object Layer, keyed by their name. - * - * @name Phaser.Tilemaps.ObjectLayer#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = GetFastValue(config, 'properties', {}); - - /** - * The type of each custom property defined on the Object Layer, keyed by its name. - * - * @name Phaser.Tilemaps.ObjectLayer#propertyTypes - * @type {object} - * @since 3.0.0 - */ - this.propertyTypes = GetFastValue(config, 'propertytypes', {}); - - /** - * The type of the layer, which should be `objectgroup`. - * - * @name Phaser.Tilemaps.ObjectLayer#type - * @type {string} - * @since 3.0.0 - */ - this.type = GetFastValue(config, 'type', 'objectgroup'); - - /** - * Whether the layer is shown (`true`) or hidden (`false`). - * - * @name Phaser.Tilemaps.ObjectLayer#visible - * @type {boolean} - * @since 3.0.0 - */ - this.visible = GetFastValue(config, 'visible', true); - - /** - * An array of all objects on this Object Layer. - * - * Each Tiled object corresponds to a JavaScript object in this array. It has an `id` (unique), - * `name` (as assigned in Tiled), `type` (as assigned in Tiled), `rotation` (in clockwise degrees), - * `properties` (if any), `visible` state (`true` if visible, `false` otherwise), - * `x` and `y` coordinates (in pixels, relative to the tilemap), and a `width` and `height` (in pixels). - * - * An object tile has a `gid` property (GID of the represented tile), a `flippedHorizontal` property, - * a `flippedVertical` property, and `flippedAntiDiagonal` property. - * The {@link http://docs.mapeditor.org/en/latest/reference/tmx-map-format/|Tiled documentation} contains - * information on flipping and rotation. - * - * Polylines have a `polyline` property, which is an array of objects corresponding to points, - * where each point has an `x` property and a `y` property. Polygons have an identically structured - * array in their `polygon` property. Text objects have a `text` property with the text's properties. - * - * Rectangles and ellipses have a `rectangle` or `ellipse` property set to `true`. - * - * @name Phaser.Tilemaps.ObjectLayer#objects - * @type {Phaser.Types.Tilemaps.TiledObject[]} - * @since 3.0.0 - */ - this.objects = GetFastValue(config, 'objects', []); - } - -}); - -module.exports = ObjectLayer; - - -/***/ }), -/* 553 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Base64Decode = __webpack_require__(554); -var CONST = __webpack_require__(29); -var CreateGroupLayer = __webpack_require__(158); -var FromOrientationString = __webpack_require__(252); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(117); -var ParseGID = __webpack_require__(255); -var Tile = __webpack_require__(83); - -/** - * Parses all tilemap layers in a Tiled JSON object into new LayerData objects. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). - * - * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in - * json.layers with the type 'tilelayer'. - */ -var ParseTileLayers = function (json, insertNull) -{ - var infiniteMap = GetFastValue(json, 'infinite', false); - var tileLayers = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - var curl = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - if (curl.type !== 'tilelayer') - { - if (curl.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curl, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - // Base64 decode data if necessary. NOTE: uncompressed base64 only. - if (curl.compression) - { - console.warn( - 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' - + curl.name + '\'' - ); - continue; - } - else if (curl.encoding && curl.encoding === 'base64') - { - // Chunks for an infinite map - if (curl.chunks) - { - for (var i = 0; i < curl.chunks.length; i++) - { - curl.chunks[i].data = Base64Decode(curl.chunks[i].data); - } - } - - // Non-infinite map data - if (curl.data) - { - curl.data = Base64Decode(curl.data); - } - - delete curl.encoding; // Allow the same map to be parsed multiple times - } - - // This is an array containing the tile indexes, one after the other. -1 = no tile, - // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map - // contains multiple tilesets then the indexes are relative to that which the set starts - // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this - // manually it means you can use the same map data but a new tileset. - - var layerData; - var gidInfo; - var tile; - var blankTile; - - var output = []; - var x = 0; - - if (infiniteMap) - { - var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x); - var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y); - - layerData = new LayerData({ - name: (curGroupState.name + curl.name), - x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + layerOffsetX * json.tilewidth), - y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + layerOffsetY * json.tileheight), - width: curl.width, - height: curl.height, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - alpha: (curGroupState.opacity * curl.opacity), - visible: (curGroupState.visible && curl.visible), - properties: GetFastValue(curl, 'properties', []), - orientation: FromOrientationString(json.orientation) - }); - - if (layerData.orientation === CONST.HEXAGONAL) - { - layerData.hexSideLength = json.hexsidelength; - } - - for (var c = 0; c < curl.height; c++) - { - output.push([ null ]); - - for (var j = 0; j < curl.width; j++) - { - output[c][j] = null; - } - } - - for (c = 0, len = curl.chunks.length; c < len; c++) - { - var chunk = curl.chunks[c]; - - var offsetX = (chunk.x - layerOffsetX); - var offsetY = (chunk.y - layerOffsetY); - - var y = 0; - - for (var t = 0, len2 = chunk.data.length; t < len2; t++) - { - var newOffsetX = x + offsetX; - var newOffsetY = y + offsetY; - - gidInfo = ParseGID(chunk.data[t]); - - // index, x, y, width, height - if (gidInfo.gid > 0) - { - tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); - - // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal - // propeties into flipX, flipY and rotation - tile.rotation = gidInfo.rotation; - tile.flipX = gidInfo.flipped; - - output[newOffsetY][newOffsetX] = tile; - } - else - { - blankTile = insertNull - ? null - : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); - - output[newOffsetY][newOffsetX] = blankTile; - } - - x++; - - if (x === chunk.width) - { - y++; - x = 0; - } - } - } - } - else - { - layerData = new LayerData({ - name: (curGroupState.name + curl.name), - x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + curl.x), - y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + curl.y), - width: curl.width, - height: curl.height, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - alpha: (curGroupState.opacity * curl.opacity), - visible: (curGroupState.visible && curl.visible), - properties: GetFastValue(curl, 'properties', []), - orientation: FromOrientationString(json.orientation) - }); - - if (layerData.orientation === CONST.HEXAGONAL) - { - layerData.hexSideLength = json.hexsidelength; - } - var row = []; - - // Loop through the data field in the JSON. - for (var k = 0, len = curl.data.length; k < len; k++) - { - gidInfo = ParseGID(curl.data[k]); - - // index, x, y, width, height - if (gidInfo.gid > 0) - { - tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); - - // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal - // propeties into flipX, flipY and rotation - tile.rotation = gidInfo.rotation; - tile.flipX = gidInfo.flipped; - - row.push(tile); - } - else - { - blankTile = insertNull - ? null - : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); - row.push(blankTile); - } - - x++; - - if (x === curl.width) - { - output.push(row); - x = 0; - row = []; - } - } - } - - layerData.data = output; - tileLayers.push(layerData); - } - - return tileLayers; -}; - -module.exports = ParseTileLayers; - - -/***/ }), -/* 554 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Decode base-64 encoded data, for example as exported by Tiled. - * - * @function Phaser.Tilemaps.Parsers.Tiled.Base64Decode - * @since 3.0.0 - * - * @param {object} data - Base-64 encoded data to decode. - * - * @return {array} Array containing the decoded bytes. - */ -var Base64Decode = function (data) -{ - var binaryString = window.atob(data); - var len = binaryString.length; - var bytes = new Array(len / 4); - - // Interpret binaryString as an array of bytes representing little-endian encoded uint32 values. - for (var i = 0; i < len; i += 4) - { - bytes[i / 4] = ( - binaryString.charCodeAt(i) | - binaryString.charCodeAt(i + 1) << 8 | - binaryString.charCodeAt(i + 2) << 16 | - binaryString.charCodeAt(i + 3) << 24 - ) >>> 0; - } - - return bytes; -}; - -module.exports = Base64Decode; - - -/***/ }), -/* 555 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); -var ImageCollection = __webpack_require__(556); -var ParseObject = __webpack_require__(254); - -/** - * Tilesets and Image Collections - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseTilesets - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON data. - * - * @return {object} An object containing the tileset and image collection data. - */ -var ParseTilesets = function (json) -{ - var tilesets = []; - var imageCollections = []; - var lastSet = null; - var stringID; - - for (var i = 0; i < json.tilesets.length; i++) - { - // name, firstgid, width, height, margin, spacing, properties - var set = json.tilesets[i]; - - if (set.source) - { - console.warn('External tilesets unsupported. Use Embed Tileset and re-export'); - } - else if (set.image) - { - var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); - - if (json.version > 1) - { - // Tiled 1.2+ - - if (Array.isArray(set.tiles)) - { - var tiles = {}; - var props = {}; - - for (var t = 0; t < set.tiles.length; t++) - { - var tile = set.tiles[t]; - - // Convert tileproperties - if (tile.properties) - { - var newPropData = {}; - - tile.properties.forEach(function (propData) - { - newPropData[propData['name']] = propData['value']; - }); - - props[tile.id] = newPropData; - } - - // Convert objectgroup - if (tile.objectgroup) - { - tiles[tile.id] = { objectgroup: tile.objectgroup }; - - if (tile.objectgroup.objects) - { - var parsedObjects2 = tile.objectgroup.objects.map(function (obj) - { - return ParseObject(obj); - }); - - tiles[tile.id].objectgroup.objects = parsedObjects2; - } - } - - // Copy animation data - if (tile.animation) - { - if (tiles.hasOwnProperty(tile.id)) - { - tiles[tile.id].animation = tile.animation; - } - else - { - tiles[tile.id] = { animation: tile.animation }; - } - } - } - - newSet.tileData = tiles; - newSet.tileProperties = props; - } - } - else - { - // Tiled 1 - - // Properties stored per-tile in object with string indexes starting at "0" - if (set.tileproperties) - { - newSet.tileProperties = set.tileproperties; - } - - // Object & terrain shapes stored per-tile in object with string indexes starting at "0" - if (set.tiles) - { - newSet.tileData = set.tiles; - - // Parse the objects into Phaser format to match handling of other Tiled objects - for (stringID in newSet.tileData) - { - var objectGroup = newSet.tileData[stringID].objectgroup; - - if (objectGroup && objectGroup.objects) - { - var parsedObjects1 = objectGroup.objects.map(function (obj) - { - return ParseObject(obj); - }); - - newSet.tileData[stringID].objectgroup.objects = parsedObjects1; - } - } - } - } - - // For a normal sliced tileset the row/count/size information is computed when updated. - // This is done (again) after the image is set. - newSet.updateTileData(set.imagewidth, set.imageheight); - - tilesets.push(newSet); - } - else - { - var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); - - var maxId = 0; - - for (t = 0; t < set.tiles.length; t++) - { - tile = set.tiles[t]; - - var image = tile.image; - var tileId = parseInt(tile.id, 10); - var gid = set.firstgid + tileId; - newCollection.addImage(gid, image); - - maxId = Math.max(tileId, maxId); - } - - newCollection.maxId = maxId; - - imageCollections.push(newCollection); - } - - // We've got a new Tileset, so set the lastgid into the previous one - if (lastSet) - { - lastSet.lastgid = set.firstgid - 1; - } - - lastSet = set; - } - - return { tilesets: tilesets, imageCollections: imageCollections }; -}; - -module.exports = ParseTilesets; - - -/***/ }), -/* 556 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * An Image Collection is a special Tile Set containing multiple images, with no slicing into each image. - * - * Image Collections are normally created automatically when Tiled data is loaded. - * - * @class ImageCollection - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {string} name - The name of the image collection in the map data. - * @param {number} firstgid - The first image index this image collection contains. - * @param {number} [width=32] - Width of widest image (in pixels). - * @param {number} [height=32] - Height of tallest image (in pixels). - * @param {number} [margin=0] - The margin around all images in the collection (in pixels). - * @param {number} [spacing=0] - The spacing between each image in the collection (in pixels). - * @param {object} [properties={}] - Custom Image Collection properties. - */ -var ImageCollection = new Class({ - - initialize: - - function ImageCollection (name, firstgid, width, height, margin, spacing, properties) - { - if (width === undefined || width <= 0) { width = 32; } - if (height === undefined || height <= 0) { height = 32; } - if (margin === undefined) { margin = 0; } - if (spacing === undefined) { spacing = 0; } - - /** - * The name of the Image Collection. - * - * @name Phaser.Tilemaps.ImageCollection#name - * @type {string} - * @since 3.0.0 - */ - this.name = name; - - /** - * The Tiled firstgid value. - * This is the starting index of the first image index this Image Collection contains. - * - * @name Phaser.Tilemaps.ImageCollection#firstgid - * @type {number} - * @since 3.0.0 - */ - this.firstgid = firstgid | 0; - - /** - * The width of the widest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageWidth - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageWidth = width | 0; - - /** - * The height of the tallest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageHeight - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageHeight = height | 0; - - /** - * The margin around the images in the collection (in pixels). - * Use `setSpacing` to change. - * - * @name Phaser.Tilemaps.ImageCollection#imageMarge - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageMargin = margin | 0; - - /** - * The spacing between each image in the collection (in pixels). - * Use `setSpacing` to change. - * - * @name Phaser.Tilemaps.ImageCollection#imageSpacing - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageSpacing = spacing | 0; - - /** - * Image Collection-specific properties that are typically defined in the Tiled editor. - * - * @name Phaser.Tilemaps.ImageCollection#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = properties || {}; - - /** - * The cached images that are a part of this collection. - * - * @name Phaser.Tilemaps.ImageCollection#images - * @type {array} - * @readonly - * @since 3.0.0 - */ - this.images = []; - - /** - * The total number of images in the image collection. - * - * @name Phaser.Tilemaps.ImageCollection#total - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.total = 0; - }, - - /** - * Returns true if and only if this image collection contains the given image index. - * - * @method Phaser.Tilemaps.ImageCollection#containsImageIndex - * @since 3.0.0 - * - * @param {number} imageIndex - The image index to search for. - * - * @return {boolean} True if this Image Collection contains the given index. - */ - containsImageIndex: function (imageIndex) - { - return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); - }, - - /** - * Add an image to this Image Collection. - * - * @method Phaser.Tilemaps.ImageCollection#addImage - * @since 3.0.0 - * - * @param {number} gid - The gid of the image in the Image Collection. - * @param {string} image - The the key of the image in the Image Collection and in the cache. - * - * @return {Phaser.Tilemaps.ImageCollection} This ImageCollection object. - */ - addImage: function (gid, image) - { - this.images.push({ gid: gid, image: image }); - this.total++; - - return this; - } - -}); - -module.exports = ImageCollection; - - -/***/ }), -/* 557 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var MapData = __webpack_require__(118); -var ParseTileLayers = __webpack_require__(558); -var ParseTilesets = __webpack_require__(559); - -/** - * Parses a Weltmeister JSON object into a new MapData object. - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {object} json - The Weltmeister JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. - */ -var ParseWeltmeister = function (name, json, insertNull) -{ - if (json.layer.length === 0) - { - console.warn('No layers found in the Weltmeister map: ' + name); - return null; - } - - var width = 0; - var height = 0; - - for (var i = 0; i < json.layer.length; i++) - { - if (json.layer[i].width > width) { width = json.layer[i].width; } - if (json.layer[i].height > height) { height = json.layer[i].height; } - } - - var mapData = new MapData({ - width: width, - height: height, - name: name, - tileWidth: json.layer[0].tilesize, - tileHeight: json.layer[0].tilesize, - format: Formats.WELTMEISTER - }); - - mapData.layers = ParseTileLayers(json, insertNull); - mapData.tilesets = ParseTilesets(json); - - return mapData; -}; - -module.exports = ParseWeltmeister; - - -/***/ }), -/* 558 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LayerData = __webpack_require__(117); -var Tile = __webpack_require__(83); - -/** - * Parses all tilemap layers in an Impact JSON object into new LayerData objects. - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers - * @since 3.0.0 - * - * @param {object} json - The Impact JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). - * - * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in - * json.layers with the type 'tilelayer'. - */ -var ParseTileLayers = function (json, insertNull) -{ - var tileLayers = []; - - for (var i = 0; i < json.layer.length; i++) - { - var layer = json.layer[i]; - - var layerData = new LayerData({ - name: layer.name, - width: layer.width, - height: layer.height, - tileWidth: layer.tilesize, - tileHeight: layer.tilesize, - visible: layer.visible === 1 - }); - - var row = []; - var tileGrid = []; - - // Loop through the data field in the JSON. This is a 2D array containing the tile indexes, - // one after the other. The indexes are relative to the tileset that contains the tile. - for (var y = 0; y < layer.data.length; y++) - { - for (var x = 0; x < layer.data[y].length; x++) - { - // In Weltmeister, 0 = no tile, but the Tilemap API expects -1 = no tile. - var index = layer.data[y][x] - 1; - - var tile; - - if (index > -1) - { - tile = new Tile(layerData, index, x, y, layer.tilesize, layer.tilesize); - } - else - { - tile = insertNull - ? null - : new Tile(layerData, -1, x, y, layer.tilesize, layer.tilesize); - } - - row.push(tile); - } - - tileGrid.push(row); - row = []; - } - - layerData.data = tileGrid; - - tileLayers.push(layerData); - } - - return tileLayers; -}; - -module.exports = ParseTileLayers; - - -/***/ }), -/* 559 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); - -/** - * Tilesets and Image Collections - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTilesets - * @since 3.0.0 - * - * @param {object} json - The Impact JSON data. - * - * @return {array} An array of Tilesets. - */ -var ParseTilesets = function (json) -{ - var tilesets = []; - var tilesetsNames = []; - - for (var i = 0; i < json.layer.length; i++) - { - var layer = json.layer[i]; - - // A relative filepath to the source image (within Weltmeister) is used for the name - var tilesetName = layer.tilesetName; - - // Only add unique tilesets that have a valid name. Collision layers will have a blank name. - if (tilesetName !== '' && tilesetsNames.indexOf(tilesetName) === -1) - { - tilesetsNames.push(tilesetName); - - // Tiles are stored with an ID relative to the tileset, rather than a globally unique ID - // across all tilesets. Also, tilesets in Weltmeister have no margin or padding. - tilesets.push(new Tileset(tilesetName, 0, layer.tilesize, layer.tilesize, 0, 0)); - } - } - - return tilesets; -}; - -module.exports = ParseTilesets; - - -/***/ }), -/* 560 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var Formats = __webpack_require__(37); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(117); -var ORIENTATION = __webpack_require__(29); -var Rotate = __webpack_require__(356); -var SpliceOne = __webpack_require__(74); -var Sprite = __webpack_require__(73); -var Tile = __webpack_require__(83); -var TilemapComponents = __webpack_require__(245); -var TilemapLayer = __webpack_require__(561); -var Tileset = __webpack_require__(119); - -/** - * @callback TilemapFilterCallback - * - * @param {Phaser.GameObjects.GameObject} value - An object found in the filtered area. - * @param {number} index - The index of the object within the array. - * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. - * - * @return {Phaser.GameObjects.GameObject} The object. - */ - -/** - * @callback TilemapFindCallback - * - * @param {Phaser.GameObjects.GameObject} value - An object found. - * @param {number} index - The index of the object within the array. - * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. - * - * @return {boolean} `true` if the callback should be invoked, otherwise `false`. - */ - -/** - * @classdesc - * A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data - * about the map and allows you to add tilesets and tilemap layers to it. A map can have one or - * more tilemap layers, which are the display objects that actually render the tiles. - * - * The Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free - * software package specifically for creating tile maps, and is available from: - * http://www.mapeditor.org - * - * As of Phaser 3.50.0 the Tilemap API now supports the following types of map: - * - * 1) Orthogonal - * 2) Isometric - * 3) Hexagonal - * 4) Staggered - * - * Prior to this release, only orthogonal maps were supported. - * - * Another large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created - * either a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been - * merged and the API simplified, so now there is just the single `TilemapLayer` class. - * - * A Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing - * you to build or modify the tilemap data at runtime. - * - * Note that all Tilemaps use a base tile size to calculate dimensions from, but that a - * TilemapLayer may have its own unique tile size that overrides this. - * - * As of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these - * will be traversed and the following properties will impact children: - * - * - Opacity (blended with parent) and visibility (parent overrides child) - * - Vertical and horizontal offset - * - * The grouping hierarchy is not preserved and all layers will be flattened into a single array. - * - * Group layers are parsed during Tilemap construction but are discarded after parsing so dynamic - * layers will NOT continue to be affected by a parent. - * - * To avoid duplicate layer names, a layer that is a child of a group layer will have its parent - * group name prepended with a '/'. For example, consider a group called 'ParentGroup' with a - * child called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name - * 'ParentGroup/Layer 1'. - * - * @class Tilemap - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. - * @param {Phaser.Tilemaps.MapData} mapData - A MapData instance containing Tilemap data. - */ -var Tilemap = new Class({ - - initialize: - - function Tilemap (scene, mapData) - { - /** - * @name Phaser.Tilemaps.Tilemap#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * The base width of a tile in pixels. Note that individual layers may have a different tile - * width. - * - * @name Phaser.Tilemaps.Tilemap#tileWidth - * @type {number} - * @since 3.0.0 - */ - this.tileWidth = mapData.tileWidth; - - /** - * The base height of a tile in pixels. Note that individual layers may have a different - * tile height. - * - * @name Phaser.Tilemaps.Tilemap#tileHeight - * @type {number} - * @since 3.0.0 - */ - this.tileHeight = mapData.tileHeight; - - /** - * The width of the map (in tiles). - * - * @name Phaser.Tilemaps.Tilemap#width - * @type {number} - * @since 3.0.0 - */ - this.width = mapData.width; - - /** - * The height of the map (in tiles). - * - * @name Phaser.Tilemaps.Tilemap#height - * @type {number} - * @since 3.0.0 - */ - this.height = mapData.height; - - /** - * The orientation of the map data (as specified in Tiled), usually 'orthogonal'. - * - * @name Phaser.Tilemaps.Tilemap#orientation - * @type {string} - * @since 3.0.0 - */ - this.orientation = mapData.orientation; - - /** - * The render (draw) order of the map data (as specified in Tiled), usually 'right-down'. - * - * The draw orders are: - * - * right-down - * left-down - * right-up - * left-up - * - * This can be changed via the `setRenderOrder` method. - * - * @name Phaser.Tilemaps.Tilemap#renderOrder - * @type {string} - * @since 3.12.0 - */ - this.renderOrder = mapData.renderOrder; - - /** - * The format of the map data. - * - * @name Phaser.Tilemaps.Tilemap#format - * @type {number} - * @since 3.0.0 - */ - this.format = mapData.format; - - /** - * The version of the map data (as specified in Tiled, usually 1). - * - * @name Phaser.Tilemaps.Tilemap#version - * @type {number} - * @since 3.0.0 - */ - this.version = mapData.version; - - /** - * Map specific properties as specified in Tiled. - * - * @name Phaser.Tilemaps.Tilemap#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = mapData.properties; - - /** - * The width of the map in pixels based on width * tileWidth. - * - * @name Phaser.Tilemaps.Tilemap#widthInPixels - * @type {number} - * @since 3.0.0 - */ - this.widthInPixels = mapData.widthInPixels; - - /** - * The height of the map in pixels based on height * tileHeight. - * - * @name Phaser.Tilemaps.Tilemap#heightInPixels - * @type {number} - * @since 3.0.0 - */ - this.heightInPixels = mapData.heightInPixels; - - /** - * A collection of Images, as parsed from Tiled map data. - * - * @name Phaser.Tilemaps.Tilemap#imageCollections - * @type {Phaser.Tilemaps.ImageCollection[]} - * @since 3.0.0 - */ - this.imageCollections = mapData.imageCollections; - - /** - * An array of Tiled Image Layers. - * - * @name Phaser.Tilemaps.Tilemap#images - * @type {array} - * @since 3.0.0 - */ - this.images = mapData.images; - - /** - * An array of Tilemap layer data. - * - * @name Phaser.Tilemaps.Tilemap#layers - * @type {Phaser.Tilemaps.LayerData[]} - * @since 3.0.0 - */ - this.layers = mapData.layers; - - /** - * An array of Tilesets used in the map. - * - * @name Phaser.Tilemaps.Tilemap#tilesets - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.0.0 - */ - this.tilesets = mapData.tilesets; - - /** - * An array of ObjectLayer instances parsed from Tiled object layers. - * - * @name Phaser.Tilemaps.Tilemap#objects - * @type {Phaser.Tilemaps.ObjectLayer[]} - * @since 3.0.0 - */ - this.objects = mapData.objects; - - /** - * The index of the currently selected LayerData object. - * - * @name Phaser.Tilemaps.Tilemap#currentLayerIndex - * @type {number} - * @since 3.0.0 - */ - this.currentLayerIndex = 0; - - /** - * The length of the horizontal sides of the hexagon. - * Only used for hexagonal orientation Tilemaps. - * - * @name Phaser.Tilemaps.Tilemap#hexSideLength - * @type {number} - * @since 3.50.0 - */ - this.hexSideLength = mapData.hexSideLength; - - var orientation = this.orientation; - - /** - * Functions used to handle world to tile, and tile to world, conversion. - * Cached here for internal use by public methods such as `worldToTileXY`, etc. - * - * @name Phaser.Tilemaps.Tilemap#_convert - * @private - * @type {object} - * @since 3.50.0 - */ - this._convert = { - WorldToTileXY: TilemapComponents.GetWorldToTileXYFunction(orientation), - WorldToTileX: TilemapComponents.GetWorldToTileXFunction(orientation), - WorldToTileY: TilemapComponents.GetWorldToTileYFunction(orientation), - TileToWorldXY: TilemapComponents.GetTileToWorldXYFunction(orientation), - TileToWorldX: TilemapComponents.GetTileToWorldXFunction(orientation), - TileToWorldY: TilemapComponents.GetTileToWorldYFunction(orientation) - }; - }, - - /** - * @ignore - */ - createBlankDynamicLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) - { - console.warn('createBlankDynamicLayer is deprecated. Use createBlankLayer'); - - return this.createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight); - }, - - /** - * @ignore - */ - createDynamicLayer: function (layerID, tileset, x, y) - { - console.warn('createDynamicLayer is deprecated. Use createLayer'); - - return this.createLayer(layerID, tileset, x, y); - }, - - /** - * @ignore - */ - createStaticLayer: function (layerID, tileset, x, y) - { - console.warn('createStaticLayer is deprecated. Use createLayer'); - - return this.createLayer(layerID, tileset, x, y); - }, - - /** - * Sets the rendering (draw) order of the tiles in this map. - * - * The default is 'right-down', meaning it will order the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * Setting the render order does not change the tiles or how they are stored in the layer, - * it purely impacts the order in which they are rendered. - * - * You can provide either an integer (0 to 3), or the string version of the order. - * - * Calling this method _after_ creating Tilemap Layers will **not** automatically - * update them to use the new render order. If you call this method after creating layers, use their - * own `setRenderOrder` methods to change them as needed. - * - * @method Phaser.Tilemaps.Tilemap#setRenderOrder - * @since 3.12.0 - * - * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. - * - * @return {this} This Tilemap object. - */ - setRenderOrder: function (renderOrder) - { - var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; - - if (typeof renderOrder === 'number') - { - renderOrder = orders[renderOrder]; - } - - if (orders.indexOf(renderOrder) > -1) - { - this.renderOrder = renderOrder; - } - - return this; - }, - - /** - * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. - * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled - * editor. - * - * @method Phaser.Tilemaps.Tilemap#addTilesetImage - * @since 3.0.0 - * - * @param {string} tilesetName - The name of the tileset as specified in the map data. - * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If - * `undefined` or `null` it will look for an image with a key matching the tilesetName parameter. - * @param {number} [tileWidth] - The width of the tile (in pixels) in the Tileset Image. If not - * given it will default to the map's tileWidth value, or the tileWidth specified in the Tiled - * JSON file. - * @param {number} [tileHeight] - The height of the tiles (in pixels) in the Tileset Image. If - * not given it will default to the map's tileHeight value, or the tileHeight specified in the - * Tiled JSON file. - * @param {number} [tileMargin] - The margin around the tiles in the sheet (in pixels). If not - * specified, it will default to 0 or the value specified in the Tiled JSON file. - * @param {number} [tileSpacing] - The spacing between each the tile in the sheet (in pixels). - * If not specified, it will default to 0 or the value specified in the Tiled JSON file. - * @param {number} [gid=0] - If adding multiple tilesets to a blank map, specify the starting - * GID this set will use here. - * - * @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it - * failed. - */ - addTilesetImage: function (tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid) - { - if (tilesetName === undefined) { return null; } - if (key === undefined || key === null) { key = tilesetName; } - - if (!this.scene.sys.textures.exists(key)) - { - console.warn('Invalid Tileset Image: ' + key); - return null; - } - - var texture = this.scene.sys.textures.get(key); - - var index = this.getTilesetIndex(tilesetName); - - if (index === null && this.format === Formats.TILED_JSON) - { - console.warn('No data found for Tileset: ' + tilesetName); - return null; - } - - var tileset = this.tilesets[index]; - - if (tileset) - { - tileset.setTileSize(tileWidth, tileHeight); - tileset.setSpacing(tileMargin, tileSpacing); - tileset.setImage(texture); - - return tileset; - } - - if (tileWidth === undefined) { tileWidth = this.tileWidth; } - if (tileHeight === undefined) { tileHeight = this.tileHeight; } - if (tileMargin === undefined) { tileMargin = 0; } - if (tileSpacing === undefined) { tileSpacing = 0; } - if (gid === undefined) { gid = 0; } - - tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing); - - tileset.setImage(texture); - - this.tilesets.push(tileset); - - return tileset; - }, - - /** - * Copies the tiles in the source rectangular area to a new destination (all specified in tile - * coordinates) within the layer. This copies all tile properties & recalculates collision - * information in the destination region. - * - * If no layer specified, the map's current layer is used. This cannot be applied to StaticTilemapLayers. - * - * @method Phaser.Tilemaps.Tilemap#copy - * @since 3.0.0 - * - * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. - * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. - * @param {number} width - The width of the area to copy, in tiles, not pixels. - * @param {number} height - The height of the area to copy, in tiles, not pixels. - * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. - * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) - { - layer = this.getLayer(layer); - - if (layer !== null) - { - TilemapComponents.Copy( - srcTileX, srcTileY, - width, height, - destTileX, destTileY, - recalculateFaces, layer - ); - - return this; - } - else - { - return null; - } - }, - - /** - * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. - * - * Prior to v3.50.0 this method was called `createBlankDynamicLayer`. - * - * @method Phaser.Tilemaps.Tilemap#createBlankLayer - * @since 3.0.0 - * - * @param {string} name - The name of this layer. Must be unique within the map. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The world x position where the top left of this layer will be placed. - * @param {number} [y=0] - The world y position where the top left of this layer will be placed. - * @param {number} [width] - The width of the layer in tiles. If not specified, it will default to the map's width. - * @param {number} [height] - The height of the layer in tiles. If not specified, it will default to the map's height. - * @param {number} [tileWidth] - The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth. - * @param {number} [tileHeight] - The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight. - * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed. - */ - createBlankLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } - if (tileWidth === undefined) { tileWidth = this.tileWidth; } - if (tileHeight === undefined) { tileHeight = this.tileHeight; } - - var index = this.getLayerIndex(name); - - if (index !== null) - { - console.warn('Invalid Tilemap Layer ID: ' + name); - return null; - } - - var layerData = new LayerData({ - name: name, - tileWidth: tileWidth, - tileHeight: tileHeight, - width: width, - height: height, - orientation: this.orientation - }); - - var row; - - for (var tileY = 0; tileY < height; tileY++) - { - row = []; - - for (var tileX = 0; tileX < width; tileX++) - { - row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight)); - } - - layerData.data.push(row); - } - - this.layers.push(layerData); - - this.currentLayerIndex = this.layers.length - 1; - - var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y); - - layer.setRenderOrder(this.renderOrder); - - this.scene.sys.displayList.add(layer); - - return layer; - }, - - /** - * Creates a new Tilemap Layer that renders the LayerData associated with the given - * `layerID`. The currently selected layer in the map is set to this new layer. - * - * The `layerID` is important. If you've created your map in Tiled then you can get this by - * looking in Tiled and looking at the layer name. Or you can open the JSON file it exports and - * look at the layers[].name value. Either way it must match. - * - * Prior to v3.50.0 this method was called `createDynamicLayer`. - * - * @method Phaser.Tilemaps.Tilemap#createLayer - * @since 3.0.0 - * - * @param {(number|string)} layerID - The layer array index value, or if a string is given, the layer name from Tiled. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. - * @param {number} [y=0] - The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. - * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed. - */ - createLayer: function (layerID, tileset, x, y) - { - var index = this.getLayerIndex(layerID); - - if (index === null) - { - console.warn('Invalid Tilemap Layer ID: ' + layerID); - - if (typeof layerID === 'string') - { - console.warn('Valid tilelayer names:\n\t' + this.getTileLayerNames().join(',\n\t')); - } - - return null; - } - - var layerData = this.layers[index]; - - // Check for an associated static or dynamic tilemap layer - if (layerData.tilemapLayer) - { - console.warn('Tilemap Layer ID already exists:' + layerID); - return null; - } - - this.currentLayerIndex = index; - - // Default the x/y position to match Tiled layer offset, if it exists. - - if (x === undefined) - { - x = layerData.x; - } - - if (y === undefined) - { - y = layerData.y; - } - - var layer = new TilemapLayer(this.scene, this, index, tileset, x, y); - - layer.setRenderOrder(this.renderOrder); - - this.scene.sys.displayList.add(layer); - - return layer; - }, - - /** - * This method will iterate through all of the objects defined in a Tiled Object Layer and then - * convert the matching results into Phaser Game Objects (by default, Sprites) - * - * Objects are matched on one of 3 criteria: The Object ID, the Object GID or the Object Name. - * - * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects - * using the same image. Finally, Object Names are strings and the same name can be used on multiple - * Objects in Tiled, they do not have to be unique. - * - * You set the configuration parameter accordingly, based on which type of criteria you wish - * to match against. For example, to convert all items on an Object Layer with a `gid` of 26: - * - * ```javascript - * createFromObjects(layerName, { - * gid: 26 - * }); - * ``` - * - * Or, to convert objects with the name 'bonus': - * - * ```javascript - * createFromObjects(layerName, { - * name: 'bonus' - * }); - * ``` - * - * Or, to convert an object with a specific id: - * - * ```javascript - * createFromObjects(layerName, { - * id: 9 - * }); - * ``` - * - * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than - * one criteria to your config. If you do not specify any criteria, then _all_ objects in the - * Object Layer will be converted. - * - * By default this method will convert objects into `Sprite` instances, but you can override - * this by providing your own class type: - * - * ```javascript - * createFromObjects(layerName, { - * gid: 26, - * classType: Coin - * }); - * ``` - * - * This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass - * any class type here, but it _must_ extend `Phaser.GameObjects.GameObject` as its base class. - * Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene - * specified in the config object or, if not given, the Scene to which this Tilemap belongs. - * - * All properties from object are copied into the Game Object, so you can use this as an easy - * way to configure properties from within the map editor. For example giving an object a - * property of `alpha: 0.5` in Tiled will be reflected in the Game Object that is created. - * - * Custom object properties that do not exist as a Game Object property are set in the - * Game Objects {@link Phaser.GameObjects.GameObject#data data store}. - * - * You can use set a `container` property in the config. If given, the class will be added to - * the Container instance instead of the Scene. - * - * Finally, you can provide an array of config objects, to convert multiple types of object in - * a single call: - * - * ```javascript - * createFromObjects(layerName, [ - * { - * gid: 26, - * classType: Coin - * }, - * { - * id: 9, - * classType: BossMonster - * }, - * { - * name: 'lava', - * classType: LavaTile - * } - * ]); - * ``` - * - * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. - * - * @method Phaser.Tilemaps.Tilemap#createFromObjects - * @since 3.0.0 - * - * @param {string} objectLayerName - The name of the Tiled object layer to create the Game Objects from. - * @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]} config - A CreateFromObjects configuration object, or an array of them. - * - * @return {Phaser.GameObjects.GameObject[]} An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found. - */ - createFromObjects: function (objectLayerName, config) - { - var results = []; - - var objectLayer = this.getObjectLayer(objectLayerName); - - if (!objectLayer) - { - console.warn('createFromObjects: Invalid objectLayerName given: ' + objectLayerName); - - return results; - } - - if (!Array.isArray(config)) - { - config = [ config ]; - } - - var objects = objectLayer.objects; - - for (var c = 0; c < config.length; c++) - { - var singleConfig = config[c]; - - var id = GetFastValue(singleConfig, 'id', null); - var gid = GetFastValue(singleConfig, 'gid', null); - var name = GetFastValue(singleConfig, 'name', null); - - var obj; - var toConvert = []; - - // Sweep to get all the objects we want to convert in this pass - for (var s = 0; s < objects.length; s++) - { - obj = objects[s]; - - if ( - (id === null && gid === null && name === null) || - (id !== null && obj.id === id) || - (gid !== null && obj.gid === gid) || - (name !== null && obj.name === name) - ) - { - toConvert.push(obj); - } - } - - // Now let's convert them ... - - var classType = GetFastValue(singleConfig, 'classType', Sprite); - var scene = GetFastValue(singleConfig, 'scene', this.scene); - var container = GetFastValue(singleConfig, 'container', null); - var texture = GetFastValue(singleConfig, 'key', null); - var frame = GetFastValue(singleConfig, 'frame', null); - - for (var i = 0; i < toConvert.length; i++) - { - obj = toConvert[i]; - - var sprite = new classType(scene); - - sprite.setName(obj.name); - sprite.setPosition(obj.x, obj.y); - sprite.setTexture(texture, frame); - - if (obj.width) - { - sprite.displayWidth = obj.width; - } - - if (obj.height) - { - sprite.displayHeight = obj.height; - } - - // Origin is (0, 1) in Tiled, so find the offset that matches the Sprites origin. - // Do not offset objects with zero dimensions (e.g. points). - var offset = { - x: sprite.originX * obj.width, - y: (sprite.originY - 1) * obj.height - }; - - // If the object is rotated, then the origin offset also needs to be rotated. - if (obj.rotation) - { - var angle = DegToRad(obj.rotation); - - Rotate(offset, angle); - - sprite.rotation = angle; - } - - sprite.x += offset.x; - sprite.y += offset.y; - - if (obj.flippedHorizontal !== undefined || obj.flippedVertical !== undefined) - { - sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical); - } - - if (!obj.visible) - { - sprite.visible = false; - } - - // Set properties the class may have, or setData those it doesn't - for (var key in obj.properties) - { - if (sprite[key] !== undefined) - { - sprite[key] = obj.properties[key]; - } - else - { - sprite.setData(key, obj.properties[key]); - } - } - - if (container) - { - container.add(sprite); - } - else - { - scene.add.existing(sprite); - } - - results.push(sprite); - } - } - - return results; - }, - - /** - * Creates a Sprite for every object matching the given tile indexes in the layer. You can - * optionally specify if each tile will be replaced with a new tile after the Sprite has been - * created. This is useful if you want to lay down special tiles in a level that are converted to - * Sprites, but want to replace the tile itself with a floor tile or similar once converted. - * - * @method Phaser.Tilemaps.Tilemap#createFromTiles - * @since 3.0.0 - * - * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. - * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted - * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a - * one-to-one mapping with the indexes array. - * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} spriteConfig - The config object to pass into the Sprite creator (i.e. scene.make.sprite). - * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.GameObjects.Sprite[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); - }, - - /** - * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the - * specified index. Tiles will be set to collide if the given index is a colliding index. - * Collision information in the region will be recalculated. - * - * If no layer specified, the map's current layer is used. - * This cannot be applied to StaticTilemapLayers. - * - * @method Phaser.Tilemaps.Tilemap#fill - * @since 3.0.0 - * - * @param {number} index - The tile index to fill the area with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); - - return this; - }, - - /** - * For each object in the given object layer, run the given filter callback function. Any - * objects that pass the filter test (i.e. where the callback returns true) will returned as a - * new array. Similar to Array.prototype.Filter in vanilla JS. - * - * @method Phaser.Tilemaps.Tilemap#filterObjects - * @since 3.0.0 - * - * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. - * @param {TilemapFilterCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * - * @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid. - */ - filterObjects: function (objectLayer, callback, context) - { - if (typeof objectLayer === 'string') - { - var name = objectLayer; - - objectLayer = this.getObjectLayer(objectLayer); - - if (!objectLayer) - { - console.warn('No object layer found with the name: ' + name); - return null; - } - } - - return objectLayer.objects.filter(callback, context); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns - * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#filterTiles - * @since 3.0.0 - * - * @param {function} callback - The callback. Each tile in the given area will be passed to this - * callback as the first and only parameter. The callback should return true for tiles that pass the - * filter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * Searches the entire map layer for the first tile matching the given index, then returns that Tile - * object. If no match is found, it returns null. The search starts from the top-left tile and - * continues horizontally until it hits the end of the row, then it drops down to the next column. - * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to - * the top-left. - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#findByIndex - * @since 3.0.0 - * - * @param {number} index - The tile index value to search for. - * @param {number} [skip=0] - The number of times to skip a matching tile before returning. - * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. - */ - findByIndex: function (findIndex, skip, reverse, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); - }, - - /** - * Find the first object in the given object layer that satisfies the provided testing function. - * I.e. finds the first object for which `callback` returns true. Similar to - * Array.prototype.find in vanilla JS. - * - * @method Phaser.Tilemaps.Tilemap#findObject - * @since 3.0.0 - * - * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. - * @param {TilemapFindCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * - * @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found. - */ - findObject: function (objectLayer, callback, context) - { - if (typeof objectLayer === 'string') - { - var name = objectLayer; - - objectLayer = this.getObjectLayer(objectLayer); - - if (!objectLayer) - { - console.warn('No object layer found with the name: ' + name); - return null; - } - } - - return objectLayer.objects.find(callback, context) || null; - }, - - /** - * Find the first tile in the given rectangular area (in tile coordinates) of the layer that - * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns - * true. Similar to Array.prototype.find in vanilla JS. - * If no layer specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#findTile - * @since 3.0.0 - * - * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. - */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * callback. Similar to Array.prototype.forEach in vanilla JS. - * - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#forEachTile - * @since 3.0.0 - * - * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); - - return this; - }, - - /** - * Gets the image layer index based on its name. - * - * @method Phaser.Tilemaps.Tilemap#getImageIndex - * @since 3.0.0 - * - * @param {string} name - The name of the image to get. - * - * @return {number} The index of the image in this tilemap, or null if not found. - */ - getImageIndex: function (name) - { - return this.getIndex(this.images, name); - }, - - /** - * Return a list of all valid imagelayer names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getImageLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap. - */ - getImageLayerNames: function () - { - if (!this.images || !Array.isArray(this.images)) - { - return []; - } - - return this.images.map(function (image) - { - return image.name; - }); - }, - - /** - * Internally used. Returns the index of the object in one of the Tilemaps arrays whose name - * property matches the given `name`. - * - * @method Phaser.Tilemaps.Tilemap#getIndex - * @since 3.0.0 - * - * @param {array} location - The Tilemap array to search. - * @param {string} name - The name of the array element to get. - * - * @return {number} The index of the element in the array, or null if not found. - */ - getIndex: function (location, name) - { - for (var i = 0; i < location.length; i++) - { - if (location[i].name === name) - { - return i; - } - } - - return null; - }, - - /** - * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. - * - * @method Phaser.Tilemaps.Tilemap#getLayer - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or Tilemap Layer. If not given will default to the maps current layer index. - * - * @return {Phaser.Tilemaps.LayerData} The corresponding LayerData within this.layers. - */ - getLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - return (index !== null) ? this.layers[index] : null; - }, - - /** - * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. - * - * @method Phaser.Tilemaps.Tilemap#getObjectLayer - * @since 3.0.0 - * - * @param {string} [name] - The name of the object layer from Tiled. - * - * @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null. - */ - getObjectLayer: function (name) - { - var index = this.getIndex(this.objects, name); - - return (index !== null) ? this.objects[index] : null; - }, - - /** - * Return a list of all valid objectgroup names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getObjectLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap. - */ - getObjectLayerNames: function () - { - if (!this.objects || !Array.isArray(this.objects)) - { - return []; - } - - return this.objects.map(function (object) - { - return object.name; - }); - }, - - /** - * Gets the LayerData index of the given `layer` within this.layers, or null if an invalid - * `layer` is given. - * - * @method Phaser.Tilemaps.Tilemap#getLayerIndex - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a Tilemap Layer. If not given will default to the map's current layer index. - * - * @return {number} The LayerData index within this.layers. - */ - getLayerIndex: function (layer) - { - if (layer === undefined) - { - return this.currentLayerIndex; - } - else if (typeof layer === 'string') - { - return this.getLayerIndexByName(layer); - } - else if (typeof layer === 'number' && layer < this.layers.length) - { - return layer; - } - else if (layer instanceof TilemapLayer) - { - return layer.layerIndex; - } - else - { - return null; - } - }, - - /** - * Gets the index of the LayerData within this.layers that has the given `name`, or null if an - * invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getLayerIndexByName - * @since 3.0.0 - * - * @param {string} name - The name of the layer to get. - * - * @return {number} The LayerData index within this.layers. - */ - getLayerIndexByName: function (name) - { - return this.getIndex(this.layers, name); - }, - - /** - * Gets a tile at the given tile coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTileAt - * @since 3.0.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {boolean} [nonNull] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - getTileAt: function (tileX, tileY, nonNull, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); - }, - - /** - * Gets a tile at the given world coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - X position to get the tile from (given in pixels) - * @param {number} worldY - Y position to get the tile from (given in pixels) - * @param {boolean} [nonNull] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); - }, - - /** - * Return a list of all valid tilelayer names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getTileLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap. - */ - getTileLayerNames: function () - { - if (!this.layers || !Array.isArray(this.layers)) - { - return []; - } - - return this.layers.map(function (layer) - { - return layer.name; - }); - }, - - /** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithin - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, - * Line, Rectangle or Triangle. The shape should be in world coordinates. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinShape - * @since 3.0.0 - * - * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithinShape: function (shape, filteringOptions, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); - }, - - /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); - }, - - /** - * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getTileset - * @since 3.14.0 - * - * @param {string} name - The name of the Tileset to get. - * - * @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found. - */ - getTileset: function (name) - { - var index = this.getIndex(this.tilesets, name); - - return (index !== null) ? this.tilesets[index] : null; - }, - - /** - * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an - * invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getTilesetIndex - * @since 3.0.0 - * - * @param {string} name - The name of the Tileset to get. - * - * @return {number} The Tileset index within this.tilesets. - */ - getTilesetIndex: function (name) - { - return this.getIndex(this.tilesets, name); - }, - - /** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#hasTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ - hasTileAt: function (tileX, tileY, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.HasTileAt(tileX, tileY, layer); - }, - - /** - * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ - hasTileAtWorldXY: function (worldX, worldY, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); - }, - - /** - * The LayerData object that is currently selected in the map. You can set this property using - * any type supported by setLayer. - * - * @name Phaser.Tilemaps.Tilemap#layer - * @type {Phaser.Tilemaps.LayerData} - * @since 3.0.0 - */ - layer: { - get: function () - { - return this.layers[this.currentLayerIndex]; - }, - - set: function (layer) - { - this.setLayer(layer); - } - }, - - /** - * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index - * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified - * location. If you pass in an index, only the index at the specified location will be changed. - * Collision information will be recalculated at the specified location. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTileAt - * @since 3.0.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid or the coordinates were out of bounds. - */ - putTileAt: function (tile, tileX, tileY, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer); - }, - - /** - * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either - * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the - * specified location. If you pass in an index, only the index at the specified location will be - * changed. Collision information will be recalculated at the specified location. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTileAtWorldXY - * @since 3.0.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer); - }, - - /** - * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified - * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, - * all attributes will be copied over to the specified location. If you pass in an index, only the - * index at the specified location will be changed. Collision information will be recalculated - * within the region tiles were changed. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTilesAt - * @since 3.0.0 - * - * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer); - - return this; - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then - * those will be used for randomly assigning new tile indexes. If an array is not provided, the - * indexes found within the region (excluding -1) will be used for randomly assigning new tile - * indexes. This method only modifies tile indexes and does not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#randomize - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - randomize: function (tileX, tileY, width, height, indexes, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer); - - return this; - }, - - /** - * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting - * faces are used internally for optimizing collisions against tiles. This method is mostly used - * internally to optimize recalculating faces when only one tile has been changed. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#calculateFacesAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - calculateFacesAt: function (tileX, tileY, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.CalculateFacesAt(tileX, tileY, layer); - - return this; - }, - - /** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#calculateFacesWithin - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - calculateFacesWithin: function (tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Removes the given TilemapLayer from this Tilemap without destroying it. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeLayer - * @since 3.17.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be removed. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - removeLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - SpliceOne(this.layers, index); - - for (var i = index; i < this.layers.length; i++) - { - if (this.layers[i].tilemapLayer) - { - this.layers[i].tilemapLayer.layerIndex--; - } - } - - if (this.currentLayerIndex === index) - { - this.currentLayerIndex = 0; - } - - return this; - } - else - { - return null; - } - }, - - /** - * Destroys the given TilemapLayer and removes it from this Tilemap. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#destroyLayer - * @since 3.17.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be destroyed. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - destroyLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - layer = this.layers[index]; - - layer.destroy(); - - SpliceOne(this.layers, index); - - if (this.currentLayerIndex === index) - { - this.currentLayerIndex = 0; - } - - return this; - } - else - { - return null; - } - }, - - /** - * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. - * - * @method Phaser.Tilemaps.Tilemap#removeAllLayers - * @since 3.0.0 - * - * @return {this} This Tilemap object. - */ - removeAllLayers: function () - { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) - { - if (layers[i].tilemapLayer) - { - layers[i].tilemapLayer.destroy(false); - } - } - - layers.length = 0; - - this.currentLayerIndex = 0; - - return this; - }, - - /** - * Removes the given Tile, or an array of Tiles, from the layer to which they belong, - * and optionally recalculates the collision information. - * - * @method Phaser.Tilemaps.Tilemap#removeTile - * @since 3.17.0 - * - * @param {(Phaser.Tilemaps.Tile|Phaser.Tilemaps.Tile[])} tiles - The Tile to remove, or an array of Tiles. - * @param {number} [replaceIndex=-1] - After removing the Tile, insert a brand new Tile into its location with the given index. Leave as -1 to just remove the tile. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed. - */ - removeTile: function (tiles, replaceIndex, recalculateFaces) - { - if (replaceIndex === undefined) { replaceIndex = -1; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - var removed = []; - - if (!Array.isArray(tiles)) - { - tiles = [ tiles ]; - } - - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; - - removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); - - if (replaceIndex > -1) - { - this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); - } - } - - return removed; - }, - - /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layers collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns the Tile that was removed, or null if the layer given was invalid. - */ - removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces, layer) - { - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); - }, - - /** - * Removes the tile at the given world coordinates in the specified layer and updates the layers collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) - { - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); - }, - - /** - * Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to - * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles - * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation - * wherever you want on the screen. - * - * If no layer is specified, the maps current layer is used. - * - * **Note:** This method currently only works with orthogonal tilemap layers. - * - * @method Phaser.Tilemaps.Tilemap#renderDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - renderDebug: function (graphics, styleConfig, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - if (this.orientation === ORIENTATION.ORTHOGONAL) - { - TilemapComponents.RenderDebug(graphics, styleConfig, layer); - } - - return this; - }, - - /** - * Draws a debug representation of all layers within this Tilemap to the given Graphics object. - * - * This is helpful when you want to get a quick idea of which of your tiles are colliding and which - * have interesting faces. The tiles are drawn starting at (0, 0) in the Graphics, allowing you to - * place the debug representation wherever you want on the screen. - * - * @method Phaser.Tilemaps.Tilemap#renderDebugFull - * @since 3.17.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * - * @return {this} This Tilemap instance. - */ - renderDebugFull: function (graphics, styleConfig) - { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) - { - TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); - } - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#replaceByIndex - * @since 3.0.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Sets collision on the given tile or tiles within a layer by index. You can pass in either a - * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if - * collision will be enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollision - * @since 3.0.0 - * - * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollision: function (indexes, collides, recalculateFaces, layer, updateLayer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - if (updateLayer === undefined) { updateLayer = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); - - return this; - }, - - /** - * Sets collision on a range of tiles in a layer whose index is between the specified `start` and - * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set - * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be - * enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionBetween - * @since 3.0.0 - * - * @param {number} start - The first index of the tile to be set for collision. - * @param {number} stop - The last index of the tile to be set for collision. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property - * that matches the given properties object, its collision flag will be set. The `collides` - * parameter controls if collision will be enabled (true) or disabled (false). Passing in - * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that - * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can - * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a - * "types" property that matches any of those values, its collision flag will be updated. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionByProperty - * @since 3.0.0 - * - * @param {object} properties - An object with tile properties and corresponding values that should be checked. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionByProperty: function (properties, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on all tiles in the given layer, except for tiles that have an index specified in - * the given array. The `collides` parameter controls if collision will be enabled (true) or - * disabled (false). Tile indexes not currently in the layer are not affected. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion - * @since 3.0.0 - * - * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking each tiles collision group data - * (typically defined in Tiled within the tileset collision editor). If any objects are found within - * a tiles collision group, the tiles colliding information will be set. The `collides` parameter - * controls if collision will be enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup - * @since 3.0.0 - * - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionFromCollisionGroup: function (collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets a global collision callback for the given tile index within the layer. This will affect all - * tiles on this layer that have the same index. If a callback is already set for the tile index it - * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile - * at a specific location on the map then see `setTileLocationCallback`. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setTileIndexCallback - * @since 3.0.0 - * - * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. All values should be integers. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} callbackContext - The context under which the callback is called. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setTileIndexCallback: function (indexes, callback, callbackContext, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer); - - return this; - }, - - /** - * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. - * If a callback is already set for the tile index it will be replaced. Set the callback to null to - * remove it. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setTileLocationCallback - * @since 3.0.0 - * - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} [callbackContext] - The context under which the callback is called. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); - - return this; - }, - - /** - * Sets the current layer to the LayerData associated with `layer`. - * - * @method Phaser.Tilemaps.Tilemap#setLayer - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. - * - * @return {this} This Tilemap object. - */ - setLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - this.currentLayerIndex = index; - } - - return this; - }, - - /** - * Sets the base tile size for the map. Note: this does not necessarily match the tileWidth and - * tileHeight for all layers. This also updates the base size on all tiles across all layers. - * - * @method Phaser.Tilemaps.Tilemap#setBaseTileSize - * @since 3.0.0 - * - * @param {number} tileWidth - The width of the tiles the map uses for calculations. - * @param {number} tileHeight - The height of the tiles the map uses for calculations. - * - * @return {this} This Tilemap object. - */ - setBaseTileSize: function (tileWidth, tileHeight) - { - this.tileWidth = tileWidth; - this.tileHeight = tileHeight; - this.widthInPixels = this.width * tileWidth; - this.heightInPixels = this.height * tileHeight; - - // Update the base tile size on all layers & tiles - for (var i = 0; i < this.layers.length; i++) - { - this.layers[i].baseTileWidth = tileWidth; - this.layers[i].baseTileHeight = tileHeight; - - var mapData = this.layers[i].data; - var mapWidth = this.layers[i].width; - var mapHeight = this.layers[i].height; - - for (var row = 0; row < mapHeight; row++) - { - for (var col = 0; col < mapWidth; col++) - { - var tile = mapData[row][col]; - - if (tile !== null) - { - tile.setSize(undefined, undefined, tileWidth, tileHeight); - } - } - } - } - - return this; - }, - - /** - * Sets the tile size for a specific `layer`. Note: this does not necessarily match the maps - * tileWidth and tileHeight for all layers. This will set the tile size for the layer and any - * tiles the layer has. - * - * @method Phaser.Tilemaps.Tilemap#setLayerTileSize - * @since 3.0.0 - * - * @param {number} tileWidth - The width of the tiles (in pixels) in the layer. - * @param {number} tileHeight - The height of the tiles (in pixels) in the layer. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. - * - * @return {this} This Tilemap object. - */ - setLayerTileSize: function (tileWidth, tileHeight, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return this; } - - layer.tileWidth = tileWidth; - layer.tileHeight = tileHeight; - - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; - - for (var row = 0; row < mapHeight; row++) - { - for (var col = 0; col < mapWidth; col++) - { - var tile = mapData[row][col]; - - if (tile !== null) - { - tile.setSize(tileWidth, tileHeight); - } - } - } - - return this; - }, - - /** - * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given - * layer. It will only randomize the tiles in that area, so if they're all the same nothing will - * appear to have changed! This method only modifies tile indexes and does not change collision - * information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#shuffle - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - shuffle: function (tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Shuffle(tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision - * information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#swapByIndex - * @since 3.0.0 - * - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - swapByIndex: function (indexA, indexB, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldX - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - tileToWorldX: function (tileX, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldX(tileX, camera, layer); - }, - - /** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldY - * @since 3.0.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - tileToWorldY: function (tileX, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldY(tileX, camera, layer); - }, - - /** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldXY - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid. - */ - tileToWorldXY: function (tileX, tileY, vec2, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. New indexes are drawn from the given - * weightedIndexes array. An example weighted array: - * - * [ - * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 - * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 - * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 - * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 - * ] - * - * The probability of any index being picked is (the indexs weight) / (sum of all weights). This - * method only modifies tile indexes and does not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#weightedRandomize - * @since 3.0.0 - * - * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); - - return this; - }, - - /** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileX - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - worldToTileX: function (worldX, snapToFloor, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); - }, - - /** - * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileY - * @since 3.0.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - worldToTileY: function (worldY, snapToFloor, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); - }, - - /** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid. - */ - worldToTileXY: function (worldX, worldY, snapToFloor, vec2, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); - }, - - /** - * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any - * TilemapLayers that have been created. - * - * @method Phaser.Tilemaps.Tilemap#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.removeAllLayers(); - - this.tilesets.length = 0; - this.objects.length = 0; - - this.scene = null; - } - -}); - -module.exports = Tilemap; - - -/***/ }), -/* 561 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var TilemapComponents = __webpack_require__(245); -var TilemapLayerRender = __webpack_require__(1442); - -/** - * @classdesc - * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination - * with one, or more, Tilesets. - * - * @class TilemapLayer - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.50.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. - * @param {Phaser.Tilemaps.Tilemap} tilemap - The Tilemap this layer is a part of. - * @param {number} layerIndex - The index of the LayerData associated with this layer. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The world x position where the top left of this layer will be placed. - * @param {number} [y=0] - The world y position where the top left of this layer will be placed. - */ -var TilemapLayer = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Origin, - Components.Pipeline, - Components.Transform, - Components.Visible, - Components.ScrollFactor, - TilemapLayerRender - ], - - initialize: - - function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) - { - GameObject.call(this, scene, 'TilemapLayer'); - - /** - * Used internally by physics system to perform fast type checks. - * - * @name Phaser.Tilemaps.TilemapLayer#isTilemap - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.isTilemap = true; - - /** - * The Tilemap that this layer is a part of. - * - * @name Phaser.Tilemaps.TilemapLayer#tilemap - * @type {Phaser.Tilemaps.Tilemap} - * @since 3.50.0 - */ - this.tilemap = tilemap; - - /** - * The index of the LayerData associated with this layer. - * - * @name Phaser.Tilemaps.TilemapLayer#layerIndex - * @type {number} - * @since 3.50.0 - */ - this.layerIndex = layerIndex; - - /** - * The LayerData associated with this layer. LayerData can only be associated with one - * tilemap layer. - * - * @name Phaser.Tilemaps.TilemapLayer#layer - * @type {Phaser.Tilemaps.LayerData} - * @since 3.50.0 - */ - this.layer = tilemap.layers[layerIndex]; - - // Link the LayerData with this static tilemap layer - this.layer.tilemapLayer = this; - - /** - * An array of `Tileset` objects associated with this layer. - * - * @name Phaser.Tilemaps.TilemapLayer#tileset - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.50.0 - */ - this.tileset = []; - - /** - * The total number of tiles drawn by the renderer in the last frame. - * - * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.tilesDrawn = 0; - - /** - * The total number of tiles in this layer. Updated every frame. - * - * @name Phaser.Tilemaps.TilemapLayer#tilesTotal - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.tilesTotal = this.layer.width * this.layer.height; - - /** - * Used internally during rendering. This holds the tiles that are visible within the Camera. - * - * @name Phaser.Tilemaps.TilemapLayer#culledTiles - * @type {Phaser.Tilemaps.Tile[]} - * @since 3.50.0 - */ - this.culledTiles = []; - - /** - * You can control if the camera should cull tiles on this layer before rendering them or not. - * - * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. - * - * However, there are some instances when you may wish to disable this, and toggling this flag allows - * you to do so. Also see `setSkipCull` for a chainable method that does the same thing. - * - * @name Phaser.Tilemaps.TilemapLayer#skipCull - * @type {boolean} - * @since 3.50.0 - */ - this.skipCull = false; - - /** - * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. - * - * See the method `setCullPadding` for more details. - * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX - * @type {number} - * @default 1 - * @since 3.50.0 - */ - this.cullPaddingX = 1; - - /** - * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. - * - * See the method `setCullPadding` for more details. - * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY - * @type {number} - * @default 1 - * @since 3.50.0 - */ - this.cullPaddingY = 1; - - /** - * The callback that is invoked when the tiles are culled. - * - * It will call a different function based on the map orientation: - * - * Orthogonal (the default) is `TilemapComponents.CullTiles` - * Isometric is `TilemapComponents.IsometricCullTiles` - * Hexagonal is `TilemapComponents.HexagonalCullTiles` - * Staggered is `TilemapComponents.StaggeredCullTiles` - * - * However, you can override this to call any function you like. - * - * It will be sent 4 arguments: - * - * 1. The Phaser.Tilemaps.LayerData object for this Layer - * 2. The Camera that is culling the layer. You can check its `dirty` property to see if it has changed since the last cull. - * 3. A reference to the `culledTiles` array, which should be used to store the tiles you want rendered. - * 4. The Render Order constant. - * - * See the `TilemapComponents.CullTiles` source code for details on implementing your own culling system. - * - * @name Phaser.Tilemaps.TilemapLayer#cullCallback - * @type {function} - * @since 3.50.0 - */ - this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); - - /** - * The rendering (draw) order of the tiles in this layer. - * - * The default is 0 which is 'right-down', meaning it will draw the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * This can be changed via the `setRenderOrder` method. - * - * @name Phaser.Tilemaps.TilemapLayer#_renderOrder - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - this._renderOrder = 0; - - /** - * An array holding the mapping between the tile indexes and the tileset they belong to. - * - * @name Phaser.Tilemaps.TilemapLayer#gidMap - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.50.0 - */ - this.gidMap = []; - - this.setTilesets(tileset); - this.setAlpha(this.layer.alpha); - this.setPosition(x, y); - this.setOrigin(); - this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height); - - this.initPipeline(); - }, - - /** - * Populates the internal `tileset` array with the Tileset references this Layer requires for rendering. - * - * @method Phaser.Tilemaps.TilemapLayer#setTilesets - * @private - * @since 3.50.0 - * - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - */ - setTilesets: function (tilesets) - { - var gidMap = []; - var setList = []; - var map = this.tilemap; - - if (!Array.isArray(tilesets)) - { - tilesets = [ tilesets ]; - } - - for (var i = 0; i < tilesets.length; i++) - { - var tileset = tilesets[i]; - - if (typeof tileset === 'string') - { - tileset = map.getTileset(tileset); - } - - if (tileset) - { - setList.push(tileset); - - var s = tileset.firstgid; - - for (var t = 0; t < tileset.total; t++) - { - gidMap[s + t] = tileset; - } - } - } - - this.gidMap = gidMap; - this.tileset = setList; - }, - - /** - * Sets the rendering (draw) order of the tiles in this layer. - * - * The default is 'right-down', meaning it will order the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * Setting the render order does not change the tiles or how they are stored in the layer, - * it purely impacts the order in which they are rendered. - * - * You can provide either an integer (0 to 3), or the string version of the order. - * - * @method Phaser.Tilemaps.TilemapLayer#setRenderOrder - * @since 3.50.0 - * - * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. - * - * @return {this} This Tilemap Layer object. - */ - setRenderOrder: function (renderOrder) - { - var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; - - if (typeof renderOrder === 'string') - { - renderOrder = orders.indexOf(renderOrder); - } - - if (renderOrder >= 0 && renderOrder < 4) - { - this._renderOrder = renderOrder; - } - - return this; - }, - - /** - * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting - * faces are used internally for optimizing collisions against tiles. This method is mostly used - * internally to optimize recalculating faces when only one tile has been changed. - * - * @method Phaser.Tilemaps.TilemapLayer#calculateFacesAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. - * - * @return {this} This Tilemap Layer object. - */ - calculateFacesAt: function (tileX, tileY) - { - TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer); - - return this; - }, - - /** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - calculateFacesWithin: function (tileX, tileY, width, height) - { - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Creates a Sprite for every object matching the given tile indexes in the layer. You can - * optionally specify if each tile will be replaced with a new tile after the Sprite has been - * created. This is useful if you want to lay down special tiles in a level that are converted to - * Sprites, but want to replace the tile itself with a floor tile or similar once converted. - * - * @method Phaser.Tilemaps.TilemapLayer#createFromTiles - * @since 3.50.0 - * - * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. - * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted - * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a - * one-to-one mapping with the indexes array. - * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e. - * scene.make.sprite). - * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when determining the world XY - * - * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. - */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera) - { - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer); - }, - - /** - * Returns the tiles in the given layer that are within the cameras viewport. - * This is used internally during rendering. - * - * @method Phaser.Tilemaps.TilemapLayer#cull - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render. - */ - cull: function (camera) - { - return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder); - }, - - /** - * Copies the tiles in the source rectangular area to a new destination (all specified in tile - * coordinates) within the layer. This copies all tile properties & recalculates collision - * information in the destination region. - * - * @method Phaser.Tilemaps.TilemapLayer#copy - * @since 3.50.0 - * - * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. - * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. - * @param {number} width - The width of the area to copy, in tiles, not pixels. - * @param {number} height - The height of the area to copy, in tiles, not pixels. - * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. - * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) - { - TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the - * specified index. Tiles will be set to collide if the given index is a colliding index. - * Collision information in the region will be recalculated. - * - * @method Phaser.Tilemaps.TilemapLayer#fill - * @since 3.50.0 - * - * @param {number} index - The tile index to fill the area with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - fill: function (index, tileX, tileY, width, height, recalculateFaces) - { - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); - - return this; - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns - * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#filterTiles - * @since 3.50.0 - * - * @param {function} callback - The callback. Each tile in the given area will be passed to this - * callback as the first and only parameter. The callback should return true for tiles that pass the - * filter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * Searches the entire map layer for the first tile matching the given index, then returns that Tile - * object. If no match is found, it returns null. The search starts from the top-left tile and - * continues horizontally until it hits the end of the row, then it drops down to the next column. - * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to - * the top-left. - * - * @method Phaser.Tilemaps.TilemapLayer#findByIndex - * @since 3.50.0 - * - * @param {number} index - The tile index value to search for. - * @param {number} [skip=0] - The number of times to skip a matching tile before returning. - * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. - * - * @return {Phaser.Tilemaps.Tile} The first matching Tile object. - */ - findByIndex: function (findIndex, skip, reverse) - { - return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer); - }, - - /** - * Find the first tile in the given rectangular area (in tile coordinates) of the layer that - * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns - * true. Similar to Array.prototype.find in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#findTile - * @since 3.50.0 - * - * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location. - */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * callback. Similar to Array.prototype.forEach in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#forEachTile - * @since 3.50.0 - * - * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context, or scope, under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {this} This Tilemap Layer object. - */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - - return this; - }, - - /** - * Gets a tile at the given tile coordinates from the given layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTileAt - * @since 3.50.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {boolean} [nonNull=false] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. - * - * @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ - getTileAt: function (tileX, tileY, nonNull) - { - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer); - }, - - /** - * Gets a tile at the given world coordinates from the given layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - X position to get the tile from (given in pixels) - * @param {number} worldY - Y position to get the tile from (given in pixels) - * @param {boolean} [nonNull=false] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera) - { - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer); - }, - - /** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. - */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, - * Line, Rectangle or Triangle. The shape should be in world coordinates. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape - * @since 3.50.0 - * - * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. - */ - getTilesWithinShape: function (shape, filteringOptions, camera) - { - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); - }, - - /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. - */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera) - { - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer); - }, - - /** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @method Phaser.Tilemaps.TilemapLayer#hasTileAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. - */ - hasTileAt: function (tileX, tileY) - { - return TilemapComponents.HasTileAt(tileX, tileY, this.layer); - }, - - /** - * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. - */ - hasTileAtWorldXY: function (worldX, worldY, camera) - { - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); - }, - - /** - * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index - * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified - * location. If you pass in an index, only the index at the specified location will be changed. - * Collision information will be recalculated at the specified location. - * - * @method Phaser.Tilemaps.TilemapLayer#putTileAt - * @since 3.50.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. - */ - putTileAt: function (tile, tileX, tileY, recalculateFaces) - { - return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer); - }, - - /** - * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either - * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the - * specified location. If you pass in an index, only the index at the specified location will be - * changed. Collision information will be recalculated at the specified location. - * - * @method Phaser.Tilemaps.TilemapLayer#putTileAtWorldXY - * @since 3.50.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. - */ - putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera) - { - return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer); - }, - - /** - * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified - * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, - * all attributes will be copied over to the specified location. If you pass in an index, only the - * index at the specified location will be changed. Collision information will be recalculated - * within the region tiles were changed. - * - * @method Phaser.Tilemaps.TilemapLayer#putTilesAt - * @since 3.50.0 - * - * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces) - { - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer); - - return this; - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then - * those will be used for randomly assigning new tile indexes. If an array is not provided, the - * indexes found within the region (excluding -1) will be used for randomly assigning new tile - * indexes. This method only modifies tile indexes and does not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#randomize - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. - * - * @return {this} This Tilemap Layer object. - */ - randomize: function (tileX, tileY, width, height, indexes) - { - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); - - return this; - }, - - /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layers - * collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile} A Tile object. - */ - removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces) - { - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer); - }, - - /** - * Removes the tile at the given world coordinates in the specified layer and updates the layers - * collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location. - */ - removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera) - { - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer); - }, - - /** - * Draws a debug representation of the layer to the given Graphics. This is helpful when you want to - * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles - * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation - * wherever you want on the screen. - * - * @method Phaser.Tilemaps.TilemapLayer#renderDebug - * @since 3.50.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * - * @return {this} This Tilemap Layer object. - */ - renderDebug: function (graphics, styleConfig) - { - TilemapComponents.RenderDebug(graphics, styleConfig, this.layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#replaceByIndex - * @since 3.50.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height) - { - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * You can control if the Cameras should cull tiles before rendering them or not. - * - * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. - * - * However, there are some instances when you may wish to disable this. - * - * @method Phaser.Tilemaps.TilemapLayer#setSkipCull - * @since 3.50.0 - * - * @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again. - * - * @return {this} This Tilemap Layer object. - */ - setSkipCull: function (value) - { - if (value === undefined) { value = true; } - - this.skipCull = value; - - return this; - }, - - /** - * When a Camera culls the tiles in this layer it does so using its view into the world, building up a - * rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size - * of this 'cull rectangle', especially if you plan on rotating the Camera viewing the layer. Do so - * by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px - * and you set `paddingX` to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale) - * - * @method Phaser.Tilemaps.TilemapLayer#setCullPadding - * @since 3.50.0 - * - * @param {number} [paddingX=1] - The amount of extra horizontal tiles to add to the cull check padding. - * @param {number} [paddingY=1] - The amount of extra vertical tiles to add to the cull check padding. - * - * @return {this} This Tilemap Layer object. - */ - setCullPadding: function (paddingX, paddingY) - { - if (paddingX === undefined) { paddingX = 1; } - if (paddingY === undefined) { paddingY = 1; } - - this.cullPaddingX = paddingX; - this.cullPaddingY = paddingY; - - return this; - }, - - /** - * Sets collision on the given tile or tiles within a layer by index. You can pass in either a - * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if - * collision will be enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollision - * @since 3.50.0 - * - * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. - * - * @return {this} This Tilemap Layer object. - */ - setCollision: function (indexes, collides, recalculateFaces, updateLayer) - { - TilemapComponents.SetCollision(indexes, collides, recalculateFaces, this.layer, updateLayer); - - return this; - }, - - /** - * Sets collision on a range of tiles in a layer whose index is between the specified `start` and - * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set - * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be - * enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween - * @since 3.50.0 - * - * @param {number} start - The first index of the tile to be set for collision. - * @param {number} stop - The last index of the tile to be set for collision. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionBetween: function (start, stop, collides, recalculateFaces) - { - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property - * that matches the given properties object, its collision flag will be set. The `collides` - * parameter controls if collision will be enabled (true) or disabled (false). Passing in - * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that - * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can - * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a - * "types" property that matches any of those values, its collision flag will be updated. - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionByProperty - * @since 3.50.0 - * - * @param {object} properties - An object with tile properties and corresponding values that should be checked. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionByProperty: function (properties, collides, recalculateFaces) - { - TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on all tiles in the given layer, except for tiles that have an index specified in - * the given array. The `collides` parameter controls if collision will be enabled (true) or - * disabled (false). Tile indexes not currently in the layer are not affected. - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion - * @since 3.50.0 - * - * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces) - { - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking each tiles collision group data - * (typically defined in Tiled within the tileset collision editor). If any objects are found within - * a tiles collision group, the tile's colliding information will be set. The `collides` parameter - * controls if collision will be enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup - * @since 3.50.0 - * - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionFromCollisionGroup: function (collides, recalculateFaces) - { - TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets a global collision callback for the given tile index within the layer. This will affect all - * tiles on this layer that have the same index. If a callback is already set for the tile index it - * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile - * at a specific location on the map then see setTileLocationCallback. - * - * @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback - * @since 3.50.0 - * - * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} callbackContext - The context under which the callback is called. - * - * @return {this} This Tilemap Layer object. - */ - setTileIndexCallback: function (indexes, callback, callbackContext) - { - TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer); - - return this; - }, - - /** - * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. - * If a callback is already set for the tile index it will be replaced. Set the callback to null to - * remove it. - * - * @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {function} [callback] - The callback that will be invoked when the tile is collided with. - * @param {object} [callbackContext] - The context, or scope, under which the callback is invoked. - * - * @return {this} This Tilemap Layer object. - */ - setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext) - { - TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer); - - return this; - }, - - /** - * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given - * layer. It will only randomize the tiles in that area, so if they're all the same nothing will - * appear to have changed! This method only modifies tile indexes and does not change collision - * information. - * - * @method Phaser.Tilemaps.TilemapLayer#shuffle - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - shuffle: function (tileX, tileY, width, height) - { - TilemapComponents.Shuffle(tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision - * information. - * - * @method Phaser.Tilemaps.TilemapLayer#swapByIndex - * @since 3.50.0 - * - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - swapByIndex: function (indexA, indexB, tileX, tileY, width, height) - { - TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldX - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The Tile X coordinate converted to pixels. - */ - tileToWorldX: function (tileX, camera) - { - return this.tilemap.tileToWorldX(tileX, camera, this); - }, - - /** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The Tile Y coordinate converted to pixels. - */ - tileToWorldY: function (tileY, camera) - { - return this.tilemap.tileToWorldY(tileY, camera, this); - }, - - /** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Math.Vector2} A Vector2 containing the world coordinates of the Tile. - */ - tileToWorldXY: function (tileX, tileY, point, camera) - { - return this.tilemap.tileToWorldXY(tileX, tileY, point, camera, this); - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. New indexes are drawn from the given - * weightedIndexes array. An example weighted array: - * - * [ - * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 - * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 - * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 - * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 - * ] - * - * The probability of any index being choose is (the index's weight) / (sum of all weights). This - * method only modifies tile indexes and does not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#weightedRandomize - * @since 3.50.0 - * - * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - weightedRandomize: function (tileX, tileY, width, height, weightedIndexes) - { - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); - - return this; - }, - - /** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileX - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The tile X coordinate based on the world value. - */ - worldToTileX: function (worldX, snapToFloor, camera) - { - return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this); - }, - - /** - * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The tile Y coordinate based on the world value. - */ - worldToTileY: function (worldY, snapToFloor, camera) - { - return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); - }, - - /** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values. - */ - worldToTileXY: function (worldX, worldY, snapToFloor, point, camera) - { - return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this); - }, - - /** - * Destroys this TilemapLayer and removes its link to the associated LayerData. - * - * @method Phaser.Tilemaps.TilemapLayer#destroy - * @since 3.50.0 - * - * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? - */ - destroy: function (removeFromTilemap) - { - if (removeFromTilemap === undefined) { removeFromTilemap = true; } - - if (!this.tilemap) - { - // Abort, we've already been destroyed - return; - } - - // Uninstall this layer only if it is still installed on the LayerData object - if (this.layer.tilemapLayer === this) - { - this.layer.tilemapLayer = undefined; - } - - if (removeFromTilemap) - { - this.tilemap.removeLayer(this); - } - - this.tilemap = undefined; - this.layer = undefined; - this.culledTiles.length = 0; - this.cullCallback = null; - - this.gidMap = []; - this.tileset = []; - - GameObject.prototype.destroy.call(this); - } - -}); - -module.exports = TilemapLayer; - - -/***/ }), -/* 562 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * A Timer Event represents a delayed function call. It's managed by a Scene's {@link Clock} and will call its function after a set amount of time has passed. The Timer Event can optionally repeat - i.e. call its function multiple times before finishing, or loop indefinitely. - * - * Because it's managed by a Clock, a Timer Event is based on game time, will be affected by its Clock's time scale, and will pause if its Clock pauses. - * - * @class TimerEvent - * @memberof Phaser.Time - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.Time.TimerEventConfig} config - The configuration for the Timer Event, including its delay and callback. - */ -var TimerEvent = new Class({ - - initialize: - - function TimerEvent (config) - { - /** - * The delay in ms at which this TimerEvent fires. - * - * @name Phaser.Time.TimerEvent#delay - * @type {number} - * @default 0 - * @readonly - * @since 3.0.0 - */ - this.delay = 0; - - /** - * The total number of times this TimerEvent will repeat before finishing. - * - * @name Phaser.Time.TimerEvent#repeat - * @type {number} - * @default 0 - * @readonly - * @since 3.0.0 - */ - this.repeat = 0; - - /** - * If repeating this contains the current repeat count. - * - * @name Phaser.Time.TimerEvent#repeatCount - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeatCount = 0; - - /** - * True if this TimerEvent loops, otherwise false. - * - * @name Phaser.Time.TimerEvent#loop - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.loop = false; - - /** - * The callback that will be called when the TimerEvent occurs. - * - * @name Phaser.Time.TimerEvent#callback - * @type {function} - * @since 3.0.0 - */ - this.callback; - - /** - * The scope in which the callback will be called. - * - * @name Phaser.Time.TimerEvent#callbackScope - * @type {object} - * @since 3.0.0 - */ - this.callbackScope; - - /** - * Additional arguments to be passed to the callback. - * - * @name Phaser.Time.TimerEvent#args - * @type {array} - * @since 3.0.0 - */ - this.args; - - /** - * Scale the time causing this TimerEvent to update. - * - * @name Phaser.Time.TimerEvent#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly) - * - * @name Phaser.Time.TimerEvent#startAt - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.startAt = 0; - - /** - * The time in milliseconds which has elapsed since the Timer Event's creation. - * - * This value is local for the Timer Event and is relative to its Clock. As such, it's influenced by the Clock's time scale and paused state, the Timer Event's initial {@link #startAt} property, and the Timer Event's {@link #timeScale} and {@link #paused} state. - * - * @name Phaser.Time.TimerEvent#elapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.elapsed = 0; - - /** - * Whether or not this timer is paused. - * - * @name Phaser.Time.TimerEvent#paused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.paused = false; - - /** - * Whether the Timer Event's function has been called. - * - * When the Timer Event fires, this property will be set to `true` before the callback function is invoked and will be reset immediately afterward if the Timer Event should repeat. The value of this property does not directly influence whether the Timer Event will be removed from its Clock, but can prevent it from firing. - * - * @name Phaser.Time.TimerEvent#hasDispatched - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.hasDispatched = false; - - this.reset(config); - }, - - /** - * Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object. - * - * @method Phaser.Time.TimerEvent#reset - * @since 3.0.0 - * - * @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event. - * - * @return {Phaser.Time.TimerEvent} This TimerEvent object. - */ - reset: function (config) - { - this.delay = GetFastValue(config, 'delay', 0); - - // Can also be set to -1 for an infinite loop (same as setting loop: true) - this.repeat = GetFastValue(config, 'repeat', 0); - - this.loop = GetFastValue(config, 'loop', false); - - this.callback = GetFastValue(config, 'callback', undefined); - - this.callbackScope = GetFastValue(config, 'callbackScope', this.callback); - - this.args = GetFastValue(config, 'args', []); - - this.timeScale = GetFastValue(config, 'timeScale', 1); - - this.startAt = GetFastValue(config, 'startAt', 0); - - this.paused = GetFastValue(config, 'paused', false); - - this.elapsed = this.startAt; - this.hasDispatched = false; - this.repeatCount = (this.repeat === -1 || this.loop) ? 999999999999 : this.repeat; - - return this; - }, - - /** - * Gets the progress of the current iteration, not factoring in repeats. - * - * @method Phaser.Time.TimerEvent#getProgress - * @since 3.0.0 - * - * @return {number} A number between 0 and 1 representing the current progress. - */ - getProgress: function () - { - return (this.elapsed / this.delay); - }, - - /** - * Gets the progress of the timer overall, factoring in repeats. - * - * @method Phaser.Time.TimerEvent#getOverallProgress - * @since 3.0.0 - * - * @return {number} The overall progress of the Timer Event, between 0 and 1. - */ - getOverallProgress: function () - { - if (this.repeat > 0) - { - var totalDuration = this.delay + (this.delay * this.repeat); - var totalElapsed = this.elapsed + (this.delay * (this.repeat - this.repeatCount)); - - return (totalElapsed / totalDuration); - } - else - { - return this.getProgress(); - } - }, - - /** - * Returns the number of times this Timer Event will repeat before finishing. - * - * This should not be confused with the number of times the Timer Event will fire before finishing. A return value of 0 doesn't indicate that the Timer Event has finished running - it indicates that it will not repeat after the next time it fires. - * - * @method Phaser.Time.TimerEvent#getRepeatCount - * @since 3.0.0 - * - * @return {number} How many times the Timer Event will repeat. - */ - getRepeatCount: function () - { - return this.repeatCount; - }, - - /** - * Returns the local elapsed time for the current iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getElapsed - * @since 3.0.0 - * - * @return {number} The local elapsed time in milliseconds. - */ - getElapsed: function () - { - return this.elapsed; - }, - - /** - * Returns the local elapsed time for the current iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getElapsedSeconds - * @since 3.0.0 - * - * @return {number} The local elapsed time in seconds. - */ - getElapsedSeconds: function () - { - return this.elapsed * 0.001; - }, - - /** - * Returns the time interval until the next iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getRemaining - * @since 3.50.0 - * - * @return {number} The time interval in milliseconds. - */ - getRemaining: function () - { - return this.delay - this.elapsed; - }, - - /** - * Returns the time interval until the next iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getRemainingSeconds - * @since 3.50.0 - * - * @return {number} The time interval in seconds. - */ - getRemainingSeconds: function () - { - return this.getRemaining() * 0.001; - }, - - /** - * Returns the time interval until the last iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getOverallRemaining - * @since 3.50.0 - * - * @return {number} The time interval in milliseconds. - */ - getOverallRemaining: function () - { - return this.delay * (1 + this.repeatCount) - this.elapsed; - }, - - /** - * Returns the time interval until the last iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds - * @since 3.50.0 - * - * @return {number} The time interval in seconds. - */ - getOverallRemainingSeconds: function () - { - return this.getOverallRemaining() * 0.001; - }, - - /** - * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. - * - * @method Phaser.Time.TimerEvent#remove - * @since 3.0.0 - * - * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. - */ - remove: function (dispatchCallback) - { - if (dispatchCallback === undefined) { dispatchCallback = false; } - - this.elapsed = this.delay; - - this.hasDispatched = !dispatchCallback; - - this.repeatCount = 0; - }, - - /** - * Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments. - * - * Normally, this method is only called by the Clock when it shuts down. As such, it doesn't stop the Timer Event. If called manually, the Timer Event will still be updated by the Clock, but it won't do anything when it fires. - * - * @method Phaser.Time.TimerEvent#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.callback = undefined; - this.callbackScope = undefined; - this.args = []; - } - -}); - -module.exports = TimerEvent; - - -/***/ }), -/* 563 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var RESERVED = __webpack_require__(1451); - -/** - * Internal function used by the Tween Builder to return an array of properties - * that the Tween will be operating on. It takes a tween configuration object - * and then checks that none of the `props` entries start with an underscore, or that - * none of the direct properties are on the Reserved list. - * - * @function Phaser.Tweens.Builders.GetProps - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TweenBuilderConfig} config - The configuration object of the Tween to get the properties from. - * - * @return {string[]} An array of all the properties the tween will operate on. - */ -var GetProps = function (config) -{ - var key; - var keys = []; - - // First see if we have a props object - - if (config.hasOwnProperty('props')) - { - for (key in config.props) - { - // Skip any property that starts with an underscore - if (key.substr(0, 1) !== '_') - { - keys.push({ key: key, value: config.props[key] }); - } - } - } - else - { - for (key in config) - { - // Skip any property that is in the ReservedProps list or that starts with an underscore - if (RESERVED.indexOf(key) === -1 && key.substr(0, 1) !== '_') - { - keys.push({ key: key, value: config[key] }); - } - } - } - - return keys; -}; - -module.exports = GetProps; - - -/***/ }), -/* 564 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetValue = __webpack_require__(6); - -/** - * Internal function used by the Timeline Builder. - * - * It returns an array of all tweens in the given timeline config. - * - * @function Phaser.Tweens.Builders.GetTweens - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. - * - * @return {Phaser.Tweens.Tween[]} An array of Tween instances that the Timeline will manage. - */ -var GetTweens = function (config) -{ - var tweens = GetValue(config, 'tweens', null); - - if (tweens === null) - { - return []; - } - else if (typeof tweens === 'function') - { - tweens = tweens.call(); - } - - if (!Array.isArray(tweens)) - { - tweens = [ tweens ]; - } - - return tweens; -}; - -module.exports = GetTweens; - - -/***/ }), -/* 565 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Defaults = __webpack_require__(259); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(96); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(258); -var Tween = __webpack_require__(260); -var TweenData = __webpack_require__(262); - -/** - * Creates a new Number Tween. - * - * @function Phaser.Tweens.Builders.NumberTweenBuilder - * @since 3.0.0 - * - * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - The owner of the new Tween. - * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - Configuration for the new Tween. - * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. - * - * @return {Phaser.Tweens.Tween} The new tween. - */ -var NumberTweenBuilder = function (parent, config, defaults) -{ - if (defaults === undefined) - { - defaults = Defaults; - } - - // var tween = this.tweens.addCounter({ - // from: 100, - // to: 200, - // ... (normal tween properties) - // }) - // - // Then use it in your game via: - // - // tween.getValue() - - var from = GetValue(config, 'from', 0); - var to = GetValue(config, 'to', 1); - - var targets = [ { value: from } ]; - - var delay = GetNewValue(config, 'delay', defaults.delay); - var duration = GetNewValue(config, 'duration', defaults.duration); - var easeParams = GetValue(config, 'easeParams', defaults.easeParams); - var ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), easeParams); - var hold = GetNewValue(config, 'hold', defaults.hold); - var repeat = GetNewValue(config, 'repeat', defaults.repeat); - var repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); - var yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); - - var data = []; - - var ops = GetValueOp('value', to); - - var tweenData = TweenData( - targets[0], - 0, - 'value', - ops.getEnd, - ops.getStart, - ops.getActive, - ease, - delay, - duration, - yoyo, - hold, - repeat, - repeatDelay, - false, - false - ); - - tweenData.start = from; - tweenData.current = from; - tweenData.to = to; - - data.push(tweenData); - - var tween = new Tween(parent, data, targets); - - tween.offset = GetAdvancedValue(config, 'offset', null); - tween.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); - tween.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); - tween.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); - tween.paused = GetBoolean(config, 'paused', false); - tween.useFrames = GetBoolean(config, 'useFrames', false); - - // Set the Callbacks - var scope = GetValue(config, 'callbackScope', tween); - - // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params - var tweenArray = [ tween, null ]; - - var callbacks = Tween.TYPES; - - for (var i = 0; i < callbacks.length; i++) - { - var type = callbacks[i]; - - var callback = GetValue(config, type, false); - - if (callback) - { - var callbackScope = GetValue(config, type + 'Scope', scope); - var callbackParams = GetValue(config, type + 'Params', []); - - // The null is reset to be the Tween target - tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); - } - } - - return tween; -}; - -module.exports = NumberTweenBuilder; - - -/***/ }), -/* 566 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetEaseFunction = __webpack_require__(80); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); - -/** - * Creates a Stagger function to be used by a Tween property. - * - * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. - * - * This is only worth using if the tween has multiple targets. - * - * The following will stagger the delay by 100ms across all targets of the tween, causing them to scale down to 0.2 - * over the duration specified: - * - * ```javascript - * this.tweens.add({ - * targets: [ ... ], - * scale: 0.2, - * ease: 'linear', - * duration: 1000, - * delay: this.tweens.stagger(100) - * }); - * ``` - * - * The following will stagger the delay by 500ms across all targets of the tween using a 10 x 6 grid, staggering - * from the center out, using a cubic ease. - * - * ```javascript - * this.tweens.add({ - * targets: [ ... ], - * scale: 0.2, - * ease: 'linear', - * duration: 1000, - * delay: this.tweens.stagger(500, { grid: [ 10, 6 ], from: 'center', ease: 'cubic.out' }) - * }); - * ``` - * - * @function Phaser.Tweens.Builders.StaggerBuilder - * @since 3.19.0 - * - * @param {(number|number[])} value - The amount to stagger by, or an array containing two elements representing the min and max values to stagger between. - * @param {Phaser.Types.Tweens.StaggerConfig} [config] - A Stagger Configuration object. - * - * @return {function} The stagger function. - */ -var StaggerBuilder = function (value, options) -{ - if (options === undefined) { options = {}; } - - var result; - - var start = GetValue(options, 'start', 0); - var ease = GetValue(options, 'ease', null); - var grid = GetValue(options, 'grid', null); - - var from = GetValue(options, 'from', 0); - - var fromFirst = (from === 'first'); - var fromCenter = (from === 'center'); - var fromLast = (from === 'last'); - var fromValue = (typeof(from) === 'number'); - - var isRange = (Array.isArray(value)); - var value1 = (isRange) ? parseFloat(value[0]) : parseFloat(value); - var value2 = (isRange) ? parseFloat(value[1]) : 0; - var maxValue = Math.max(value1, value2); - - if (isRange) - { - start += value1; - } - - if (grid) - { - // Pre-calc the grid to save doing it for ever tweendata update - var gridWidth = grid[0]; - var gridHeight = grid[1]; - - var fromX = 0; - var fromY = 0; - - var distanceX = 0; - var distanceY = 0; - - var gridValues = []; - - if (fromLast) - { - fromX = gridWidth - 1; - fromY = gridHeight - 1; - } - else if (fromValue) - { - fromX = from % gridWidth; - fromY = Math.floor(from / gridWidth); - } - else if (fromCenter) - { - fromX = (gridWidth - 1) / 2; - fromY = (gridHeight - 1) / 2; - } - - var gridMax = MATH_CONST.MIN_SAFE_INTEGER; - - for (var toY = 0; toY < gridHeight; toY++) - { - gridValues[toY] = []; - - for (var toX = 0; toX < gridWidth; toX++) - { - distanceX = fromX - toX; - distanceY = fromY - toY; - - var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); - - if (dist > gridMax) - { - gridMax = dist; - } - - gridValues[toY][toX] = dist; - } - } - } - - var easeFunction = (ease) ? GetEaseFunction(ease) : null; - - if (grid) - { - result = function (target, key, value, index) - { - var gridSpace = 0; - var toX = index % gridWidth; - var toY = Math.floor(index / gridWidth); - - if (toX >= 0 && toX < gridWidth && toY >= 0 && toY < gridHeight) - { - gridSpace = gridValues[toY][toX]; - } - - var output; - - if (isRange) - { - var diff = (value2 - value1); - - if (easeFunction) - { - output = ((gridSpace / gridMax) * diff) * easeFunction(gridSpace / gridMax); - } - else - { - output = (gridSpace / gridMax) * diff; - } - } - else if (easeFunction) - { - output = (gridSpace * value1) * easeFunction(gridSpace / gridMax); - } - else - { - output = gridSpace * value1; - } - - return output + start; - }; - } - else - { - result = function (target, key, value, index, total) - { - // zero offset - total--; - - var fromIndex; - - if (fromFirst) - { - fromIndex = index; - } - else if (fromCenter) - { - fromIndex = Math.abs((total / 2) - index); - } - else if (fromLast) - { - fromIndex = total - index; - } - else if (fromValue) - { - fromIndex = Math.abs(from - index); - } - - var output; - - if (isRange) - { - var spacing; - - if (fromCenter) - { - spacing = ((value2 - value1) / total) * (fromIndex * 2); - } - else - { - spacing = ((value2 - value1) / total) * fromIndex; - } - - if (easeFunction) - { - output = spacing * easeFunction(fromIndex / total); - } - else - { - output = spacing; - } - } - else if (easeFunction) - { - output = (total * maxValue) * easeFunction(fromIndex / total); - } - else - { - output = fromIndex * value1; - } - - return output + start; - }; - } - - return result; -}; - -module.exports = StaggerBuilder; - - -/***/ }), -/* 567 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Clone = __webpack_require__(77); -var Defaults = __webpack_require__(259); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(96); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetTargets = __webpack_require__(257); -var GetTweens = __webpack_require__(564); -var GetValue = __webpack_require__(6); -var Timeline = __webpack_require__(568); -var TweenBuilder = __webpack_require__(160); - -/** - * Builds a Timeline of Tweens based on a configuration object. - * - * @function Phaser.Tweens.Builders.TimelineBuilder - * @since 3.0.0 - * - * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager to which the Timeline will belong. - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. - * - * @return {Phaser.Tweens.Timeline} The created Timeline. - */ -var TimelineBuilder = function (manager, config) -{ - var timeline = new Timeline(manager); - - timeline.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); - timeline.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); - timeline.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); - timeline.paused = GetBoolean(config, 'paused', false); - timeline.useFrames = GetBoolean(config, 'useFrames', false); - - // Callbacks - - var scope = GetValue(config, 'callbackScope', timeline); - - var timelineArray = [ timeline ]; - - var onStart = GetValue(config, 'onStart', false); - - // The Start of the Timeline - if (onStart) - { - var onStartScope = GetValue(config, 'onStartScope', scope); - var onStartParams = GetValue(config, 'onStartParams', []); - - timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope); - } - - var onUpdate = GetValue(config, 'onUpdate', false); - - // Every time the Timeline updates (regardless which Tweens are running) - if (onUpdate) - { - var onUpdateScope = GetValue(config, 'onUpdateScope', scope); - var onUpdateParams = GetValue(config, 'onUpdateParams', []); - - timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope); - } - - var onLoop = GetValue(config, 'onLoop', false); - - // Called when the whole Timeline loops - if (onLoop) - { - var onLoopScope = GetValue(config, 'onLoopScope', scope); - var onLoopParams = GetValue(config, 'onLoopParams', []); - - timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope); - } - - var onYoyo = GetValue(config, 'onYoyo', false); - - // Called when a Timeline yoyos - if (onYoyo) - { - var onYoyoScope = GetValue(config, 'onYoyoScope', scope); - var onYoyoParams = GetValue(config, 'onYoyoParams', []); - - timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope); - } - - var onComplete = GetValue(config, 'onComplete', false); - - // Called when the Timeline completes, after the completeDelay, etc. - if (onComplete) - { - var onCompleteScope = GetValue(config, 'onCompleteScope', scope); - var onCompleteParams = GetValue(config, 'onCompleteParams', []); - - timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope); - } - - // Tweens - - var tweens = GetTweens(config); - - if (tweens.length === 0) - { - timeline.paused = true; - - return timeline; - } - - var defaults = Clone(Defaults); - - defaults.targets = GetTargets(config); - - // totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration - - var totalDuration = GetAdvancedValue(config, 'totalDuration', 0); - - if (totalDuration > 0) - { - defaults.duration = Math.floor(totalDuration / tweens.length); - } - else - { - defaults.duration = GetNewValue(config, 'duration', defaults.duration); - } - - defaults.delay = GetNewValue(config, 'delay', defaults.delay); - defaults.easeParams = GetValue(config, 'easeParams', defaults.easeParams); - defaults.ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), defaults.easeParams); - defaults.hold = GetNewValue(config, 'hold', defaults.hold); - defaults.repeat = GetNewValue(config, 'repeat', defaults.repeat); - defaults.repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); - defaults.yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); - defaults.flipX = GetBoolean(config, 'flipX', defaults.flipX); - defaults.flipY = GetBoolean(config, 'flipY', defaults.flipY); - - // Create the Tweens - for (var i = 0; i < tweens.length; i++) - { - timeline.queue(TweenBuilder(timeline, tweens[i], defaults)); - } - - return timeline; -}; - -module.exports = TimelineBuilder; - - -/***/ }), -/* 568 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(261); -var TweenBuilder = __webpack_require__(160); -var TWEEN_CONST = __webpack_require__(97); - -/** - * @classdesc - * A Timeline combines multiple Tweens into one. Its overall behavior is otherwise similar to a single Tween. - * - * The Timeline updates all of its Tweens simultaneously. Its methods allow you to easily build a sequence - * of Tweens (each one starting after the previous one) or run multiple Tweens at once during given parts of the Timeline. - * - * @class Timeline - * @memberof Phaser.Tweens - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager which owns this Timeline. - */ -var Timeline = new Class({ - - Extends: EventEmitter, - - initialize: - - function Timeline (manager) - { - EventEmitter.call(this); - - /** - * The Tween Manager which owns this Timeline. - * - * @name Phaser.Tweens.Timeline#manager - * @type {Phaser.Tweens.TweenManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * A constant value which allows this Timeline to be easily identified as one. - * - * @name Phaser.Tweens.Timeline#isTimeline - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.isTimeline = true; - - /** - * An array of Tween objects, each containing a unique property and target being tweened. - * - * @name Phaser.Tweens.Timeline#data - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.data = []; - - /** - * The cached size of the data array. - * - * @name Phaser.Tweens.Timeline#totalData - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalData = 0; - - /** - * If true then duration, delay, etc values are all frame totals, rather than ms. - * - * @name Phaser.Tweens.Timeline#useFrames - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.useFrames = false; - - /** - * Scales the time applied to this Timeline. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. - * Value isn't used when calculating total duration of the Timeline, it's a run-time delta adjustment only. - * - * @name Phaser.Tweens.Timeline#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * Loop this Timeline? Can be -1 for an infinite loop, or an integer. - * When enabled it will play through ALL Tweens again (use Tween.repeat to loop a single tween) - * - * @name Phaser.Tweens.Timeline#loop - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loop = 0; - - /** - * Time in ms/frames before this Timeline loops. - * - * @name Phaser.Tweens.Timeline#loopDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loopDelay = 0; - - /** - * How many loops are left to run? - * - * @name Phaser.Tweens.Timeline#loopCounter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loopCounter = 0; - - /** - * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes) - * - * @name Phaser.Tweens.Timeline#completeDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.completeDelay = 0; - - /** - * Countdown timer value, as used by `loopDelay` and `completeDelay`. - * - * @name Phaser.Tweens.Timeline#countdown - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.countdown = 0; - - /** - * The current state of the Timeline. - * - * @name Phaser.Tweens.Timeline#state - * @type {number} - * @since 3.0.0 - */ - this.state = TWEEN_CONST.PENDING_ADD; - - /** - * The state of the Timeline when it was paused (used by Resume) - * - * @name Phaser.Tweens.Timeline#_pausedState - * @type {number} - * @private - * @since 3.0.0 - */ - this._pausedState = TWEEN_CONST.PENDING_ADD; - - /** - * Does the Timeline start off paused? (if so it needs to be started with Timeline.play) - * - * @name Phaser.Tweens.Timeline#paused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.paused = false; - - /** - * Elapsed time in ms/frames of this run through of the Timeline. - * - * @name Phaser.Tweens.Timeline#elapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.elapsed = 0; - - /** - * Total elapsed time in ms/frames of the entire Timeline, including looping. - * - * @name Phaser.Tweens.Timeline#totalElapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalElapsed = 0; - - /** - * Time in ms/frames for the whole Timeline to play through once, excluding loop amounts and loop delays. - * - * @name Phaser.Tweens.Timeline#duration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.duration = 0; - - /** - * Value between 0 and 1. The amount of progress through the Timeline, _excluding loops_. - * - * @name Phaser.Tweens.Timeline#progress - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.progress = 0; - - /** - * Time in ms/frames for all Tweens in this Timeline to complete (including looping) - * - * @name Phaser.Tweens.Timeline#totalDuration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalDuration = 0; - - /** - * Value between 0 and 1. The amount through the entire Timeline, including looping. - * - * @name Phaser.Tweens.Timeline#totalProgress - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalProgress = 0; - - /** - * An object containing the different Tween callback functions. - * - * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. - * - * `onComplete` When the Timeline finishes playback fully or `Timeline.stop` is called. Never invoked if timeline is set to repeat infinitely. - * `onLoop` When a Timeline loops. - * `onStart` When the Timeline starts playing. - * `onUpdate` When a Timeline updates a child Tween. - * `onYoyo` When a Timeline starts a yoyo. - * - * @name Phaser.Tweens.Timeline#callbacks - * @type {object} - * @since 3.0.0 - */ - this.callbacks = { - onComplete: null, - onLoop: null, - onStart: null, - onUpdate: null, - onYoyo: null - }; - - /** - * The context in which all callbacks are invoked. - * - * @name Phaser.Tweens.Timeline#callbackScope - * @type {any} - * @since 3.0.0 - */ - this.callbackScope; - }, - - /** - * Internal method that will emit a Timeline based Event and invoke the given callback. - * - * @method Phaser.Tweens.Timeline#dispatchTimelineEvent - * @since 3.19.0 - * - * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. - * @param {function} callback - The callback to be invoked. Can be `null` or `undefined` to skip invocation. - */ - dispatchTimelineEvent: function (event, callback) - { - this.emit(event, this); - - if (callback) - { - callback.func.apply(callback.scope, callback.params); - } - }, - - /** - * Sets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. - * A value of 0.5 runs 50% slower, and so on. - * - * The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only. - * - * @method Phaser.Tweens.Timeline#setTimeScale - * @since 3.0.0 - * - * @param {number} value - The time scale value to set. - * - * @return {this} This Timeline object. - */ - setTimeScale: function (value) - { - this.timeScale = value; - - return this; - }, - - /** - * Gets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. - * A value of 0.5 runs 50% slower, and so on. - * - * @method Phaser.Tweens.Timeline#getTimeScale - * @since 3.0.0 - * - * @return {number} The value of the time scale applied to this Timeline. - */ - getTimeScale: function () - { - return this.timeScale; - }, - - /** - * Check whether or not the Timeline is playing. - * - * @method Phaser.Tweens.Timeline#isPlaying - * @since 3.0.0 - * - * @return {boolean} `true` if this Timeline is active, otherwise `false`. - */ - isPlaying: function () - { - return (this.state === TWEEN_CONST.ACTIVE); - }, - - /** - * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. - * - * @method Phaser.Tweens.Timeline#add - * @since 3.0.0 - * - * @param {(Phaser.Types.Tweens.TweenBuilderConfig|object)} config - The configuration object for the Tween. - * - * @return {this} This Timeline object. - */ - add: function (config) - { - return this.queue(TweenBuilder(this, config)); - }, - - /** - * Adds an existing Tween to this Timeline. - * - * @method Phaser.Tweens.Timeline#queue - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to be added to this Timeline. - * - * @return {this} This Timeline object. - */ - queue: function (tween) - { - if (!this.isPlaying()) - { - tween.parent = this; - tween.parentIsTimeline = true; - - this.data.push(tween); - - this.totalData = this.data.length; - } - - return this; - }, - - /** - * Checks whether a Tween has an offset value. - * - * @method Phaser.Tweens.Timeline#hasOffset - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to check. - * - * @return {boolean} `true` if the tween has a non-null offset. - */ - hasOffset: function (tween) - { - return (tween.offset !== null); - }, - - /** - * Checks whether the offset value is a number or a directive that is relative to previous tweens. - * - * @method Phaser.Tweens.Timeline#isOffsetAbsolute - * @since 3.0.0 - * - * @param {number} value - The offset value to be evaluated. - * - * @return {boolean} `true` if the result is a number, `false` if it is a directive like " -= 1000". - */ - isOffsetAbsolute: function (value) - { - return (typeof(value) === 'number'); - }, - - /** - * Checks if the offset is a relative value rather than an absolute one. - * If the value is just a number, this returns false. - * - * @method Phaser.Tweens.Timeline#isOffsetRelative - * @since 3.0.0 - * - * @param {string} value - The offset value to be evaluated. - * - * @return {boolean} `true` if the value is relative, i.e " -= 1000". If `false`, the offset is absolute. - */ - isOffsetRelative: function (value) - { - var t = typeof(value); - - if (t === 'string') - { - var op = value[0]; - - if (op === '-' || op === '+') - { - return true; - } - } - - return false; - }, - - /** - * Parses the relative offset value, returning a positive or negative number. - * - * @method Phaser.Tweens.Timeline#getRelativeOffset - * @since 3.0.0 - * - * @param {string} value - The relative offset, in the format of '-=500', for example. The first character determines whether it will be a positive or negative number. Spacing matters here. - * @param {number} base - The value to use as the offset. - * - * @return {number} The parsed offset value. - */ - getRelativeOffset: function (value, base) - { - var op = value[0]; - var num = parseFloat(value.substr(2)); - var result = base; - - switch (op) - { - case '+': - result += num; - break; - - case '-': - result -= num; - break; - } - - // Cannot ever be < 0 - return Math.max(0, result); - }, - - /** - * Calculates the total duration of the timeline. - * - * Computes all tween durations and returns the full duration of the timeline. - * - * The resulting number is stored in the timeline, not as a return value. - * - * @method Phaser.Tweens.Timeline#calcDuration - * @since 3.0.0 - */ - calcDuration: function () - { - var prevEnd = 0; - var totalDuration = 0; - var offsetDuration = 0; - - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - tween.init(); - - if (this.hasOffset(tween)) - { - if (this.isOffsetAbsolute(tween.offset)) - { - // An actual number, so it defines the start point from the beginning of the timeline - tween.calculatedOffset = tween.offset; - - if (tween.offset === 0) - { - offsetDuration = 0; - } - } - else if (this.isOffsetRelative(tween.offset)) - { - // A relative offset (i.e. '-=1000', so starts at 'offset' ms relative to the PREVIOUS Tweens ending time) - tween.calculatedOffset = this.getRelativeOffset(tween.offset, prevEnd); - } - } - else - { - // Sequential - tween.calculatedOffset = offsetDuration; - } - - prevEnd = tween.totalDuration + tween.calculatedOffset; - - totalDuration += tween.totalDuration; - offsetDuration += tween.totalDuration; - } - - // Excludes loop values - this.duration = totalDuration; - - this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; - - if (this.loopCounter > 0) - { - this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter); - } - else - { - this.totalDuration = this.duration + this.completeDelay; - } - }, - - /** - * Initializes the timeline, which means all Tweens get their init() called, and the total duration will be computed. - * Returns a boolean indicating whether the timeline is auto-started or not. - * - * @method Phaser.Tweens.Timeline#init - * @since 3.0.0 - * - * @return {boolean} `true` if the Timeline is started. `false` if it is paused. - */ - init: function () - { - this.calcDuration(); - - this.progress = 0; - this.totalProgress = 0; - - if (this.paused) - { - this.state = TWEEN_CONST.PAUSED; - - return false; - } - else - { - return true; - } - }, - - /** - * Resets all of the timeline's tweens back to their initial states. - * The boolean parameter indicates whether tweens that are looping should reset as well, or not. - * - * @method Phaser.Tweens.Timeline#resetTweens - * @since 3.0.0 - * - * @param {boolean} resetFromLoop - If `true`, resets all looping tweens to their initial values. - */ - resetTweens: function (resetFromLoop) - { - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - tween.play(resetFromLoop); - } - }, - - /** - * Sets a callback for the Timeline. - * - * @method Phaser.Tweens.Timeline#setCallback - * @since 3.0.0 - * - * @param {string} type - The internal type of callback to set. - * @param {function} callback - Timeline allows multiple tweens to be linked together to create a streaming sequence. - * @param {array} [params] - The parameters to pass to the callback. - * @param {object} [scope] - The context scope of the callback. - * - * @return {this} This Timeline object. - */ - setCallback: function (type, callback, params, scope) - { - if (Timeline.TYPES.indexOf(type) !== -1) - { - this.callbacks[type] = { func: callback, scope: scope, params: params }; - } - - return this; - }, - - /** - * Passed a Tween to the Tween Manager and requests it be made active. - * - * @method Phaser.Tweens.Timeline#makeActive - * @since 3.3.0 - * - * @param {Phaser.Tweens.Tween} tween - The tween object to make active. - * - * @return {Phaser.Tweens.TweenManager} The Timeline's Tween Manager reference. - */ - makeActive: function (tween) - { - return this.manager.makeActive(tween); - }, - - /** - * Starts playing the Timeline. - * - * @method Phaser.Tweens.Timeline#play - * @fires Phaser.Tweens.Events#TIMELINE_START - * @since 3.0.0 - */ - play: function () - { - if (this.state === TWEEN_CONST.ACTIVE) - { - return; - } - - if (this.paused) - { - this.paused = false; - - this.manager.makeActive(this); - - return; - } - else - { - this.resetTweens(false); - - this.state = TWEEN_CONST.ACTIVE; - } - - this.dispatchTimelineEvent(Events.TIMELINE_START, this.callbacks.onStart); - }, - - /** - * Updates the Timeline's `state` and fires callbacks and events. - * - * @method Phaser.Tweens.Timeline#nextState - * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE - * @fires Phaser.Tweens.Events#TIMELINE_LOOP - * @since 3.0.0 - * - * @see Phaser.Tweens.Timeline#update - */ - nextState: function () - { - if (this.loopCounter > 0) - { - // Reset the elapsed time - this.elapsed = 0; - this.progress = 0; - - this.loopCounter--; - - this.resetTweens(true); - - if (this.loopDelay > 0) - { - this.countdown = this.loopDelay; - - this.state = TWEEN_CONST.LOOP_DELAY; - } - else - { - this.state = TWEEN_CONST.ACTIVE; - - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } - } - else if (this.completeDelay > 0) - { - this.state = TWEEN_CONST.COMPLETE_DELAY; - - this.countdown = this.completeDelay; - } - else - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); - } - }, - - /** - * Returns 'true' if this Timeline has finished and should be removed from the Tween Manager. - * Otherwise, returns false. - * - * @method Phaser.Tweens.Timeline#update - * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE - * @fires Phaser.Tweens.Events#TIMELINE_UPDATE - * @since 3.0.0 - * - * @param {number} timestamp - 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. - * - * @return {boolean} Returns `true` if this Timeline has finished and should be removed from the Tween Manager. - */ - update: function (timestamp, delta) - { - if (this.state === TWEEN_CONST.PAUSED) - { - return; - } - - if (this.useFrames) - { - delta = 1 * this.manager.timeScale; - } - - delta *= this.timeScale; - - this.elapsed += delta; - this.progress = Math.min(this.elapsed / this.duration, 1); - - this.totalElapsed += delta; - this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); - - switch (this.state) - { - case TWEEN_CONST.ACTIVE: - - var stillRunning = this.totalData; - - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - if (tween.update(timestamp, delta)) - { - stillRunning--; - } - } - - this.dispatchTimelineEvent(Events.TIMELINE_UPDATE, this.callbacks.onUpdate); - - // Anything still running? If not, we're done - if (stillRunning === 0) - { - this.nextState(); - } - - break; - - case TWEEN_CONST.LOOP_DELAY: - - this.countdown -= delta; - - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.ACTIVE; - - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } - - break; - - case TWEEN_CONST.COMPLETE_DELAY: - - this.countdown -= delta; - - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); - } - - break; - } - - return (this.state === TWEEN_CONST.PENDING_REMOVE); - }, - - /** - * Stops the Timeline immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. - * - * @method Phaser.Tweens.Timeline#stop - * @since 3.0.0 - */ - stop: function () - { - this.state = TWEEN_CONST.PENDING_REMOVE; - }, - - /** - * Pauses the Timeline, retaining its internal state. - * - * Calling this on a Timeline that is already paused has no effect and fires no event. - * - * @method Phaser.Tweens.Timeline#pause - * @fires Phaser.Tweens.Events#TIMELINE_PAUSE - * @since 3.0.0 - * - * @return {this} This Timeline object. - */ - pause: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - return; - } - - this.paused = true; - - this._pausedState = this.state; - - this.state = TWEEN_CONST.PAUSED; - - this.emit(Events.TIMELINE_PAUSE, this); - - return this; - }, - - /** - * Resumes a paused Timeline from where it was when it was paused. - * - * Calling this on a Timeline that isn't paused has no effect and fires no event. - * - * @method Phaser.Tweens.Timeline#resume - * @fires Phaser.Tweens.Events#TIMELINE_RESUME - * @since 3.0.0 - * - * @return {this} This Timeline object. - */ - resume: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - this.paused = false; - - this.state = this._pausedState; - - this.emit(Events.TIMELINE_RESUME, this); - } - - return this; - }, - - /** - * Checks if any of the Tweens in this Timeline as operating on the target object. - * - * Returns `false` if no Tweens operate on the target object. - * - * @method Phaser.Tweens.Timeline#hasTarget - * @since 3.0.0 - * - * @param {object} target - The target to check all Tweens against. - * - * @return {boolean} `true` if there is at least a single Tween that operates on the target object, otherwise `false`. - */ - hasTarget: function (target) - { - for (var i = 0; i < this.data.length; i++) - { - if (this.data[i].hasTarget(target)) - { - return true; - } - } - - return false; - }, - - /** - * Stops all the Tweens in the Timeline immediately, whatever stage of progress they are at and flags - * them for removal by the TweenManager. - * - * @method Phaser.Tweens.Timeline#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var i = 0; i < this.data.length; i++) - { - this.data[i].stop(); - } - } - -}); - -Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ]; - -module.exports = Timeline; - - -/***/ }), -/* 569 */ -/***/ (function(module, exports, __webpack_require__) { - /** * @author Richard Davey * @author Felipe Alfonso <@bitnenfer> @@ -125523,13 +73485,13 @@ module.exports = Timeline; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CameraEvents = __webpack_require__(34); -var CanvasSnapshot = __webpack_require__(570); +var CameraEvents = __webpack_require__(35); +var CanvasSnapshot = __webpack_require__(363); var Class = __webpack_require__(0); var CONST = __webpack_require__(39); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(94); -var GetBlendModes = __webpack_require__(571); +var Events = __webpack_require__(88); +var GetBlendModes = __webpack_require__(364); var ScaleEvents = __webpack_require__(101); var TextureEvents = __webpack_require__(103); var TransformMatrix = __webpack_require__(25); @@ -126357,7 +74319,7 @@ module.exports = CanvasRenderer; /***/ }), -/* 570 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -126367,7 +74329,7 @@ module.exports = CanvasRenderer; */ var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var GetFastValue = __webpack_require__(2); /** @@ -126450,7 +74412,7 @@ module.exports = CanvasSnapshot; /***/ }), -/* 571 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -126459,7 +74421,7 @@ module.exports = CanvasSnapshot; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var modes = __webpack_require__(38); +var modes = __webpack_require__(33); var CanvasFeatures = __webpack_require__(342); /** @@ -126514,7 +74476,7 @@ module.exports = GetBlendModes; /***/ }), -/* 572 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -126524,22 +74486,22 @@ module.exports = GetBlendModes; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(88); -var CameraEvents = __webpack_require__(34); +var ArrayRemove = __webpack_require__(89); +var CameraEvents = __webpack_require__(35); var Class = __webpack_require__(0); var CONST = __webpack_require__(39); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(94); +var Events = __webpack_require__(88); var GameEvents = __webpack_require__(22); var IsSizePowerOfTwo = __webpack_require__(136); -var Matrix4 = __webpack_require__(65); +var Matrix4 = __webpack_require__(67); var NOOP = __webpack_require__(1); -var PipelineManager = __webpack_require__(573); -var RenderTarget = __webpack_require__(162); +var PipelineManager = __webpack_require__(366); +var RenderTarget = __webpack_require__(139); var ScaleEvents = __webpack_require__(101); var TextureEvents = __webpack_require__(103); var Utils = __webpack_require__(12); -var WebGLSnapshot = __webpack_require__(584); +var WebGLSnapshot = __webpack_require__(377); /** * @callback WebGLContextCallback @@ -129487,7 +77449,7 @@ module.exports = WebGLRenderer; /***/ }), -/* 573 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -129497,18 +77459,18 @@ module.exports = WebGLRenderer; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(72); +var CONST = __webpack_require__(65); var CustomMap = __webpack_require__(99); // Default Phaser 3 Pipelines -var BitmapMaskPipeline = __webpack_require__(574); -var GraphicsPipeline = __webpack_require__(577); -var LightPipeline = __webpack_require__(578); -var MultiPipeline = __webpack_require__(123); -var PointLightPipeline = __webpack_require__(579); -var RopePipeline = __webpack_require__(580); -var SinglePipeline = __webpack_require__(581); -var UtilityPipeline = __webpack_require__(582); +var BitmapMaskPipeline = __webpack_require__(367); +var GraphicsPipeline = __webpack_require__(370); +var LightPipeline = __webpack_require__(371); +var MultiPipeline = __webpack_require__(105); +var PointLightPipeline = __webpack_require__(372); +var RopePipeline = __webpack_require__(373); +var SinglePipeline = __webpack_require__(374); +var UtilityPipeline = __webpack_require__(375); /** * @classdesc @@ -130610,7 +78572,7 @@ module.exports = PipelineManager; /***/ }), -/* 574 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -130624,8 +78586,8 @@ var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var ShaderSourceFS = __webpack_require__(862); var ShaderSourceVS = __webpack_require__(863); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -130808,7 +78770,7 @@ module.exports = BitmapMaskPipeline; /***/ }), -/* 575 */ +/* 368 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -130835,7 +78797,7 @@ module.exports = { /***/ }), -/* 576 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -130846,7 +78808,7 @@ module.exports = { var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var WEBGL_CONST = __webpack_require__(122); +var WEBGL_CONST = __webpack_require__(104); /** * @classdesc @@ -131936,7 +79898,7 @@ module.exports = WebGLShader; /***/ }), -/* 577 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -131947,13 +79909,13 @@ module.exports = WebGLShader; */ var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); +var Earcut = __webpack_require__(68); var GetFastValue = __webpack_require__(2); var ShaderSourceFS = __webpack_require__(871); var ShaderSourceVS = __webpack_require__(872); var TransformMatrix = __webpack_require__(25); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -132619,7 +80581,7 @@ module.exports = GraphicsPipeline; /***/ }), -/* 578 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -132632,9 +80594,9 @@ module.exports = GraphicsPipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var LightShaderSourceFS = __webpack_require__(873); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); var Vec2 = __webpack_require__(3); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); var LIGHT_COUNT = 10; var tempVec2 = new Vec2(); @@ -132994,7 +80956,7 @@ module.exports = LightPipeline; /***/ }), -/* 579 */ +/* 372 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -133007,7 +80969,7 @@ var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var PointLightShaderSourceFS = __webpack_require__(876); var PointLightShaderSourceVS = __webpack_require__(877); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -133168,7 +81130,7 @@ module.exports = PointLightPipeline; /***/ }), -/* 580 */ +/* 373 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -133179,7 +81141,7 @@ module.exports = PointLightPipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); /** * @classdesc @@ -133235,7 +81197,7 @@ module.exports = RopePipeline; /***/ }), -/* 581 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -133246,10 +81208,10 @@ module.exports = RopePipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); var ShaderSourceFS = __webpack_require__(878); var ShaderSourceVS = __webpack_require__(879); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -133312,7 +81274,7 @@ module.exports = SinglePipeline; /***/ }), -/* 582 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -133322,15 +81284,15 @@ module.exports = SinglePipeline; */ var AddBlendFS = __webpack_require__(880); -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); -var ColorMatrix = __webpack_require__(266); +var ColorMatrix = __webpack_require__(195); var ColorMatrixFS = __webpack_require__(881); var CopyFS = __webpack_require__(882); var GetFastValue = __webpack_require__(2); var LinearBlendFS = __webpack_require__(883); -var QuadVS = __webpack_require__(583); -var WebGLPipeline = __webpack_require__(66); +var QuadVS = __webpack_require__(376); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -134103,7 +82065,7 @@ module.exports = UtilityPipeline; /***/ }), -/* 583 */ +/* 376 */ /***/ (function(module, exports) { module.exports = [ @@ -134129,7 +82091,7 @@ module.exports = [ /***/ }), -/* 584 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -134139,7 +82101,7 @@ module.exports = [ */ var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var GetFastValue = __webpack_require__(2); /** @@ -134240,6 +82202,52070 @@ var WebGLSnapshot = function (sourceCanvas, config) module.exports = WebGLSnapshot; +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(39); + +/** + * Called automatically by Phaser.Game and responsible for creating the console.log debug header. + * + * You can customize or disable the header via the Game Config object. + * + * @function Phaser.Core.DebugHeader + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance which will output this debug header. + */ +var DebugHeader = function (game) +{ + var config = game.config; + + if (config.hideBanner) + { + return; + } + + var renderType = 'WebGL'; + + if (config.renderType === CONST.CANVAS) + { + renderType = 'Canvas'; + } + else if (config.renderType === CONST.HEADLESS) + { + renderType = 'Headless'; + } + + var audioConfig = config.audio; + var deviceAudio = game.device.audio; + + var audioType; + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + audioType = 'Web Audio'; + } + else if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + audioType = 'No Audio'; + } + else + { + audioType = 'HTML5 Audio'; + } + + if (!game.device.browser.ie) + { + var c = ''; + var args = [ c ]; + + if (Array.isArray(config.bannerBackgroundColor)) + { + var lastColor; + + config.bannerBackgroundColor.forEach(function (color) + { + c = c.concat('%c '); + + args.push('background: ' + color); + + lastColor = color; + + }); + + // inject the text color + args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; + } + else + { + c = c.concat('%c '); + + args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); + } + + // URL link background color (always white) + args.push('background: #fff'); + + if (config.gameTitle) + { + c = c.concat(config.gameTitle); + + if (config.gameVersion) + { + c = c.concat(' v' + config.gameVersion); + } + + if (!config.hidePhaser) + { + c = c.concat(' / '); + } + } + + var fb = ( false) ? undefined : ''; + + if (!config.hidePhaser) + { + c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); + } + + c = c.concat(' %c ' + config.gameURL); + + // Inject the new string back into the args array + args[0] = c; + + console.log.apply(console, args); + } + else if (window['console']) + { + console.log('Phaser v' + CONST.VERSION + ' / https://phaser.io'); + } +}; + +module.exports = DebugHeader; + + +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetValue = __webpack_require__(6); +var NOOP = __webpack_require__(1); +var RequestAnimationFrame = __webpack_require__(380); + +// http://www.testufo.com/#test=animation-time-graph + +/** + * @classdesc + * The core runner class that Phaser uses to handle the game loop. It can use either Request Animation Frame, + * or SetTimeout, based on browser support and config settings, to create a continuous loop within the browser. + * + * Each time the loop fires, `TimeStep.step` is called and this is then passed onto the core Game update loop, + * it is the core heartbeat of your game. It will fire as often as Request Animation Frame is capable of handling + * on the target device. + * + * Note that there are lots of situations where a browser will stop updating your game. Such as if the player + * switches tabs, or covers up the browser window with another application. In these cases, the 'heartbeat' + * of your game will pause, and only resume when focus is returned to it by the player. There is no way to avoid + * this situation, all you can do is use the visibility events the browser, and Phaser, provide to detect when + * it has happened and then gracefully recover. + * + * @class TimeStep + * @memberof Phaser.Core + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step. + * @param {Phaser.Types.Core.FPSConfig} config + */ +var TimeStep = new Class({ + + initialize: + + function TimeStep (game, config) + { + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Core.TimeStep#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; + + /** + * The Request Animation Frame DOM Event handler. + * + * @name Phaser.Core.TimeStep#raf + * @type {Phaser.DOM.RequestAnimationFrame} + * @readonly + * @since 3.0.0 + */ + this.raf = new RequestAnimationFrame(); + + /** + * A flag that is set once the TimeStep has started running and toggled when it stops. + * + * @name Phaser.Core.TimeStep#started + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.started = false; + + /** + * A flag that is set once the TimeStep has started running and toggled when it stops. + * The difference between this value and `started` is that `running` is toggled when + * the TimeStep is sent to sleep, where-as `started` remains `true`, only changing if + * the TimeStep is actually stopped, not just paused. + * + * @name Phaser.Core.TimeStep#running + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.running = false; + + /** + * The minimum fps rate you want the Time Step to run at. + * + * @name Phaser.Core.TimeStep#minFps + * @type {number} + * @default 5 + * @since 3.0.0 + */ + this.minFps = GetValue(config, 'min', 5); + + /** + * The target fps rate for the Time Step to run at. + * + * Setting this value will not actually change the speed at which the browser runs, that is beyond + * the control of Phaser. Instead, it allows you to determine performance issues and if the Time Step + * is spiraling out of control. + * + * @name Phaser.Core.TimeStep#targetFps + * @type {number} + * @default 60 + * @since 3.0.0 + */ + this.targetFps = GetValue(config, 'target', 60); + + /** + * The minFps value in ms. + * Defaults to 200ms between frames (i.e. super slow!) + * + * @name Phaser.Core.TimeStep#_min + * @type {number} + * @private + * @since 3.0.0 + */ + this._min = 1000 / this.minFps; + + /** + * The targetFps value in ms. + * Defaults to 16.66ms between frames (i.e. normal) + * + * @name Phaser.Core.TimeStep#_target + * @type {number} + * @private + * @since 3.0.0 + */ + this._target = 1000 / this.targetFps; + + /** + * An exponential moving average of the frames per second. + * + * @name Phaser.Core.TimeStep#actualFps + * @type {number} + * @readonly + * @default 60 + * @since 3.0.0 + */ + this.actualFps = this.targetFps; + + /** + * The time at which the next fps rate update will take place. + * When an fps update happens, the `framesThisSecond` value is reset. + * + * @name Phaser.Core.TimeStep#nextFpsUpdate + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.nextFpsUpdate = 0; + + /** + * The number of frames processed this second. + * + * @name Phaser.Core.TimeStep#framesThisSecond + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.framesThisSecond = 0; + + /** + * A callback to be invoked each time the Time Step steps. + * + * @name Phaser.Core.TimeStep#callback + * @type {Phaser.Types.Core.TimeStepCallback} + * @default NOOP + * @since 3.0.0 + */ + this.callback = NOOP; + + /** + * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting + * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time. + * + * @name Phaser.Core.TimeStep#forceSetTimeOut + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.forceSetTimeOut = GetValue(config, 'forceSetTimeOut', false); + + /** + * The time, calculated at the start of the current step, as smoothed by the delta value. + * + * @name Phaser.Core.TimeStep#time + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.time = 0; + + /** + * The time at which the game started running. This value is adjusted if the game is then + * paused and resumes. + * + * @name Phaser.Core.TimeStep#startTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * The time, as returned by `performance.now` of the previous step. + * + * @name Phaser.Core.TimeStep#lastTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lastTime = 0; + + /** + * The current frame the game is on. This counter is incremented once every game step, regardless of how much + * time has passed and is unaffected by delta smoothing. + * + * @name Phaser.Core.TimeStep#frame + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.frame = 0; + + /** + * Is the browser currently considered in focus by the Page Visibility API? + * This value is set in the `blur` method, which is called automatically by the Game instance. + * + * @name Phaser.Core.TimeStep#inFocus + * @type {boolean} + * @readonly + * @default true + * @since 3.0.0 + */ + this.inFocus = true; + + /** + * The timestamp at which the game became paused, as determined by the Page Visibility API. + * + * @name Phaser.Core.TimeStep#_pauseTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._pauseTime = 0; + + /** + * An internal counter to allow for the browser 'cooling down' after coming back into focus. + * + * @name Phaser.Core.TimeStep#_coolDown + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._coolDown = 0; + + /** + * The delta time, in ms, since the last game step. This is a clamped and smoothed average value. + * + * @name Phaser.Core.TimeStep#delta + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.delta = 0; + + /** + * Internal index of the delta history position. + * + * @name Phaser.Core.TimeStep#deltaIndex + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.deltaIndex = 0; + + /** + * Internal array holding the previous delta values, used for delta smoothing. + * + * @name Phaser.Core.TimeStep#deltaHistory + * @type {number[]} + * @since 3.0.0 + */ + this.deltaHistory = []; + + /** + * The maximum number of delta values that are retained in order to calculate a smoothed moving average. + * + * This can be changed in the Game Config via the `fps.deltaHistory` property. The default is 10. + * + * @name Phaser.Core.TimeStep#deltaSmoothingMax + * @type {number} + * @default 10 + * @since 3.0.0 + */ + this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10); + + /** + * The number of frames that the cooldown is set to after the browser panics over the FPS rate, usually + * as a result of switching tabs and regaining focus. + * + * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120. + * + * @name Phaser.Core.TimeStep#panicMax + * @type {number} + * @default 120 + * @since 3.0.0 + */ + this.panicMax = GetValue(config, 'panicMax', 120); + + /** + * The actual elapsed time in ms between one update and the next. + * + * Unlike with `delta`, no smoothing, capping, or averaging is applied to this value. + * So please be careful when using this value in math calculations. + * + * @name Phaser.Core.TimeStep#rawDelta + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.rawDelta = 0; + + /** + * The time, as returned by `performance.now` at the very start of the current step. + * This can differ from the `time` value in that it isn't calculated based on the delta value. + * + * @name Phaser.Core.TimeStep#now + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.now = 0; + + /** + * Apply smoothing to the delta value used within Phasers internal calculations? + * + * This can be changed in the Game Config via the `fps.smoothStep` property. The default is `true`. + * + * Smoothing helps settle down the delta values after browser tab switches, or other situations + * which could cause significant delta spikes or dips. By default it has been enabled in Phaser 3 + * since the first version, but is now exposed under this property (and the corresponding game config + * `smoothStep` value), to allow you to easily disable it, should you require. + * + * @name Phaser.Core.TimeStep#smoothStep + * @type {boolean} + * @since 3.22.0 + */ + this.smoothStep = GetValue(config, 'smoothStep', true); + }, + + /** + * Called by the Game instance when the DOM window.onBlur event triggers. + * + * @method Phaser.Core.TimeStep#blur + * @since 3.0.0 + */ + blur: function () + { + this.inFocus = false; + }, + + /** + * Called by the Game instance when the DOM window.onFocus event triggers. + * + * @method Phaser.Core.TimeStep#focus + * @since 3.0.0 + */ + focus: function () + { + this.inFocus = true; + + this.resetDelta(); + }, + + /** + * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc) + * + * @method Phaser.Core.TimeStep#pause + * @since 3.0.0 + */ + pause: function () + { + this._pauseTime = window.performance.now(); + }, + + /** + * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc) + * + * @method Phaser.Core.TimeStep#resume + * @since 3.0.0 + */ + resume: function () + { + this.resetDelta(); + + this.startTime += this.time - this._pauseTime; + }, + + /** + * Resets the time, lastTime, fps averages and delta history. + * Called automatically when a browser sleeps them resumes. + * + * @method Phaser.Core.TimeStep#resetDelta + * @since 3.0.0 + */ + resetDelta: function () + { + var now = window.performance.now(); + + this.time = now; + this.lastTime = now; + this.nextFpsUpdate = now + 1000; + this.framesThisSecond = 0; + + // Pre-populate smoothing array + + for (var i = 0; i < this.deltaSmoothingMax; i++) + { + this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]); + } + + this.delta = 0; + this.deltaIndex = 0; + + this._coolDown = this.panicMax; + }, + + /** + * Starts the Time Step running, if it is not already doing so. + * Called automatically by the Game Boot process. + * + * @method Phaser.Core.TimeStep#start + * @since 3.0.0 + * + * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps. + */ + start: function (callback) + { + if (this.started) + { + return this; + } + + this.started = true; + this.running = true; + + for (var i = 0; i < this.deltaSmoothingMax; i++) + { + this.deltaHistory[i] = this._target; + } + + this.resetDelta(); + + this.startTime = window.performance.now(); + + this.callback = callback; + + this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target); + }, + + /** + * The main step method. This is called each time the browser updates, either by Request Animation Frame, + * or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more. + * You generally should never call this method directly. + * + * @method Phaser.Core.TimeStep#step + * @since 3.0.0 + */ + step: function () + { + // Because the timestamp passed in from raf represents the beginning of the main thread frame that we’re currently in, + // not the actual time now, and as we want to compare this time value against Event timeStamps and the like, we need a + // more accurate one: + + var time = window.performance.now(); + + this.now = time; + + var before = time - this.lastTime; + + if (before < 0) + { + // Because, Chrome. + before = 0; + } + + this.rawDelta = before; + + var idx = this.deltaIndex; + var history = this.deltaHistory; + var max = this.deltaSmoothingMax; + + // delta time (time is in ms) + var dt = before; + + // Delta Average + var avg = before; + + // When a browser switches tab, then comes back again, it takes around 10 frames before + // the delta time settles down so we employ a 'cooling down' period before we start + // trusting the delta values again, to avoid spikes flooding through our delta average + + if (this.smoothStep) + { + if (this._coolDown > 0 || !this.inFocus) + { + this._coolDown--; + + dt = Math.min(dt, this._target); + } + + if (dt > this._min) + { + // Probably super bad start time or browser tab context loss, + // so use the last 'sane' dt value + + dt = history[idx]; + + // Clamp delta to min (in case history has become corrupted somehow) + dt = Math.min(dt, this._min); + } + + // Smooth out the delta over the previous X frames + + // add the delta to the smoothing array + history[idx] = dt; + + // adjusts the delta history array index based on the smoothing count + // this stops the array growing beyond the size of deltaSmoothingMax + this.deltaIndex++; + + if (this.deltaIndex > max) + { + this.deltaIndex = 0; + } + + // Loop the history array, adding the delta values together + avg = 0; + + for (var i = 0; i < max; i++) + { + avg += history[i]; + } + + // Then divide by the array length to get the average delta + avg /= max; + } + + // Set as the world delta value + this.delta = avg; + + // Real-world timer advance + this.time += this.rawDelta; + + // Update the estimate of the frame rate, `fps`. Every second, the number + // of frames that occurred in that second are included in an exponential + // moving average of all frames per second, with an alpha of 0.25. This + // means that more recent seconds affect the estimated frame rate more than + // older seconds. + // + // When a browser window is NOT minimized, but is covered up (i.e. you're using + // another app which has spawned a window over the top of the browser), then it + // will start to throttle the raf callback time. It waits for a while, and then + // starts to drop the frame rate at 1 frame per second until it's down to just over 1fps. + // So if the game was running at 60fps, and the player opens a new window, then + // after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz. + // + // When they make the game visible again, the frame rate is increased at a rate of + // approx. 8fps, back up to 60fps (or the max it can obtain) + // + // There is no easy way to determine if this drop in frame rate is because the + // browser is throttling raf, or because the game is struggling with performance + // because you're asking it to do too much on the device. + + if (time > this.nextFpsUpdate) + { + // Compute the new exponential moving average with an alpha of 0.25. + this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps; + this.nextFpsUpdate = time + 1000; + this.framesThisSecond = 0; + } + + this.framesThisSecond++; + + // Interpolation - how far between what is expected and where we are? + var interpolation = avg / this._target; + + this.callback(time, avg, interpolation); + + // Shift time value over + this.lastTime = time; + + this.frame++; + }, + + /** + * Manually calls `TimeStep.step`. + * + * @method Phaser.Core.TimeStep#tick + * @since 3.0.0 + */ + tick: function () + { + this.step(); + }, + + /** + * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false. + * + * @method Phaser.Core.TimeStep#sleep + * @since 3.0.0 + */ + sleep: function () + { + if (this.running) + { + this.raf.stop(); + + this.running = false; + } + }, + + /** + * Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true. + * The `seamless` argument controls if the wake-up should adjust the start time or not. + * + * @method Phaser.Core.TimeStep#wake + * @since 3.0.0 + * + * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values. + */ + wake: function (seamless) + { + if (this.running) + { + return; + } + else if (seamless) + { + this.startTime += -this.lastTime + (this.lastTime + window.performance.now()); + } + + this.raf.start(this.step.bind(this), this.useRAF); + + this.running = true; + + this.step(); + }, + + /** + * Gets the duration which the game has been running, in seconds. + * + * @method Phaser.Core.TimeStep#getDuration + * @since 3.17.0 + * + * @return {number} The duration in seconds. + */ + getDuration: function () + { + return Math.round(this.lastTime - this.startTime) / 1000; + }, + + /** + * Gets the duration which the game has been running, in ms. + * + * @method Phaser.Core.TimeStep#getDurationMS + * @since 3.17.0 + * + * @return {number} The duration in ms. + */ + getDurationMS: function () + { + return Math.round(this.lastTime - this.startTime); + }, + + /** + * Stops the TimeStep running. + * + * @method Phaser.Core.TimeStep#stop + * @since 3.0.0 + * + * @return {this} The TimeStep object. + */ + stop: function () + { + this.running = false; + this.started = false; + + this.raf.stop(); + + return this; + }, + + /** + * Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null + * any objects. + * + * @method Phaser.Core.TimeStep#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stop(); + + this.callback = NOOP; + + this.raf = null; + this.game = null; + } + +}); + +module.exports = TimeStep; + + +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * Abstracts away the use of RAF or setTimeOut for the core game update loop. + * This is invoked automatically by the Phaser.Game instance. + * + * @class RequestAnimationFrame + * @memberof Phaser.DOM + * @constructor + * @since 3.0.0 + */ +var RequestAnimationFrame = new Class({ + + initialize: + + function RequestAnimationFrame () + { + /** + * True if RequestAnimationFrame is running, otherwise false. + * + * @name Phaser.DOM.RequestAnimationFrame#isRunning + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isRunning = false; + + /** + * The callback to be invoked each step. + * + * @name Phaser.DOM.RequestAnimationFrame#callback + * @type {FrameRequestCallback} + * @since 3.0.0 + */ + this.callback = NOOP; + + /** + * The most recent timestamp. Either a DOMHighResTimeStamp under RAF or `Date.now` under SetTimeout. + * + * @name Phaser.DOM.RequestAnimationFrame#tick + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.tick = 0; + + /** + * True if the step is using setTimeout instead of RAF. + * + * @name Phaser.DOM.RequestAnimationFrame#isSetTimeOut + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isSetTimeOut = false; + + /** + * The setTimeout or RAF callback ID used when canceling them. + * + * @name Phaser.DOM.RequestAnimationFrame#timeOutID + * @type {?number} + * @default null + * @since 3.0.0 + */ + this.timeOutID = null; + + /** + * The previous time the step was called. + * + * @name Phaser.DOM.RequestAnimationFrame#lastTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lastTime = 0; + + /** + * The target FPS rate in ms. + * Only used when setTimeout is used instead of RAF. + * + * @name Phaser.DOM.RequestAnimationFrame#target + * @type {number} + * @default 0 + * @since 3.21.0 + */ + this.target = 0; + + var _this = this; + + /** + * The RAF step function. + * Updates the local tick value, invokes the callback and schedules another call to requestAnimationFrame. + * + * @name Phaser.DOM.RequestAnimationFrame#step + * @type {FrameRequestCallback} + * @since 3.0.0 + */ + this.step = function step () + { + // Because we cannot trust the time passed to this callback from the browser and need it kept in sync with event times + var timestamp = window.performance.now(); + + // DOMHighResTimeStamp + _this.lastTime = _this.tick; + + _this.tick = timestamp; + + _this.callback(timestamp); + + _this.timeOutID = window.requestAnimationFrame(step); + }; + + /** + * The SetTimeout step function. + * Updates the local tick value, invokes the callback and schedules another call to setTimeout. + * + * @name Phaser.DOM.RequestAnimationFrame#stepTimeout + * @type {function} + * @since 3.0.0 + */ + this.stepTimeout = function stepTimeout () + { + var d = Date.now(); + + var delay = Math.min(Math.max(_this.target * 2 + _this.tick - d, 0), _this.target); + + _this.lastTime = _this.tick; + + _this.tick = d; + + _this.callback(d); + + _this.timeOutID = window.setTimeout(stepTimeout, delay); + }; + }, + + /** + * Starts the requestAnimationFrame or setTimeout process running. + * + * @method Phaser.DOM.RequestAnimationFrame#start + * @since 3.0.0 + * + * @param {FrameRequestCallback} callback - The callback to invoke each step. + * @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available? + * @param {number} targetFPS - The target fps rate (in ms). Only used when setTimeout is used. + */ + start: function (callback, forceSetTimeOut, targetFPS) + { + if (this.isRunning) + { + return; + } + + this.callback = callback; + + this.isSetTimeOut = forceSetTimeOut; + + this.target = targetFPS; + + this.isRunning = true; + + this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); + }, + + /** + * Stops the requestAnimationFrame or setTimeout from running. + * + * @method Phaser.DOM.RequestAnimationFrame#stop + * @since 3.0.0 + */ + stop: function () + { + this.isRunning = false; + + if (this.isSetTimeOut) + { + clearTimeout(this.timeOutID); + } + else + { + window.cancelAnimationFrame(this.timeOutID); + } + }, + + /** + * Stops the step from running and clears the callback reference. + * + * @method Phaser.DOM.RequestAnimationFrame#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stop(); + + this.callback = NOOP; + } + +}); + +module.exports = RequestAnimationFrame; + + +/***/ }), +/* 381 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Events = __webpack_require__(22); + +/** + * The Visibility Handler is responsible for listening out for document level visibility change events. + * This includes `visibilitychange` if the browser supports it, and blur and focus events. It then uses + * the provided Event Emitter and fires the related events. + * + * @function Phaser.Core.VisibilityHandler + * @fires Phaser.Core.Events#BLUR + * @fires Phaser.Core.Events#FOCUS + * @fires Phaser.Core.Events#HIDDEN + * @fires Phaser.Core.Events#VISIBLE + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. + */ +var VisibilityHandler = function (game) +{ + var hiddenVar; + var eventEmitter = game.events; + + if (document.hidden !== undefined) + { + hiddenVar = 'visibilitychange'; + } + else + { + var vendors = [ 'webkit', 'moz', 'ms' ]; + + vendors.forEach(function (prefix) + { + if (document[prefix + 'Hidden'] !== undefined) + { + document.hidden = function () + { + return document[prefix + 'Hidden']; + }; + + hiddenVar = prefix + 'visibilitychange'; + } + + }); + } + + var onChange = function (event) + { + if (document.hidden || event.type === 'pause') + { + eventEmitter.emit(Events.HIDDEN); + } + else + { + eventEmitter.emit(Events.VISIBLE); + } + }; + + if (hiddenVar) + { + document.addEventListener(hiddenVar, onChange, false); + } + + window.onblur = function () + { + eventEmitter.emit(Events.BLUR); + }; + + window.onfocus = function () + { + eventEmitter.emit(Events.FOCUS); + }; + + // Automatically give the window focus unless config says otherwise + if (window.focus && game.config.autoFocus) + { + window.focus(); + } +}; + +module.exports = VisibilityHandler; + + +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Arne16 = __webpack_require__(383); +var CanvasPool = __webpack_require__(31); +var GetValue = __webpack_require__(6); + +/** + * Generates a texture based on the given Create configuration object. + * + * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the + * data cells map to a single color. For example, if the texture config looked like this: + * + * ```javascript + * var star = [ + * '.....828.....', + * '....72227....', + * '....82228....', + * '...7222227...', + * '2222222222222', + * '8222222222228', + * '.72222222227.', + * '..787777787..', + * '..877777778..', + * '.78778887787.', + * '.27887.78872.', + * '.787.....787.' + * ]; + * + * this.textures.generate('star', { data: star, pixelWidth: 4 }); + * ``` + * + * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array + * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color + * number 8 in the palette. If a cell contains a period character `.` then it is transparent. + * + * The default palette is Arne16, but you can specify your own using the `palette` property. + * + * @function Phaser.Create.GenerateTexture + * @since 3.0.0 + * + * @param {Phaser.Types.Create.GenerateTextureConfig} config - The Generate Texture Configuration object. + * + * @return {HTMLCanvasElement} An HTMLCanvasElement which contains the generated texture drawn to it. + */ +var GenerateTexture = function (config) +{ + var data = GetValue(config, 'data', []); + var canvas = GetValue(config, 'canvas', null); + var palette = GetValue(config, 'palette', Arne16); + var pixelWidth = GetValue(config, 'pixelWidth', 1); + var pixelHeight = GetValue(config, 'pixelHeight', pixelWidth); + var resizeCanvas = GetValue(config, 'resizeCanvas', true); + var clearCanvas = GetValue(config, 'clearCanvas', true); + var preRender = GetValue(config, 'preRender', null); + var postRender = GetValue(config, 'postRender', null); + + var width = Math.floor(Math.abs(data[0].length * pixelWidth)); + var height = Math.floor(Math.abs(data.length * pixelHeight)); + + if (!canvas) + { + canvas = CanvasPool.create2D(this, width, height); + resizeCanvas = false; + clearCanvas = false; + } + + if (resizeCanvas) + { + canvas.width = width; + canvas.height = height; + } + + var ctx = canvas.getContext('2d'); + + if (clearCanvas) + { + ctx.clearRect(0, 0, width, height); + } + + // preRender Callback? + if (preRender) + { + preRender(canvas, ctx); + } + + // Draw it + for (var y = 0; y < data.length; y++) + { + var row = data[y]; + + for (var x = 0; x < row.length; x++) + { + var d = row[x]; + + if (d !== '.' && d !== ' ') + { + ctx.fillStyle = palette[d]; + ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight); + } + } + } + + // postRender Callback? + if (postRender) + { + postRender(canvas, ctx); + } + + return canvas; +}; + +module.exports = GenerateTexture; + + +/***/ }), +/* 383 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A 16 color palette by [Arne](http://androidarts.com/palette/16pal.htm) + * + * @name Phaser.Create.Palettes.ARNE16 + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.exports = { + 0: '#000', + 1: '#9D9D9D', + 2: '#FFF', + 3: '#BE2633', + 4: '#E06F8B', + 5: '#493C2B', + 6: '#A46422', + 7: '#EB8931', + 8: '#F7E26B', + 9: '#2F484E', + A: '#44891A', + B: '#A3CE27', + C: '#1B2632', + D: '#005784', + E: '#31A2F2', + F: '#B2DCEF' +}; + + +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var CubicBezier = __webpack_require__(352); +var Curve = __webpack_require__(90); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A higher-order Bézier curve constructed of four points. + * + * @class CubicBezier + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector2[])} p0 - Start point, or an array of point pairs. + * @param {Phaser.Math.Vector2} p1 - Control Point 1. + * @param {Phaser.Math.Vector2} p2 - Control Point 2. + * @param {Phaser.Math.Vector2} p3 - End Point. + */ +var CubicBezierCurve = new Class({ + + Extends: Curve, + + initialize: + + function CubicBezierCurve (p0, p1, p2, p3) + { + Curve.call(this, 'CubicBezierCurve'); + + if (Array.isArray(p0)) + { + p3 = new Vector2(p0[6], p0[7]); + p2 = new Vector2(p0[4], p0[5]); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The start point of this curve. + * + * @name Phaser.Curves.CubicBezier#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = p0; + + /** + * The first control point of this curve. + * + * @name Phaser.Curves.CubicBezier#p1 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p1 = p1; + + /** + * The second control point of this curve. + * + * @name Phaser.Curves.CubicBezier#p2 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p2 = p2; + + /** + * The end point of this curve. + * + * @name Phaser.Curves.CubicBezier#p3 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p3 = p3; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.CubicBezier#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Returns the resolution of this curve. + * + * @method Phaser.Curves.CubicBezier#getResolution + * @since 3.0.0 + * + * @param {number} divisions - The amount of divisions used by this curve. + * + * @return {number} The resolution of the curve. + */ + getResolution: function (divisions) + { + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.CubicBezier#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var p0 = this.p0; + var p1 = this.p1; + var p2 = this.p2; + var p3 = this.p3; + + return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y)); + }, + + /** + * Draws this curve to the specified graphics object. + * + * @method Phaser.Curves.CubicBezier#draw + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - The graphics object this curve should be drawn to. + * @param {number} [pointsTotal=32] - The number of intermediary points that make up this curve. A higher number of points will result in a smoother curve. + * + * @return {Phaser.GameObjects.Graphics} The graphics object this curve was drawn to. Useful for method chaining. + */ + draw: function (graphics, pointsTotal) + { + if (pointsTotal === undefined) { pointsTotal = 32; } + + var points = this.getPoints(pointsTotal); + + graphics.beginPath(); + graphics.moveTo(this.p0.x, this.p0.y); + + for (var i = 1; i < points.length; i++) + { + graphics.lineTo(points[i].x, points[i].y); + } + + graphics.strokePath(); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Returns a JSON object that describes this curve. + * + * @method Phaser.Curves.CubicBezier#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y, + this.p2.x, this.p2.y, + this.p3.x, this.p3.y + ] + }; + } + +}); + +/** + * Generates a curve from a JSON object. + * + * @function Phaser.Curves.CubicBezier.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.CubicBezier} The curve generated from the JSON object. + */ +CubicBezierCurve.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + var p2 = new Vector2(points[4], points[5]); + var p3 = new Vector2(points[6], points[7]); + + return new CubicBezierCurve(p0, p1, p2, p3); +}; + +module.exports = CubicBezierCurve; + + +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var DegToRad = __webpack_require__(34); +var GetValue = __webpack_require__(6); +var RadToDeg = __webpack_require__(193); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * An Elliptical Curve derived from the Base Curve class. + * + * See https://en.wikipedia.org/wiki/Elliptic_curve for more details. + * + * @class Ellipse + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(number|Phaser.Types.Curves.EllipseCurveConfig)} [x=0] - The x coordinate of the ellipse, or an Ellipse Curve configuration object. + * @param {number} [y=0] - The y coordinate of the ellipse. + * @param {number} [xRadius=0] - The horizontal radius of ellipse. + * @param {number} [yRadius=0] - The vertical radius of ellipse. + * @param {number} [startAngle=0] - The start angle of the ellipse, in degrees. + * @param {number} [endAngle=360] - The end angle of the ellipse, in degrees. + * @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`). + * @param {number} [rotation=0] - The rotation of the ellipse, in degrees. + */ +var EllipseCurve = new Class({ + + Extends: Curve, + + initialize: + + function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) + { + if (typeof x === 'object') + { + var config = x; + + x = GetValue(config, 'x', 0); + y = GetValue(config, 'y', 0); + xRadius = GetValue(config, 'xRadius', 0); + yRadius = GetValue(config, 'yRadius', xRadius); + startAngle = GetValue(config, 'startAngle', 0); + endAngle = GetValue(config, 'endAngle', 360); + clockwise = GetValue(config, 'clockwise', false); + rotation = GetValue(config, 'rotation', 0); + } + else + { + if (yRadius === undefined) { yRadius = xRadius; } + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 360; } + if (clockwise === undefined) { clockwise = false; } + if (rotation === undefined) { rotation = 0; } + } + + Curve.call(this, 'EllipseCurve'); + + // Center point + + /** + * The center point of the ellipse. Used for calculating rotation. + * + * @name Phaser.Curves.Ellipse#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = new Vector2(x, y); + + /** + * The horizontal radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#_xRadius + * @type {number} + * @private + * @since 3.0.0 + */ + this._xRadius = xRadius; + + /** + * The vertical radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#_yRadius + * @type {number} + * @private + * @since 3.0.0 + */ + this._yRadius = yRadius; + + // Radians + + /** + * The starting angle of the ellipse in radians. + * + * @name Phaser.Curves.Ellipse#_startAngle + * @type {number} + * @private + * @since 3.0.0 + */ + this._startAngle = DegToRad(startAngle); + + /** + * The end angle of the ellipse in radians. + * + * @name Phaser.Curves.Ellipse#_endAngle + * @type {number} + * @private + * @since 3.0.0 + */ + this._endAngle = DegToRad(endAngle); + + /** + * Anti-clockwise direction. + * + * @name Phaser.Curves.Ellipse#_clockwise + * @type {boolean} + * @private + * @since 3.0.0 + */ + this._clockwise = clockwise; + + /** + * The rotation of the arc. + * + * @name Phaser.Curves.Ellipse#_rotation + * @type {number} + * @private + * @since 3.0.0 + */ + this._rotation = DegToRad(rotation); + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Ellipse#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return this.getPoint(0, out); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.Ellipse#getResolution + * @since 3.0.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions * 2; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Ellipse#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var twoPi = Math.PI * 2; + var deltaAngle = this._endAngle - this._startAngle; + var samePoints = Math.abs(deltaAngle) < Number.EPSILON; + + // ensures that deltaAngle is 0 .. 2 PI + while (deltaAngle < 0) + { + deltaAngle += twoPi; + } + + while (deltaAngle > twoPi) + { + deltaAngle -= twoPi; + } + + if (deltaAngle < Number.EPSILON) + { + if (samePoints) + { + deltaAngle = 0; + } + else + { + deltaAngle = twoPi; + } + } + + if (this._clockwise && !samePoints) + { + if (deltaAngle === twoPi) + { + deltaAngle = - twoPi; + } + else + { + deltaAngle = deltaAngle - twoPi; + } + } + + var angle = this._startAngle + t * deltaAngle; + var x = this.p0.x + this._xRadius * Math.cos(angle); + var y = this.p0.y + this._yRadius * Math.sin(angle); + + if (this._rotation !== 0) + { + var cos = Math.cos(this._rotation); + var sin = Math.sin(this._rotation); + + var tx = x - this.p0.x; + var ty = y - this.p0.y; + + // Rotate the point about the center of the ellipse. + x = tx * cos - ty * sin + this.p0.x; + y = tx * sin + ty * cos + this.p0.y; + } + + return out.set(x, y); + }, + + /** + * Sets the horizontal radius of this curve. + * + * @method Phaser.Curves.Ellipse#setXRadius + * @since 3.0.0 + * + * @param {number} value - The horizontal radius of this curve. + * + * @return {this} This curve object. + */ + setXRadius: function (value) + { + this.xRadius = value; + + return this; + }, + + /** + * Sets the vertical radius of this curve. + * + * @method Phaser.Curves.Ellipse#setYRadius + * @since 3.0.0 + * + * @param {number} value - The vertical radius of this curve. + * + * @return {this} This curve object. + */ + setYRadius: function (value) + { + this.yRadius = value; + + return this; + }, + + /** + * Sets the width of this curve. + * + * @method Phaser.Curves.Ellipse#setWidth + * @since 3.0.0 + * + * @param {number} value - The width of this curve. + * + * @return {this} This curve object. + */ + setWidth: function (value) + { + this.xRadius = value / 2; + + return this; + }, + + /** + * Sets the height of this curve. + * + * @method Phaser.Curves.Ellipse#setHeight + * @since 3.0.0 + * + * @param {number} value - The height of this curve. + * + * @return {this} This curve object. + */ + setHeight: function (value) + { + this.yRadius = value / 2; + + return this; + }, + + /** + * Sets the start angle of this curve. + * + * @method Phaser.Curves.Ellipse#setStartAngle + * @since 3.0.0 + * + * @param {number} value - The start angle of this curve, in radians. + * + * @return {this} This curve object. + */ + setStartAngle: function (value) + { + this.startAngle = value; + + return this; + }, + + /** + * Sets the end angle of this curve. + * + * @method Phaser.Curves.Ellipse#setEndAngle + * @since 3.0.0 + * + * @param {number} value - The end angle of this curve, in radians. + * + * @return {this} This curve object. + */ + setEndAngle: function (value) + { + this.endAngle = value; + + return this; + }, + + /** + * Sets if this curve extends clockwise or anti-clockwise. + * + * @method Phaser.Curves.Ellipse#setClockwise + * @since 3.0.0 + * + * @param {boolean} value - The clockwise state of this curve. + * + * @return {this} This curve object. + */ + setClockwise: function (value) + { + this.clockwise = value; + + return this; + }, + + /** + * Sets the rotation of this curve. + * + * @method Phaser.Curves.Ellipse#setRotation + * @since 3.0.0 + * + * @param {number} value - The rotation of this curve, in radians. + * + * @return {this} This curve object. + */ + setRotation: function (value) + { + this.rotation = value; + + return this; + }, + + /** + * The x coordinate of the center of the ellipse. + * + * @name Phaser.Curves.Ellipse#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.p0.x; + }, + + set: function (value) + { + this.p0.x = value; + } + + }, + + /** + * The y coordinate of the center of the ellipse. + * + * @name Phaser.Curves.Ellipse#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.p0.y; + }, + + set: function (value) + { + this.p0.y = value; + } + + }, + + /** + * The horizontal radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#xRadius + * @type {number} + * @since 3.0.0 + */ + xRadius: { + + get: function () + { + return this._xRadius; + }, + + set: function (value) + { + this._xRadius = value; + } + + }, + + /** + * The vertical radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#yRadius + * @type {number} + * @since 3.0.0 + */ + yRadius: { + + get: function () + { + return this._yRadius; + }, + + set: function (value) + { + this._yRadius = value; + } + + }, + + /** + * The start angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#startAngle + * @type {number} + * @since 3.0.0 + */ + startAngle: { + + get: function () + { + return RadToDeg(this._startAngle); + }, + + set: function (value) + { + this._startAngle = DegToRad(value); + } + + }, + + /** + * The end angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#endAngle + * @type {number} + * @since 3.0.0 + */ + endAngle: { + + get: function () + { + return RadToDeg(this._endAngle); + }, + + set: function (value) + { + this._endAngle = DegToRad(value); + } + + }, + + /** + * `true` if the ellipse rotation is clockwise or `false` if anti-clockwise. + * + * @name Phaser.Curves.Ellipse#clockwise + * @type {boolean} + * @since 3.0.0 + */ + clockwise: { + + get: function () + { + return this._clockwise; + }, + + set: function (value) + { + this._clockwise = value; + } + + }, + + /** + * The rotation of the ellipse, relative to the center, in degrees. + * + * @name Phaser.Curves.Ellipse#angle + * @type {number} + * @since 3.14.0 + */ + angle: { + + get: function () + { + return RadToDeg(this._rotation); + }, + + set: function (value) + { + this._rotation = DegToRad(value); + } + + }, + + /** + * The rotation of the ellipse, relative to the center, in radians. + * + * @name Phaser.Curves.Ellipse#rotation + * @type {number} + * @since 3.0.0 + */ + rotation: { + + get: function () + { + return this._rotation; + }, + + set: function (value) + { + this._rotation = value; + } + + }, + + /** + * JSON serialization of the curve. + * + * @method Phaser.Curves.Ellipse#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONEllipseCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + x: this.p0.x, + y: this.p0.y, + xRadius: this._xRadius, + yRadius: this._yRadius, + startAngle: RadToDeg(this._startAngle), + endAngle: RadToDeg(this._endAngle), + clockwise: this._clockwise, + rotation: RadToDeg(this._rotation) + }; + } + +}); + +/** + * Creates a curve from the provided Ellipse Curve Configuration object. + * + * @function Phaser.Curves.Ellipse.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. + */ +EllipseCurve.fromJSON = function (data) +{ + return new EllipseCurve(data); +}; + +module.exports = EllipseCurve; + + +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var FromPoints = __webpack_require__(196); +var Rectangle = __webpack_require__(10); +var Vector2 = __webpack_require__(3); + +var tmpVec2 = new Vector2(); + +/** + * @classdesc + * A LineCurve is a "curve" comprising exactly two points (a line segment). + * + * @class Line + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. + * @param {Phaser.Math.Vector2} [p1] - The second endpoint. + */ +var LineCurve = new Class({ + + Extends: Curve, + + initialize: + + // vec2s or array + function LineCurve (p0, p1) + { + Curve.call(this, 'LineCurve'); + + if (Array.isArray(p0)) + { + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The first endpoint. + * + * @name Phaser.Curves.Line#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = p0; + + /** + * The second endpoint. + * + * @name Phaser.Curves.Line#p1 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p1 = p1; + + // Override default Curve.arcLengthDivisions + + /** + * The quantity of arc length divisions within the curve. + * + * @name Phaser.Curves.Line#arcLengthDivisions + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.arcLengthDivisions = 1; + }, + + /** + * Returns a Rectangle where the position and dimensions match the bounds of this Curve. + * + * @method Phaser.Curves.Line#getBounds + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the bounds in. If not given a new Rectangle will be created. + * + * @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object. + */ + getBounds: function (out) + { + if (out === undefined) { out = new Rectangle(); } + + return FromPoints([ this.p0, this.p1 ], out); + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Line#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Gets the resolution of the line. + * + * @method Phaser.Curves.Line#getResolution + * @since 3.0.0 + * + * @param {number} [divisions=1] - The number of divisions to consider. + * + * @return {number} The resolution. Equal to the number of divisions. + */ + getResolution: function (divisions) + { + if (divisions === undefined) { divisions = 1; } + + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Line#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + if (t === 1) + { + return out.copy(this.p1); + } + + out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); + + return out; + }, + + // Line curve is linear, so we can overwrite default getPointAt + + /** + * Gets a point at a given position on the line. + * + * @method Phaser.Curves.Line#getPointAt + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} u - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPointAt: function (u, out) + { + return this.getPoint(u, out); + }, + + /** + * Gets the slope of the line as a unit vector. + * + * @method Phaser.Curves.Line#getTangent + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @return {Phaser.Math.Vector2} The tangent vector. + */ + getTangent: function () + { + var tangent = tmpVec2.copy(this.p1).subtract(this.p0); + + return tangent.normalize(); + }, + + /** + * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. + * + * @method Phaser.Curves.Line#getUtoTmapping + * @since 3.0.0 + * + * @param {number} u - A float between 0 and 1. + * @param {number} distance - The distance, in pixels. + * @param {number} [divisions] - Optional amount of divisions. + * + * @return {number} The equidistant value. + */ + getUtoTmapping: function (u, distance, divisions) + { + var t; + + if (distance) + { + var arcLengths = this.getLengths(divisions); + var lineLength = arcLengths[arcLengths.length - 1]; + + // Cannot overshoot the curve + var targetLineLength = Math.min(distance, lineLength); + + t = targetLineLength / lineLength; + } + else + { + t = u; + } + + return t; + }, + + // Override default Curve.draw because this is better than calling getPoints on a line! + + /** + * Draws this curve on the given Graphics object. + * + * The curve is drawn using `Graphics.lineBetween` so will be drawn at whatever the present Graphics line color is. + * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. + * + * @method Phaser.Curves.Line#draw + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn. + * + * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. + */ + draw: function (graphics) + { + graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Gets a JSON representation of the line. + * + * @method Phaser.Curves.Line#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y + ] + }; + } + +}); + +/** + * Configures this line from a JSON representation. + * + * @function Phaser.Curves.Line.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Line} A new LineCurve object. + */ +LineCurve.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + + return new LineCurve(p0, p1); +}; + +module.exports = LineCurve; + + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A MoveTo Curve is a very simple curve consisting of only a single point. + * Its intended use is to move the ending point in a Path. + * + * @class MoveTo + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - `x` pixel coordinate. + * @param {number} [y=0] - `y` pixel coordinate. + */ +var MoveTo = new Class({ + + initialize: + + function MoveTo (x, y) + { + /** + * Denotes that this Curve does not influence the bounds, points, and drawing of its parent Path. Must be `false` or some methods in the parent Path will throw errors. + * + * @name Phaser.Curves.MoveTo#active + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.active = false; + + /** + * The lone point which this curve consists of. + * + * @name Phaser.Curves.MoveTo#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = new Vector2(x, y); + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.MoveTo#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Retrieves the point at given position in the curve. This will always return this curve's only point. + * + * @method Phaser.Curves.MoveTo#getPointAt + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} u - The position in the path to retrieve, between 0 and 1. Not used. + * @param {Phaser.Math.Vector2} [out] - An optional vector in which to store the point. + * + * @return {Phaser.Math.Vector2} The modified `out` vector, or a new `Vector2` if none was provided. + */ + getPointAt: function (u, out) + { + return this.getPoint(u, out); + }, + + /** + * Gets the resolution of this curve. + * + * @method Phaser.Curves.MoveTo#getResolution + * @since 3.0.0 + * + * @return {number} The resolution of this curve. For a MoveTo the value is always 1. + */ + getResolution: function () + { + return 1; + }, + + /** + * Gets the length of this curve. + * + * @method Phaser.Curves.MoveTo#getLength + * @since 3.0.0 + * + * @return {number} The length of this curve. For a MoveTo the value is always 0. + */ + getLength: function () + { + return 0; + }, + + /** + * Converts this curve into a JSON-serializable object. + * + * @method Phaser.Curves.MoveTo#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} A primitive object with the curve's type and only point. + */ + toJSON: function () + { + return { + type: 'MoveTo', + points: [ + this.p0.x, this.p0.y + ] + }; + } + +}); + +module.exports = MoveTo; + + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var QuadraticBezierInterpolation = __webpack_require__(353); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A quadratic Bézier curve constructed from two control points. + * + * @class QuadraticBezier + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.2.0 + * + * @param {(Phaser.Math.Vector2|number[])} p0 - Start point, or an array of point pairs. + * @param {Phaser.Math.Vector2} p1 - Control Point 1. + * @param {Phaser.Math.Vector2} p2 - Control Point 2. + */ +var QuadraticBezier = new Class({ + + Extends: Curve, + + initialize: + + function QuadraticBezier (p0, p1, p2) + { + Curve.call(this, 'QuadraticBezier'); + + if (Array.isArray(p0)) + { + p2 = new Vector2(p0[4], p0[5]); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The start point. + * + * @name Phaser.Curves.QuadraticBezier#p0 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p0 = p0; + + /** + * The first control point. + * + * @name Phaser.Curves.QuadraticBezier#p1 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p1 = p1; + + /** + * The second control point. + * + * @name Phaser.Curves.QuadraticBezier#p2 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p2 = p2; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.QuadraticBezier#getStartPoint + * @since 3.2.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.QuadraticBezier#getResolution + * @since 3.2.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.QuadraticBezier#getPoint + * @since 3.2.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var p0 = this.p0; + var p1 = this.p1; + var p2 = this.p2; + + return out.set( + QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x), + QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y) + ); + }, + + /** + * Draws this curve on the given Graphics object. + * + * The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is. + * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. + * + * @method Phaser.Curves.QuadraticBezier#draw + * @since 3.2.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - `Graphics` object to draw onto. + * @param {number} [pointsTotal=32] - Number of points to be used for drawing the curve. Higher numbers result in smoother curve but require more processing. + * + * @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to. + */ + draw: function (graphics, pointsTotal) + { + if (pointsTotal === undefined) { pointsTotal = 32; } + + var points = this.getPoints(pointsTotal); + + graphics.beginPath(); + graphics.moveTo(this.p0.x, this.p0.y); + + for (var i = 1; i < points.length; i++) + { + graphics.lineTo(points[i].x, points[i].y); + } + + graphics.strokePath(); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Converts the curve into a JSON compatible object. + * + * @method Phaser.Curves.QuadraticBezier#toJSON + * @since 3.2.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y, + this.p2.x, this.p2.y + ] + }; + } + +}); + +/** + * Creates a curve from a JSON object, e. g. created by `toJSON`. + * + * @function Phaser.Curves.QuadraticBezier.fromJSON + * @since 3.2.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.QuadraticBezier} The created curve instance. + */ +QuadraticBezier.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + var p2 = new Vector2(points[4], points[5]); + + return new QuadraticBezier(p0, p1, p2); +}; + +module.exports = QuadraticBezier; + + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var CatmullRom = __webpack_require__(191); +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * Create a smooth 2d spline curve from a series of points. + * + * @class Spline + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2[]|number[]|number[][])} [points] - The points that configure the curve. + */ +var SplineCurve = new Class({ + + Extends: Curve, + + initialize: + + function SplineCurve (points) + { + if (points === undefined) { points = []; } + + Curve.call(this, 'SplineCurve'); + + /** + * The Vector2 points that configure the curve. + * + * @name Phaser.Curves.Spline#points + * @type {Phaser.Math.Vector2[]} + * @default [] + * @since 3.0.0 + */ + this.points = []; + + this.addPoints(points); + }, + + /** + * Add a list of points to the current list of Vector2 points of the curve. + * + * @method Phaser.Curves.Spline#addPoints + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve. + * + * @return {this} This curve object. + */ + addPoints: function (points) + { + for (var i = 0; i < points.length; i++) + { + var p = new Vector2(); + + if (typeof points[i] === 'number') + { + p.x = points[i]; + p.y = points[i + 1]; + i++; + } + else if (Array.isArray(points[i])) + { + // An array of arrays? + p.x = points[i][0]; + p.y = points[i][1]; + } + else + { + p.x = points[i].x; + p.y = points[i].y; + } + + this.points.push(p); + } + + return this; + }, + + /** + * Add a point to the current list of Vector2 points of the curve. + * + * @method Phaser.Curves.Spline#addPoint + * @since 3.0.0 + * + * @param {number} x - The x coordinate of this curve + * @param {number} y - The y coordinate of this curve + * + * @return {Phaser.Math.Vector2} The new Vector2 added to the curve + */ + addPoint: function (x, y) + { + var vec = new Vector2(x, y); + + this.points.push(vec); + + return vec; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Spline#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.points[0]); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.Spline#getResolution + * @since 3.0.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions * this.points.length; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Spline#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var points = this.points; + + var point = (points.length - 1) * t; + + var intPoint = Math.floor(point); + + var weight = point - intPoint; + + var p0 = points[(intPoint === 0) ? intPoint : intPoint - 1]; + var p1 = points[intPoint]; + var p2 = points[(intPoint > points.length - 2) ? points.length - 1 : intPoint + 1]; + var p3 = points[(intPoint > points.length - 3) ? points.length - 1 : intPoint + 2]; + + return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); + }, + + /** + * Exports a JSON object containing this curve data. + * + * @method Phaser.Curves.Spline#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + var points = []; + + for (var i = 0; i < this.points.length; i++) + { + points.push(this.points[i].x); + points.push(this.points[i].y); + } + + return { + type: this.type, + points: points + }; + } + +}); + +/** + * Imports a JSON object containing this curve data. + * + * @function Phaser.Curves.Spline.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Spline} The spline curve created. + */ +SplineCurve.fromJSON = function (data) +{ + return new SplineCurve(data.points); +}; + +module.exports = SplineCurve; + + +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A BaseShader is a small resource class that contains the data required for a WebGL Shader to be created. + * + * It contains the raw source code to the fragment and vertex shader, as well as an object that defines + * the uniforms the shader requires, if any. + * + * BaseShaders are stored in the Shader Cache, available in a Scene via `this.cache.shaders` and are referenced + * by a unique key-based string. Retrieve them via `this.cache.shaders.get(key)`. + * + * BaseShaders are created automatically by the GLSL File Loader when loading an external shader resource. + * They can also be created at runtime, allowing you to use dynamically generated shader source code. + * + * Default fragment and vertex source is used if not provided in the constructor, setting-up a basic shader, + * suitable for debug rendering. + * + * @class BaseShader + * @memberof Phaser.Display + * @constructor + * @since 3.17.0 + * + * @param {string} key - The key of this shader. Must be unique within the shader cache. + * @param {string} [fragmentSrc] - The fragment source for the shader. + * @param {string} [vertexSrc] - The vertex source for the shader. + * @param {any} [uniforms] - Optional object defining the uniforms the shader uses. + */ +var BaseShader = new Class({ + + initialize: + + function BaseShader (key, fragmentSrc, vertexSrc, uniforms) + { + if (!fragmentSrc || fragmentSrc === '') + { + fragmentSrc = [ + 'precision mediump float;', + + 'uniform vec2 resolution;', + + 'varying vec2 fragCoord;', + + 'void main () {', + ' vec2 uv = fragCoord / resolution.xy;', + ' gl_FragColor = vec4(uv.xyx, 1.0);', + '}' + ].join('\n'); + } + + if (!vertexSrc || vertexSrc === '') + { + vertexSrc = [ + 'precision mediump float;', + + 'uniform mat4 uProjectionMatrix;', + 'uniform mat4 uViewMatrix;', + 'uniform vec2 uResolution;', + + 'attribute vec2 inPosition;', + + 'varying vec2 fragCoord;', + 'varying vec2 outTexCoord;', + + 'void main () {', + ' gl_Position = uProjectionMatrix * uViewMatrix * vec4(inPosition, 1.0, 1.0);', + ' fragCoord = vec2(inPosition.x, uResolution.y - inPosition.y);', + ' outTexCoord = vec2(inPosition.x / uResolution.x, fragCoord.y / uResolution.y);', + '}' + ].join('\n'); + } + + if (uniforms === undefined) { uniforms = null; } + + /** + * The key of this shader, unique within the shader cache of this Phaser game instance. + * + * @name Phaser.Display.BaseShader#key + * @type {string} + * @since 3.17.0 + */ + this.key = key; + + /** + * The source code, as a string, of the fragment shader being used. + * + * @name Phaser.Display.BaseShader#fragmentSrc + * @type {string} + * @since 3.17.0 + */ + this.fragmentSrc = fragmentSrc; + + /** + * The source code, as a string, of the vertex shader being used. + * + * @name Phaser.Display.BaseShader#vertexSrc + * @type {string} + * @since 3.17.0 + */ + this.vertexSrc = vertexSrc; + + /** + * The default uniforms for this shader. + * + * @name Phaser.Display.BaseShader#uniforms + * @type {?any} + * @since 3.17.0 + */ + this.uniforms = uniforms; + } + +}); + +module.exports = BaseShader; + + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Color = __webpack_require__(36); + +Color.ColorSpectrum = __webpack_require__(905); +Color.ColorToRGBA = __webpack_require__(906); +Color.ComponentToHex = __webpack_require__(392); +Color.GetColor = __webpack_require__(100); +Color.GetColor32 = __webpack_require__(322); +Color.HexStringToColor = __webpack_require__(321); +Color.HSLToColor = __webpack_require__(907); +Color.HSVColorWheel = __webpack_require__(908); +Color.HSVToRGB = __webpack_require__(185); +Color.HueToComponent = __webpack_require__(393); +Color.IntegerToColor = __webpack_require__(186); +Color.IntegerToRGB = __webpack_require__(324); +Color.Interpolate = __webpack_require__(909); +Color.ObjectToColor = __webpack_require__(325); +Color.RandomRGB = __webpack_require__(910); +Color.RGBStringToColor = __webpack_require__(326); +Color.RGBToHSV = __webpack_require__(323); +Color.RGBToString = __webpack_require__(911); +Color.ValueToColor = __webpack_require__(184); + +module.exports = Color; + + +/***/ }), +/* 392 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns a string containing a hex representation of the given color component. + * + * @function Phaser.Display.Color.ComponentToHex + * @since 3.0.0 + * + * @param {number} color - The color channel to get the hex value for, must be a value between 0 and 255. + * + * @return {string} A string of length 2 characters, i.e. 255 = ff, 100 = 64. + */ +var ComponentToHex = function (color) +{ + var hex = color.toString(16); + + return (hex.length === 1) ? '0' + hex : hex; +}; + +module.exports = ComponentToHex; + + +/***/ }), +/* 393 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts a hue to an RGB color. + * Based on code by Michael Jackson (https://github.com/mjijackson) + * + * @function Phaser.Display.Color.HueToComponent + * @since 3.0.0 + * + * @param {number} p + * @param {number} q + * @param {number} t + * + * @return {number} The combined color value. + */ +var HueToComponent = function (p, q, t) +{ + if (t < 0) + { + t += 1; + } + + if (t > 1) + { + t -= 1; + } + + if (t < 1 / 6) + { + return p + (q - p) * 6 * t; + } + + if (t < 1 / 2) + { + return q; + } + + if (t < 2 / 3) + { + return p + (q - p) * (2 / 3 - t) * 6; + } + + return p; +}; + +module.exports = HueToComponent; + + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var OS = __webpack_require__(102); + +/** + * @callback ContentLoadedCallback + */ + +/** + * Inspects the readyState of the document. If the document is already complete then it invokes the given callback. + * If not complete it sets up several event listeners such as `deviceready`, and once those fire, it invokes the callback. + * Called automatically by the Phaser.Game instance. Should not usually be accessed directly. + * + * @function Phaser.DOM.DOMContentLoaded + * @since 3.0.0 + * + * @param {ContentLoadedCallback} callback - The callback to be invoked when the device is ready and the DOM content is loaded. + */ +var DOMContentLoaded = function (callback) +{ + if (document.readyState === 'complete' || document.readyState === 'interactive') + { + callback(); + + return; + } + + var check = function () + { + document.removeEventListener('deviceready', check, true); + document.removeEventListener('DOMContentLoaded', check, true); + window.removeEventListener('load', check, true); + + callback(); + }; + + if (!document.body) + { + window.setTimeout(check, 20); + } + else if (OS.cordova) + { + // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready + document.addEventListener('deviceready', check, false); + } + else + { + document.addEventListener('DOMContentLoaded', check, true); + window.addEventListener('load', check, true); + } +}; + +module.exports = DOMContentLoaded; + + +/***/ }), +/* 395 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Attempts to determine the document inner height across iOS and standard devices. + * Based on code by @tylerjpeterson + * + * @function Phaser.DOM.GetInnerHeight + * @since 3.16.0 + * + * @param {boolean} iOS - Is this running on iOS? + * + * @return {number} The inner height value. + */ +var GetInnerHeight = function (iOS) +{ + + if (!iOS) + { + return window.innerHeight; + } + + var axis = Math.abs(window.orientation); + + var size = { w: 0, h: 0 }; + + var ruler = document.createElement('div'); + + ruler.setAttribute('style', 'position: fixed; height: 100vh; width: 0; top: 0'); + + document.documentElement.appendChild(ruler); + + size.w = (axis === 90) ? ruler.offsetHeight : window.innerWidth; + size.h = (axis === 90) ? window.innerWidth : ruler.offsetHeight; + + document.documentElement.removeChild(ruler); + + ruler = null; + + if (Math.abs(window.orientation) !== 90) + { + return size.h; + } + else + { + return size.w; + } +}; + +module.exports = GetInnerHeight; + + +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(198); + +/** + * Attempts to determine the screen orientation using the Orientation API. + * + * @function Phaser.DOM.GetScreenOrientation + * @since 3.16.0 + * + * @param {number} width - The width of the viewport. + * @param {number} height - The height of the viewport. + * + * @return {string} The orientation. + */ +var GetScreenOrientation = function (width, height) +{ + var screen = window.screen; + var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; + + if (orientation && typeof orientation.type === 'string') + { + // Screen Orientation API specification + return orientation.type; + } + else if (typeof orientation === 'string') + { + // moz / ms-orientation are strings + return orientation; + } + + if (typeof window.orientation === 'number') + { + // Do this check first, as iOS supports this, but also has an incomplete window.screen implementation + // This may change by device based on "natural" orientation. + return (window.orientation === 0 || window.orientation === 180) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; + } + else if (window.matchMedia) + { + if (window.matchMedia('(orientation: portrait)').matches) + { + return CONST.ORIENTATION.PORTRAIT; + } + else if (window.matchMedia('(orientation: landscape)').matches) + { + return CONST.ORIENTATION.LANDSCAPE; + } + } + else + { + return (height > width) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; + } +}; + +module.exports = GetScreenOrientation; + + +/***/ }), +/* 397 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for centering the game canvas. + * + * @namespace Phaser.Scale.Center + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for centering the game canvas. + * + * To find out what each mode does please see [Phaser.Scale.Center]{@link Phaser.Scale.Center}. + * + * @typedef {Phaser.Scale.Center} Phaser.Scale.CenterType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * The game canvas is not centered within the parent by Phaser. + * You can still center it yourself via CSS. + * + * @name Phaser.Scale.Center.NO_CENTER + * @type {number} + * @const + * @since 3.16.0 + */ + NO_CENTER: 0, + + /** + * The game canvas is centered both horizontally and vertically within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_BOTH + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_BOTH: 1, + + /** + * The game canvas is centered horizontally within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_HORIZONTALLY + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_HORIZONTALLY: 2, + + /** + * The game canvas is centered both vertically within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_VERTICALLY + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_VERTICALLY: 3 + +}; + + +/***/ }), +/* 398 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for orientation. + * + * @namespace Phaser.Scale.Orientation + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for orientation. + * + * To find out what each mode does please see [Phaser.Scale.Orientation]{@link Phaser.Scale.Orientation}. + * + * @typedef {Phaser.Scale.Orientation} Phaser.Scale.OrientationType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * A landscape orientation. + * + * @name Phaser.Scale.Orientation.LANDSCAPE + * @type {string} + * @const + * @since 3.16.0 + */ + LANDSCAPE: 'landscape-primary', + + /** + * A portrait orientation. + * + * @name Phaser.Scale.Orientation.PORTRAIT + * @type {string} + * @const + * @since 3.16.0 + */ + PORTRAIT: 'portrait-primary' + +}; + + +/***/ }), +/* 399 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for the different scale modes available. + * + * @namespace Phaser.Scale.ScaleModes + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for the different scale modes available. + * + * To find out what each mode does please see [Phaser.Scale.ScaleModes]{@link Phaser.Scale.ScaleModes}. + * + * @typedef {Phaser.Scale.ScaleModes} Phaser.Scale.ScaleModeType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * No scaling happens at all. The canvas is set to the size given in the game config and Phaser doesn't change it + * again from that point on. If you change the canvas size, either via CSS, or directly via code, then you need + * to call the Scale Managers `resize` method to give the new dimensions, or input events will stop working. + * + * @name Phaser.Scale.ScaleModes.NONE + * @type {number} + * @const + * @since 3.16.0 + */ + NONE: 0, + + /** + * The height is automatically adjusted based on the width. + * + * @name Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT + * @type {number} + * @const + * @since 3.16.0 + */ + WIDTH_CONTROLS_HEIGHT: 1, + + /** + * The width is automatically adjusted based on the height. + * + * @name Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH + * @type {number} + * @const + * @since 3.16.0 + */ + HEIGHT_CONTROLS_WIDTH: 2, + + /** + * The width and height are automatically adjusted to fit inside the given target area, + * while keeping the aspect ratio. Depending on the aspect ratio there may be some space + * inside the area which is not covered. + * + * @name Phaser.Scale.ScaleModes.FIT + * @type {number} + * @const + * @since 3.16.0 + */ + FIT: 3, + + /** + * The width and height are automatically adjusted to make the size cover the entire target + * area while keeping the aspect ratio. This may extend further out than the target size. + * + * @name Phaser.Scale.ScaleModes.ENVELOP + * @type {number} + * @const + * @since 3.16.0 + */ + ENVELOP: 4, + + /** + * The Canvas is resized to fit all available _parent_ space, regardless of aspect ratio. + * + * @name Phaser.Scale.ScaleModes.RESIZE + * @type {number} + * @const + * @since 3.16.0 + */ + RESIZE: 5 + +}; + + +/***/ }), +/* 400 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for zoom modes. + * + * @namespace Phaser.Scale.Zoom + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for zoom modes. + * + * To find out what each mode does please see [Phaser.Scale.Zoom]{@link Phaser.Scale.Zoom}. + * + * @typedef {Phaser.Scale.Zoom} Phaser.Scale.ZoomType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * The game canvas will not be zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.NO_ZOOM + * @type {number} + * @const + * @since 3.16.0 + */ + NO_ZOOM: 1, + + /** + * The game canvas will be 2x zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.ZOOM_2X + * @type {number} + * @const + * @since 3.16.0 + */ + ZOOM_2X: 2, + + /** + * The game canvas will be 4x zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.ZOOM_4X + * @type {number} + * @const + * @since 3.16.0 + */ + ZOOM_4X: 4, + + /** + * Calculate the zoom value based on the maximum multiplied game size that will + * fit into the parent, or browser window if no parent is set. + * + * @name Phaser.Scale.Zoom.MAX_ZOOM + * @type {number} + * @const + * @since 3.16.0 + */ + MAX_ZOOM: -1 + +}; + + +/***/ }), +/* 401 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Attempts to get the target DOM element based on the given value, which can be either + * a string, in which case it will be looked-up by ID, or an element node. If nothing + * can be found it will return a reference to the document.body. + * + * @function Phaser.DOM.GetTarget + * @since 3.16.0 + * + * @param {HTMLElement} element - The DOM element to look-up. + */ +var GetTarget = function (element) +{ + var target; + + if (element !== '') + { + if (typeof element === 'string') + { + // Hopefully an element ID + target = document.getElementById(element); + } + else if (element && element.nodeType === 1) + { + // Quick test for a HTMLElement + target = element; + } + } + + // Fallback to the document body. Covers an invalid ID and a non HTMLElement object. + if (!target) + { + // Use the full window + target = document.body; + } + + return target; +}; + +module.exports = GetTarget; + + +/***/ }), +/* 402 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Takes the given data string and parses it as XML. + * First tries to use the window.DOMParser and reverts to the Microsoft.XMLDOM if that fails. + * The parsed XML object is returned, or `null` if there was an error while parsing the data. + * + * @function Phaser.DOM.ParseXML + * @since 3.0.0 + * + * @param {string} data - The XML source stored in a string. + * + * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. + */ +var ParseXML = function (data) +{ + var xml = ''; + + try + { + if (window['DOMParser']) + { + var domparser = new DOMParser(); + xml = domparser.parseFromString(data, 'text/xml'); + } + else + { + xml = new ActiveXObject('Microsoft.XMLDOM'); + xml.loadXML(data); + } + } + catch (e) + { + xml = null; + } + + if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) + { + return null; + } + else + { + return xml; + } +}; + +module.exports = ParseXML; + + +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(200); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(49); +var GameEvents = __webpack_require__(22); +var Keyboard = __webpack_require__(404); +var Mouse = __webpack_require__(405); +var Pointer = __webpack_require__(406); +var Touch = __webpack_require__(407); +var TransformMatrix = __webpack_require__(25); +var TransformXY = __webpack_require__(174); + +/** + * @classdesc + * The Input Manager is responsible for handling the pointer related systems in a single Phaser Game instance. + * + * Based on the Game Config it will create handlers for mouse and touch support. + * + * Keyboard and Gamepad are plugins, handled directly by the InputPlugin class. + * + * It then manages the events, pointer creation and general hit test related operations. + * + * You rarely need to interact with the Input Manager directly, and as such, all of its properties and methods + * should be considered private. Instead, you should use the Input Plugin, which is a Scene level system, responsible + * for dealing with all input events for a Scene. + * + * @class InputManager + * @memberof Phaser.Input + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Game instance that owns the Input Manager. + * @param {object} config - The Input Configuration object, as set in the Game Config. + */ +var InputManager = new Class({ + + initialize: + + function InputManager (game, config) + { + /** + * The Game instance that owns the Input Manager. + * A Game only maintains on instance of the Input Manager at any time. + * + * @name Phaser.Input.InputManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; + + /** + * A reference to the global Game Scale Manager. + * Used for all bounds checks and pointer scaling. + * + * @name Phaser.Input.InputManager#scaleManager + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.0 + */ + this.scaleManager; + + /** + * The Canvas that is used for all DOM event input listeners. + * + * @name Phaser.Input.InputManager#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.canvas; + + /** + * The Game Configuration object, as set during the game boot. + * + * @name Phaser.Input.InputManager#config + * @type {Phaser.Core.Config} + * @since 3.0.0 + */ + this.config = config; + + /** + * If set, the Input Manager will run its update loop every frame. + * + * @name Phaser.Input.InputManager#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * The Event Emitter instance that the Input Manager uses to emit events from. + * + * @name Phaser.Input.InputManager#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = new EventEmitter(); + + /** + * Are any mouse or touch pointers currently over the game canvas? + * This is updated automatically by the canvas over and out handlers. + * + * @name Phaser.Input.InputManager#isOver + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + this.isOver = true; + + /** + * The default CSS cursor to be used when interacting with your game. + * + * See the `setDefaultCursor` method for more details. + * + * @name Phaser.Input.InputManager#defaultCursor + * @type {string} + * @since 3.10.0 + */ + this.defaultCursor = ''; + + /** + * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. + * + * @name Phaser.Input.InputManager#keyboard + * @type {?Phaser.Input.Keyboard.KeyboardManager} + * @since 3.16.0 + */ + this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; + + /** + * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. + * + * @name Phaser.Input.InputManager#mouse + * @type {?Phaser.Input.Mouse.MouseManager} + * @since 3.0.0 + */ + this.mouse = (config.inputMouse) ? new Mouse(this) : null; + + /** + * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. + * + * @name Phaser.Input.InputManager#touch + * @type {Phaser.Input.Touch.TouchManager} + * @since 3.0.0 + */ + this.touch = (config.inputTouch) ? new Touch(this) : null; + + /** + * An array of Pointers that have been added to the game. + * The first entry is reserved for the Mouse Pointer, the rest are Touch Pointers. + * + * By default there is 1 touch pointer enabled. If you need more use the `addPointer` method to start them, + * or set the `input.activePointers` property in the Game Config. + * + * @name Phaser.Input.InputManager#pointers + * @type {Phaser.Input.Pointer[]} + * @since 3.10.0 + */ + this.pointers = []; + + /** + * The number of touch objects activated and being processed each update. + * + * You can change this by either calling `addPointer` at run-time, or by + * setting the `input.activePointers` property in the Game Config. + * + * @name Phaser.Input.InputManager#pointersTotal + * @type {number} + * @readonly + * @since 3.10.0 + */ + this.pointersTotal = config.inputActivePointers; + + if (config.inputTouch && this.pointersTotal === 1) + { + this.pointersTotal = 2; + } + + for (var i = 0; i <= this.pointersTotal; i++) + { + var pointer = new Pointer(this, i); + + pointer.smoothFactor = config.inputSmoothFactor; + + this.pointers.push(pointer); + } + + /** + * The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_. + * If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer` + * which will always map to the most recently interacted pointer. + * + * @name Phaser.Input.InputManager#mousePointer + * @type {?Phaser.Input.Pointer} + * @since 3.10.0 + */ + this.mousePointer = (config.inputMouse) ? this.pointers[0] : null; + + /** + * The most recently active Pointer object. + * + * If you've only 1 Pointer in your game then this will accurately be either the first finger touched, or the mouse. + * + * If your game doesn't need to support multi-touch then you can safely use this property in all of your game + * code and it will adapt to be either the mouse or the touch, based on device. + * + * @name Phaser.Input.InputManager#activePointer + * @type {Phaser.Input.Pointer} + * @since 3.0.0 + */ + this.activePointer = this.pointers[0]; + + /** + * If the top-most Scene in the Scene List receives an input it will stop input from + * propagating any lower down the scene list, i.e. if you have a UI Scene at the top + * and click something on it, that click will not then be passed down to any other + * Scene below. Disable this to have input events passed through all Scenes, all the time. + * + * @name Phaser.Input.InputManager#globalTopOnly + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.globalTopOnly = true; + + /** + * The time this Input Manager was last updated. + * This value is populated by the Game Step each frame. + * + * @name Phaser.Input.InputManager#time + * @type {number} + * @readonly + * @since 3.16.2 + */ + this.time = 0; + + /** + * A re-cycled point-like object to store hit test values in. + * + * @name Phaser.Input.InputManager#_tempPoint + * @type {{x:number, y:number}} + * @private + * @since 3.0.0 + */ + this._tempPoint = { x: 0, y: 0 }; + + /** + * A re-cycled array to store hit results in. + * + * @name Phaser.Input.InputManager#_tempHitTest + * @type {array} + * @private + * @default [] + * @since 3.0.0 + */ + this._tempHitTest = []; + + /** + * A re-cycled matrix used in hit test calculations. + * + * @name Phaser.Input.InputManager#_tempMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.4.0 + */ + this._tempMatrix = new TransformMatrix(); + + /** + * A re-cycled matrix used in hit test calculations. + * + * @name Phaser.Input.InputManager#_tempMatrix2 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + /** + * An internal private var that records Scenes aborting event processing. + * + * @name Phaser.Input.InputManager#_tempSkip + * @type {boolean} + * @private + * @since 3.18.0 + */ + this._tempSkip = false; + + /** + * An internal private array that avoids needing to create a new array on every DOM mouse event. + * + * @name Phaser.Input.InputManager#mousePointerContainer + * @type {Phaser.Input.Pointer[]} + * @private + * @since 3.18.0 + */ + this.mousePointerContainer = [ this.mousePointer ]; + + game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot handler is called by Phaser.Game when it first starts up. + * The renderer is available by now. + * + * @method Phaser.Input.InputManager#boot + * @protected + * @fires Phaser.Input.Events#MANAGER_BOOT + * @since 3.0.0 + */ + boot: function () + { + this.canvas = this.game.canvas; + + this.scaleManager = this.game.scale; + + this.events.emit(Events.MANAGER_BOOT); + + this.game.events.on(GameEvents.PRE_RENDER, this.preRender, this); + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * Internal canvas state change, called automatically by the Mouse Manager. + * + * @method Phaser.Input.InputManager#setCanvasOver + * @fires Phaser.Input.Events#GAME_OVER + * @private + * @since 3.16.0 + * + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + */ + setCanvasOver: function (event) + { + this.isOver = true; + + this.events.emit(Events.GAME_OVER, event); + }, + + /** + * Internal canvas state change, called automatically by the Mouse Manager. + * + * @method Phaser.Input.InputManager#setCanvasOut + * @fires Phaser.Input.Events#GAME_OUT + * @private + * @since 3.16.0 + * + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + */ + setCanvasOut: function (event) + { + this.isOver = false; + + this.events.emit(Events.GAME_OUT, event); + }, + + /** + * Internal update, called automatically by the Game Step right at the start. + * + * @method Phaser.Input.InputManager#preRender + * @private + * @since 3.18.0 + */ + preRender: function () + { + var time = this.game.loop.now; + var delta = this.game.loop.delta; + var scenes = this.game.scene.getScenes(true, true); + + this.time = time; + + this.events.emit(Events.MANAGER_UPDATE); + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene.sys.input && scene.sys.input.updatePoll(time, delta) && this.globalTopOnly) + { + // If the Scene returns true, it means it captured some input that no other Scene should get, so we bail out + return; + } + } + }, + + /** + * Tells the Input system to set a custom cursor. + * + * This cursor will be the default cursor used when interacting with the game canvas. + * + * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. + * + * Any valid CSS cursor value is allowed, including paths to image files, i.e.: + * + * ```javascript + * this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer'); + * ``` + * + * Please read about the differences between browsers when it comes to the file formats and sizes they support: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor + * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property + * + * It's up to you to pick a suitable cursor format that works across the range of browsers you need to support. + * + * @method Phaser.Input.InputManager#setDefaultCursor + * @since 3.10.0 + * + * @param {string} cursor - The CSS to be used when setting the default cursor. + */ + setDefaultCursor: function (cursor) + { + this.defaultCursor = cursor; + + if (this.canvas.style.cursor !== cursor) + { + this.canvas.style.cursor = cursor; + } + }, + + /** + * Called by the InputPlugin when processing over and out events. + * + * Tells the Input Manager to set a custom cursor during its postUpdate step. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor + * + * @method Phaser.Input.InputManager#setCursor + * @private + * @since 3.10.0 + * + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. + */ + setCursor: function (interactiveObject) + { + if (interactiveObject.cursor) + { + this.canvas.style.cursor = interactiveObject.cursor; + } + }, + + /** + * Called by the InputPlugin when processing over and out events. + * + * Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step. + * + * @method Phaser.Input.InputManager#resetCursor + * @private + * @since 3.10.0 + * + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. + */ + resetCursor: function (interactiveObject) + { + if (interactiveObject.cursor && this.canvas) + { + this.canvas.style.cursor = this.defaultCursor; + } + }, + + /** + * Adds new Pointer objects to the Input Manager. + * + * By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`. + * + * You can create more either by calling this method, or by setting the `input.activePointers` property + * in the Game Config, up to a maximum of 10 pointers. + * + * The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added + * via this method. + * + * @method Phaser.Input.InputManager#addPointer + * @since 3.10.0 + * + * @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total. + * + * @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created. + */ + addPointer: function (quantity) + { + if (quantity === undefined) { quantity = 1; } + + var output = []; + + if (this.pointersTotal + quantity > 10) + { + quantity = 10 - this.pointersTotal; + } + + for (var i = 0; i < quantity; i++) + { + var id = this.pointers.length; + + var pointer = new Pointer(this, id); + + pointer.smoothFactor = this.config.inputSmoothFactor; + + this.pointers.push(pointer); + + this.pointersTotal++; + + output.push(pointer); + } + + return output; + }, + + /** + * Internal method that gets a list of all the active Input Plugins in the game + * and updates each of them in turn, in reverse order (top to bottom), to allow + * for DOM top-level event handling simulation. + * + * @method Phaser.Input.InputManager#updateInputPlugins + * @since 3.16.0 + * + * @param {number} type - The type of event to process. + * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. + */ + updateInputPlugins: function (type, pointers) + { + var scenes = this.game.scene.getScenes(true, true); + + this._tempSkip = false; + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene.sys.input) + { + var capture = scene.sys.input.update(type, pointers); + + if ((capture && this.globalTopOnly) || this._tempSkip) + { + // If the Scene returns true, or called stopPropagation, it means it captured some input that no other Scene should get, so we bail out + return; + } + } + } + }, + + // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element) + // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + + /** + * Processes a touch start event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchStart + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchStart: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (!pointer.active) + { + pointer.touchstart(changedTouch, event); + + this.activePointer = pointer; + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_START, changed); + }, + + /** + * Processes a touch move event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchMove + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchMove: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchmove(changedTouch, event); + + this.activePointer = pointer; + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_MOVE, changed); + }, + + // For touch end its a list of the touch points that have been removed from the surface + // https://developer.mozilla.org/en-US/docs/DOM/TouchList + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + + /** + * Processes a touch end event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchEnd + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchEnd: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchend(changedTouch, event); + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_END, changed); + }, + + /** + * Processes a touch cancel event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchCancel + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchCancel: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchcancel(changedTouch, event); + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_CANCEL, changed); + }, + + /** + * Processes a mouse down event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseDown + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseDown: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.down(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer); + }, + + /** + * Processes a mouse move event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseMove + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseMove: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.move(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer); + }, + + /** + * Processes a mouse up event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseUp + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseUp: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.up(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); + }, + + /** + * Processes a mouse wheel event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseWheel + * @private + * @since 3.18.0 + * + * @param {WheelEvent} event - The native DOM Wheel event. + */ + onMouseWheel: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.wheel(event); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer); + }, + + /** + * Processes a pointer lock change event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onPointerLockChange + * @fires Phaser.Input.Events#POINTERLOCK_CHANGE + * @private + * @since 3.19.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onPointerLockChange: function (event) + { + var isLocked = this.mouse.locked; + + this.mousePointer.locked = isLocked; + + this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked); + }, + + /** + * Checks if the given Game Object should be considered as a candidate for input or not. + * + * Checks if the Game Object has an input component that is enabled, that it will render, + * and finally, if it has a parent, that the parent parent, or any ancestor, is visible or not. + * + * @method Phaser.Input.InputManager#inputCandidate + * @private + * @since 3.10.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to test. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * + * @return {boolean} `true` if the Game Object should be considered for input, otherwise `false`. + */ + inputCandidate: function (gameObject, camera) + { + var input = gameObject.input; + + if (!input || !input.enabled || (!input.alwaysEnabled && !gameObject.willRender(camera))) + { + return false; + } + + var visible = true; + var parent = gameObject.parentContainer; + + if (parent) + { + do + { + if (!parent.willRender(camera)) + { + visible = false; + break; + } + + parent = parent.parentContainer; + + } while (parent); + } + + return visible; + }, + + /** + * Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects. + * + * The Game Objects are culled against the camera, and then the coordinates are translated into the local camera space + * and used to determine if they fall within the remaining Game Objects hit areas or not. + * + * If nothing is matched an empty array is returned. + * + * This method is called automatically by InputPlugin.hitTestPointer and doesn't usually need to be invoked directly. + * + * @method Phaser.Input.InputManager#hitTest + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to test against. + * @param {array} gameObjects - An array of interactive Game Objects to check. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * @param {array} [output] - An array to store the results in. If not given, a new empty array is created. + * + * @return {array} An array of the Game Objects that were hit during this hit test. + */ + hitTest: function (pointer, gameObjects, camera, output) + { + if (output === undefined) { output = this._tempHitTest; } + + var tempPoint = this._tempPoint; + + var csx = camera.scrollX; + var csy = camera.scrollY; + + output.length = 0; + + var x = pointer.x; + var y = pointer.y; + + // Stores the world point inside of tempPoint + camera.getWorldPoint(x, y, tempPoint); + + pointer.worldX = tempPoint.x; + pointer.worldY = tempPoint.y; + + var point = { x: 0, y: 0 }; + + var matrix = this._tempMatrix; + var parentMatrix = this._tempMatrix2; + + for (var i = 0; i < gameObjects.length; i++) + { + var gameObject = gameObjects[i]; + + // Checks if the Game Object can receive input (isn't being ignored by the camera, invisible, etc) + // and also checks all of its parents, if any + if (!this.inputCandidate(gameObject, camera)) + { + continue; + } + + var px = tempPoint.x + (csx * gameObject.scrollFactorX) - csx; + var py = tempPoint.y + (csy * gameObject.scrollFactorY) - csy; + + if (gameObject.parentContainer) + { + gameObject.getWorldTransformMatrix(matrix, parentMatrix); + + matrix.applyInverse(px, py, point); + } + else + { + TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); + } + + if (this.pointWithinHitArea(gameObject, point.x, point.y)) + { + output.push(gameObject); + } + } + + return output; + }, + + /** + * Checks if the given x and y coordinate are within the hit area of the Game Object. + * + * This method assumes that the coordinate values have already been translated into the space of the Game Object. + * + * If the coordinates are within the hit area they are set into the Game Objects Input `localX` and `localY` properties. + * + * @method Phaser.Input.InputManager#pointWithinHitArea + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object to check against. + * @param {number} x - The translated x coordinate for the hit test. + * @param {number} y - The translated y coordinate for the hit test. + * + * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. + */ + pointWithinHitArea: function (gameObject, x, y) + { + // Normalize the origin + x += gameObject.displayOriginX; + y += gameObject.displayOriginY; + + var input = gameObject.input; + + if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) + { + input.localX = x; + input.localY = y; + + return true; + } + else + { + return false; + } + }, + + /** + * Checks if the given x and y coordinate are within the hit area of the Interactive Object. + * + * This method assumes that the coordinate values have already been translated into the space of the Interactive Object. + * + * If the coordinates are within the hit area they are set into the Interactive Objects Input `localX` and `localY` properties. + * + * @method Phaser.Input.InputManager#pointWithinInteractiveObject + * @since 3.0.0 + * + * @param {Phaser.Types.Input.InteractiveObject} object - The Interactive Object to check against. + * @param {number} x - The translated x coordinate for the hit test. + * @param {number} y - The translated y coordinate for the hit test. + * + * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. + */ + pointWithinInteractiveObject: function (object, x, y) + { + if (!object.hitArea) + { + return false; + } + + // Normalize the origin + x += object.gameObject.displayOriginX; + y += object.gameObject.displayOriginY; + + object.localX = x; + object.localY = y; + + return object.hitAreaCallback(object.hitArea, x, y, object); + }, + + /** + * Transforms the pageX and pageY values of a Pointer into the scaled coordinate space of the Input Manager. + * + * @method Phaser.Input.InputManager#transformPointer + * @since 3.10.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to transform the values for. + * @param {number} pageX - The Page X value. + * @param {number} pageY - The Page Y value. + * @param {boolean} wasMove - Are we transforming the Pointer from a move event, or an up / down event? + */ + transformPointer: function (pointer, pageX, pageY, wasMove) + { + var p0 = pointer.position; + var p1 = pointer.prevPosition; + + // Store previous position + p1.x = p0.x; + p1.y = p0.y; + + // Translate coordinates + var x = this.scaleManager.transformX(pageX); + var y = this.scaleManager.transformY(pageY); + + var a = pointer.smoothFactor; + + if (!wasMove || a === 0) + { + // Set immediately + p0.x = x; + p0.y = y; + } + else + { + // Apply smoothing + p0.x = x * a + p1.x * (1 - a); + p0.y = y * a + p1.y * (1 - a); + } + }, + + /** + * Destroys the Input Manager and all of its systems. + * + * There is no way to recover from doing this. + * + * @method Phaser.Input.InputManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.events.removeAllListeners(); + + this.game.events.off(GameEvents.PRE_RENDER); + + if (this.keyboard) + { + this.keyboard.destroy(); + } + + if (this.mouse) + { + this.mouse.destroy(); + } + + if (this.touch) + { + this.touch.destroy(); + } + + for (var i = 0; i < this.pointers.length; i++) + { + this.pointers[i].destroy(); + } + + this.pointers = []; + this._tempHitTest = []; + this._tempMatrix.destroy(); + this.canvas = null; + this.game = null; + } + +}); + +module.exports = InputManager; + + +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArrayRemove = __webpack_require__(89); +var Class = __webpack_require__(0); +var GameEvents = __webpack_require__(22); +var InputEvents = __webpack_require__(49); +var KeyCodes = __webpack_require__(141); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * The Keyboard Manager is a helper class that belongs to the global Input Manager. + * + * Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically if keyboard + * input has been enabled in the Game Config. + * + * @class KeyboardManager + * @memberof Phaser.Input.Keyboard + * @constructor + * @since 3.16.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var KeyboardManager = new Class({ + + initialize: + + function KeyboardManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Keyboard.KeyboardManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.16.0 + */ + this.manager = inputManager; + + /** + * An internal event queue. + * + * @name Phaser.Input.Keyboard.KeyboardManager#queue + * @type {KeyboardEvent[]} + * @private + * @since 3.16.0 + */ + this.queue = []; + + /** + * A flag that controls if the non-modified keys, matching those stored in the `captures` array, + * have `preventDefault` called on them or not. + * + * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are + * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). + * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. + * However, if the user presses just the r key on its own, it will have its event prevented. + * + * If you wish to stop capturing the keys, for example switching out to a DOM based element, then + * you can toggle this property at run-time. + * + * @name Phaser.Input.Keyboard.KeyboardManager#preventDefault + * @type {boolean} + * @since 3.16.0 + */ + this.preventDefault = true; + + /** + * An array of Key Code values that will automatically have `preventDefault` called on them, + * as long as the `KeyboardManager.preventDefault` boolean is set to `true`. + * + * By default the array is empty. + * + * The key must be non-modified when pressed in order to be captured. + * + * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are + * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). + * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. + * However, if the user presses just the r key on its own, it will have its event prevented. + * + * If you wish to stop capturing the keys, for example switching out to a DOM based element, then + * you can toggle the `KeyboardManager.preventDefault` boolean at run-time. + * + * If you need more specific control, you can create Key objects and set the flag on each of those instead. + * + * This array can be populated via the Game Config by setting the `input.keyboard.capture` array, or you + * can call the `addCapture` method. See also `removeCapture` and `clearCaptures`. + * + * @name Phaser.Input.Keyboard.KeyboardManager#captures + * @type {number[]} + * @since 3.16.0 + */ + this.captures = []; + + /** + * A boolean that controls if the Keyboard Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Keyboard.KeyboardManager#enabled + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.enabled = false; + + /** + * The Keyboard Event target, as defined in the Game Config. + * Typically the window in which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Keyboard.KeyboardManager#target + * @type {any} + * @since 3.16.0 + */ + this.target; + + /** + * The Key Down Event handler. + * This function is sent the native DOM KeyEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Keyboard.KeyboardManager#onKeyDown + * @type {function} + * @since 3.16.00 + */ + this.onKeyDown = NOOP; + + /** + * The Key Up Event handler. + * This function is sent the native DOM KeyEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp + * @type {function} + * @since 3.16.00 + */ + this.onKeyUp = NOOP; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Keyboard Manager boot process. + * + * @method Phaser.Input.Keyboard.KeyboardManager#boot + * @private + * @since 3.16.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputKeyboard; + this.target = config.inputKeyboardEventTarget; + + this.addCapture(config.inputKeyboardCapture); + + if (!this.target && window) + { + this.target = window; + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + + this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, this); + }, + + /** + * Starts the Keyboard Event listeners running. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Keyboard.KeyboardManager#startListeners + * @since 3.16.0 + */ + startListeners: function () + { + var _this = this; + + this.onKeyDown = function (event) + { + if (event.defaultPrevented || !_this.enabled || !_this.manager) + { + // Do nothing if event already handled + return; + } + + _this.queue.push(event); + + _this.manager.events.emit(InputEvents.MANAGER_PROCESS); + + var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); + + if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) + { + event.preventDefault(); + } + }; + + this.onKeyUp = function (event) + { + if (event.defaultPrevented || !_this.enabled || !_this.manager) + { + // Do nothing if event already handled + return; + } + + _this.queue.push(event); + + _this.manager.events.emit(InputEvents.MANAGER_PROCESS); + + var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); + + if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) + { + event.preventDefault(); + } + }; + + var target = this.target; + + if (target) + { + target.addEventListener('keydown', this.onKeyDown, false); + target.addEventListener('keyup', this.onKeyUp, false); + + this.enabled = true; + } + }, + + /** + * Stops the Key Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Keyboard.KeyboardManager#stopListeners + * @since 3.16.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('keydown', this.onKeyDown, false); + target.removeEventListener('keyup', this.onKeyUp, false); + + this.enabled = false; + }, + + /** + * Clears the event queue. + * Called automatically by the Input Manager. + * + * @method Phaser.Input.Keyboard.KeyboardManager#postUpdate + * @private + * @since 3.16.0 + */ + postUpdate: function () + { + this.queue = []; + }, + + /** + * By default when a key is pressed Phaser will not stop the event from propagating up to the browser. + * There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll. + * + * This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser + * and cause the default browser behavior. + * + * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent + * the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one. + * + * You can pass in a single key code value, or an array of key codes, or a string: + * + * ```javascript + * this.input.keyboard.addCapture(62); + * ``` + * + * An array of key codes: + * + * ```javascript + * this.input.keyboard.addCapture([ 62, 63, 64 ]); + * ``` + * + * Or a string: + * + * ```javascript + * this.input.keyboard.addCapture('W,S,A,D'); + * ``` + * + * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * + * You can also provide an array mixing both strings and key code integers. + * + * If there are active captures after calling this method, the `preventDefault` property is set to `true`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#addCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser. + */ + addCapture: function (keycode) + { + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } + + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } + + var captures = this.captures; + + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; + + if (typeof code === 'string') + { + code = KeyCodes[code.trim().toUpperCase()]; + } + + if (captures.indexOf(code) === -1) + { + captures.push(code); + } + } + + this.preventDefault = captures.length > 0; + }, + + /** + * Removes an existing key capture. + * + * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove + * the capture of a key, then it will remove it for any Scene in your game, not just the calling one. + * + * You can pass in a single key code value, or an array of key codes, or a string: + * + * ```javascript + * this.input.keyboard.removeCapture(62); + * ``` + * + * An array of key codes: + * + * ```javascript + * this.input.keyboard.removeCapture([ 62, 63, 64 ]); + * ``` + * + * Or a string: + * + * ```javascript + * this.input.keyboard.removeCapture('W,S,A,D'); + * ``` + * + * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * + * You can also provide an array mixing both strings and key code integers. + * + * If there are no captures left after calling this method, the `preventDefault` property is set to `false`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#removeCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again. + */ + removeCapture: function (keycode) + { + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } + + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } + + var captures = this.captures; + + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; + + if (typeof code === 'string') + { + code = KeyCodes[code.toUpperCase()]; + } + + ArrayRemove(captures, code); + } + + this.preventDefault = captures.length > 0; + }, + + /** + * Removes all keyboard captures and sets the `preventDefault` property to `false`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures + * @since 3.16.0 + */ + clearCaptures: function () + { + this.captures = []; + + this.preventDefault = false; + }, + + /** + * Destroys this Keyboard Manager instance. + * + * @method Phaser.Input.Keyboard.KeyboardManager#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.stopListeners(); + + this.clearCaptures(); + + this.queue = []; + + this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = KeyboardManager; + + +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Features = __webpack_require__(188); +var InputEvents = __webpack_require__(49); +var NOOP = __webpack_require__(1); + +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent +// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md + +/** + * @classdesc + * The Mouse Manager is a helper class that belongs to the Input Manager. + * + * Its role is to listen for native DOM Mouse Events and then pass them onto the Input Manager for further processing. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. + * + * @class MouseManager + * @memberof Phaser.Input.Mouse + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var MouseManager = new Class({ + + initialize: + + function MouseManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Mouse.MouseManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = inputManager; + + /** + * If `true` the DOM `mousedown` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultDown + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultDown = true; + + /** + * If `true` the DOM `mouseup` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultUp + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultUp = true; + + /** + * If `true` the DOM `mousemove` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultMove + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultMove = true; + + /** + * If `true` the DOM `wheel` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultWheel + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultWheel = false; + + /** + * A boolean that controls if the Mouse Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Mouse.MouseManager#enabled + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.enabled = false; + + /** + * The Mouse target, as defined in the Game Config. + * Typically the canvas to which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Mouse.MouseManager#target + * @type {any} + * @since 3.0.0 + */ + this.target; + + /** + * If the mouse has been pointer locked successfully this will be set to true. + * + * @name Phaser.Input.Mouse.MouseManager#locked + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.locked = false; + + /** + * The Mouse Move Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseMove + * @type {function} + * @since 3.10.0 + */ + this.onMouseMove = NOOP; + + /** + * The Mouse Down Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseDown + * @type {function} + * @since 3.10.0 + */ + this.onMouseDown = NOOP; + + /** + * The Mouse Up Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseUp + * @type {function} + * @since 3.10.0 + */ + this.onMouseUp = NOOP; + + /** + * The Mouse Down Event handler specifically for events on the Window. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseDownWindow + * @type {function} + * @since 3.17.0 + */ + this.onMouseDownWindow = NOOP; + + /** + * The Mouse Up Event handler specifically for events on the Window. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseUpWindow + * @type {function} + * @since 3.17.0 + */ + this.onMouseUpWindow = NOOP; + + /** + * The Mouse Over Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseOver + * @type {function} + * @since 3.16.0 + */ + this.onMouseOver = NOOP; + + /** + * The Mouse Out Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseOut + * @type {function} + * @since 3.16.0 + */ + this.onMouseOut = NOOP; + + /** + * The Mouse Wheel Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseWheel + * @type {function} + * @since 3.18.0 + */ + this.onMouseWheel = NOOP; + + /** + * Internal pointerLockChange handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#pointerLockChange + * @type {function} + * @since 3.0.0 + */ + this.pointerLockChange = NOOP; + + /** + * Are the event listeners hooked into `window.top` or `window`? + * + * This is set during the `boot` sequence. If the browser does not have access to `window.top`, + * such as in cross-origin iframe environments, this property gets set to `false` and the events + * are hooked into `window` instead. + * + * @name Phaser.Input.Mouse.MouseManager#isTop + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.isTop = true; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Touch Manager boot process. + * + * @method Phaser.Input.Mouse.MouseManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputMouse; + this.target = config.inputMouseEventTarget; + this.passive = config.inputMousePassive; + + this.preventDefaultDown = config.inputMousePreventDefaultDown; + this.preventDefaultUp = config.inputMousePreventDefaultUp; + this.preventDefaultMove = config.inputMousePreventDefaultMove; + this.preventDefaultWheel = config.inputMousePreventDefaultWheel; + + if (!this.target) + { + this.target = this.manager.game.canvas; + } + else if (typeof this.target === 'string') + { + this.target = document.getElementById(this.target); + } + + if (config.disableContextMenu) + { + this.disableContextMenu(); + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + }, + + /** + * Attempts to disable the context menu from appearing if you right-click on the browser. + * + * Works by listening for the `contextmenu` event and prevent defaulting it. + * + * Use this if you need to enable right-button mouse support in your game, and the browser + * menu keeps getting in the way. + * + * @method Phaser.Input.Mouse.MouseManager#disableContextMenu + * @since 3.0.0 + * + * @return {this} This Mouse Manager instance. + */ + disableContextMenu: function () + { + document.body.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return false; + }); + + return this; + }, + + /** + * If the browser supports it, you can request that the pointer be locked to the browser window. + * + * This is classically known as 'FPS controls', where the pointer can't leave the browser until + * the user presses an exit key. + * + * If the browser successfully enters a locked state, a `POINTER_LOCK_CHANGE_EVENT` will be dispatched, + * from the games Input Manager, with an `isPointerLocked` property. + * + * It is important to note that pointer lock can only be enabled after an 'engagement gesture', + * see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture. + * + * Note for Firefox: There is a bug in certain Firefox releases that cause native DOM events like + * `mousemove` to fire continuously when in pointer lock mode. You can get around this by setting + * `this.preventDefaultMove` to `false` in this class. You may also need to do the same for + * `preventDefaultDown` and/or `preventDefaultUp`. Please test combinations of these if you encounter + * the error. + * + * @method Phaser.Input.Mouse.MouseManager#requestPointerLock + * @since 3.0.0 + */ + requestPointerLock: function () + { + if (Features.pointerLock) + { + var element = this.target; + + element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; + + element.requestPointerLock(); + } + }, + + /** + * If the browser supports pointer lock, this will request that the pointer lock is released. If + * the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be + * dispatched - from the game's input manager - with an `isPointerLocked` property. + * + * @method Phaser.Input.Mouse.MouseManager#releasePointerLock + * @since 3.0.0 + */ + releasePointerLock: function () + { + if (Features.pointerLock) + { + document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; + document.exitPointerLock(); + } + }, + + /** + * Starts the Mouse Event listeners running. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Mouse.MouseManager#startListeners + * @since 3.0.0 + */ + startListeners: function () + { + var target = this.target; + + if (!target) + { + return; + } + + var _this = this; + var manager = this.manager; + var canvas = manager.canvas; + var autoFocus = (window && window.focus && manager.game.config.autoFocus); + + this.onMouseMove = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseMove(event); + + if (_this.preventDefaultMove) + { + event.preventDefault(); + } + } + }; + + this.onMouseDown = function (event) + { + if (autoFocus) + { + window.focus(); + } + + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseDown(event); + + if (_this.preventDefaultDown && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onMouseDownWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + manager.onMouseDown(event); + } + }; + + this.onMouseUp = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseUp(event); + + if (_this.preventDefaultUp && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onMouseUpWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + manager.onMouseUp(event); + } + }; + + this.onMouseOver = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOver(event); + } + }; + + this.onMouseOut = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOut(event); + } + }; + + this.onMouseWheel = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseWheel(event); + } + + if (_this.preventDefaultWheel && event.target === canvas) + { + event.preventDefault(); + } + }; + + var passive = { passive: true }; + + target.addEventListener('mousemove', this.onMouseMove); + target.addEventListener('mousedown', this.onMouseDown); + target.addEventListener('mouseup', this.onMouseUp); + target.addEventListener('mouseover', this.onMouseOver, passive); + target.addEventListener('mouseout', this.onMouseOut, passive); + + if (this.preventDefaultWheel) + { + target.addEventListener('wheel', this.onMouseWheel, { passive: false }); + } + else + { + target.addEventListener('wheel', this.onMouseWheel, passive); + } + + if (window && manager.game.config.inputWindowEvents) + { + try + { + window.top.addEventListener('mousedown', this.onMouseDownWindow, passive); + window.top.addEventListener('mouseup', this.onMouseUpWindow, passive); + } + catch (exception) + { + window.addEventListener('mousedown', this.onMouseDownWindow, passive); + window.addEventListener('mouseup', this.onMouseUpWindow, passive); + + this.isTop = false; + } + } + + if (Features.pointerLock) + { + this.pointerLockChange = function (event) + { + var element = _this.target; + + _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; + + manager.onPointerLockChange(event); + }; + + document.addEventListener('pointerlockchange', this.pointerLockChange, true); + document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } + + this.enabled = true; + }, + + /** + * Stops the Mouse Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Mouse.MouseManager#stopListeners + * @since 3.0.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('mousemove', this.onMouseMove); + target.removeEventListener('mousedown', this.onMouseDown); + target.removeEventListener('mouseup', this.onMouseUp); + target.removeEventListener('mouseover', this.onMouseOver); + target.removeEventListener('mouseout', this.onMouseOut); + + if (window) + { + target = (this.isTop) ? window.top : window; + + target.removeEventListener('mousedown', this.onMouseDownWindow); + target.removeEventListener('mouseup', this.onMouseUpWindow); + } + + if (Features.pointerLock) + { + document.removeEventListener('pointerlockchange', this.pointerLockChange, true); + document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } + }, + + /** + * Destroys this Mouse Manager instance. + * + * @method Phaser.Input.Mouse.MouseManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stopListeners(); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = MouseManager; + + +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Angle = __webpack_require__(343); +var Class = __webpack_require__(0); +var Distance = __webpack_require__(48); +var FuzzyEqual = __webpack_require__(123); +var SmoothStepInterpolation = __webpack_require__(354); +var Vector2 = __webpack_require__(3); +var OS = __webpack_require__(102); + +/** + * @classdesc + * A Pointer object encapsulates both mouse and touch input within Phaser. + * + * By default, Phaser will create 2 pointers for your game to use. If you require more, i.e. for a multi-touch + * game, then use the `InputPlugin.addPointer` method to do so, rather than instantiating this class directly, + * otherwise it won't be managed by the input system. + * + * You can reference the current active pointer via `InputPlugin.activePointer`. You can also use the properties + * `InputPlugin.pointer1` through to `pointer10`, for each pointer you have enabled in your game. + * + * The properties of this object are set by the Input Plugin during processing. This object is then sent in all + * input related events that the Input Plugin emits, so you can reference properties from it directly in your + * callbacks. + * + * @class Pointer + * @memberof Phaser.Input + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} manager - A reference to the Input Manager. + * @param {number} id - The internal ID of this Pointer. + */ +var Pointer = new Class({ + + initialize: + + function Pointer (manager, id) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Pointer#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * The internal ID of this Pointer. + * + * @name Phaser.Input.Pointer#id + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.id = id; + + /** + * The most recent native DOM Event this Pointer has processed. + * + * @name Phaser.Input.Pointer#event + * @type {(TouchEvent|MouseEvent)} + * @since 3.0.0 + */ + this.event; + + /** + * The DOM element the Pointer was pressed down on, taken from the DOM event. + * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. + * + * @name Phaser.Input.Pointer#downElement + * @type {any} + * @readonly + * @since 3.16.0 + */ + this.downElement; + + /** + * The DOM element the Pointer was released on, taken from the DOM event. + * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. + * + * @name Phaser.Input.Pointer#upElement + * @type {any} + * @readonly + * @since 3.16.0 + */ + this.upElement; + + /** + * The camera the Pointer interacted with during its last update. + * + * A Pointer can only ever interact with one camera at once, which will be the top-most camera + * in the list should multiple cameras be positioned on-top of each other. + * + * @name Phaser.Input.Pointer#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @default null + * @since 3.0.0 + */ + this.camera = null; + + /** + * A read-only property that indicates which button was pressed, or released, on the pointer + * during the most recent event. It is only set during `up` and `down` events. + * + * On Touch devices the value is always 0. + * + * Users may change the configuration of buttons on their pointing device so that if an event's button property + * is zero, it may not have been caused by the button that is physically left–most on the pointing device; + * however, it should behave as if the left button was clicked in the standard button layout. + * + * @name Phaser.Input.Pointer#button + * @type {number} + * @readonly + * @default 0 + * @since 3.18.0 + */ + this.button = 0; + + /** + * 0: No button or un-initialized + * 1: Left button + * 2: Right button + * 4: Wheel button or middle button + * 8: 4th button (typically the "Browser Back" button) + * 16: 5th button (typically the "Browser Forward" button) + * + * For a mouse configured for left-handed use, the button actions are reversed. + * In this case, the values are read from right to left. + * + * @name Phaser.Input.Pointer#buttons + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.buttons = 0; + + /** + * The position of the Pointer in screen space. + * + * @name Phaser.Input.Pointer#position + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.position = new Vector2(); + + /** + * The previous position of the Pointer in screen space. + * + * The old x and y values are stored in here during the InputManager.transformPointer call. + * + * Use the properties `velocity`, `angle` and `distance` to create your own gesture recognition. + * + * @name Phaser.Input.Pointer#prevPosition + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.11.0 + */ + this.prevPosition = new Vector2(); + + /** + * An internal vector used for calculations of the pointer speed and angle. + * + * @name Phaser.Input.Pointer#midPoint + * @type {Phaser.Math.Vector2} + * @private + * @since 3.16.0 + */ + this.midPoint = new Vector2(-1, -1); + + /** + * The current velocity of the Pointer, based on its current and previous positions. + * + * This value is smoothed out each frame, according to the `motionFactor` property. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * @name Phaser.Input.Pointer#velocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.16.0 + */ + this.velocity = new Vector2(); + + /** + * The current angle the Pointer is moving, in radians, based on its previous and current position. + * + * The angle is based on the old position facing to the current position. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * @name Phaser.Input.Pointer#angle + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.angle = 0; + + /** + * The distance the Pointer has moved, based on its previous and current position. + * + * This value is smoothed out each frame, according to the `motionFactor` property. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * If you need the total distance travelled since the primary buttons was pressed down, + * then use the `Pointer.getDistance` method. + * + * @name Phaser.Input.Pointer#distance + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.distance = 0; + + /** + * The smoothing factor to apply to the Pointer position. + * + * Due to their nature, pointer positions are inherently noisy. While this is fine for lots of games, if you need cleaner positions + * then you can set this value to apply an automatic smoothing to the positions as they are recorded. + * + * The default value of zero means 'no smoothing'. + * Set to a small value, such as 0.2, to apply an average level of smoothing between positions. You can do this by changing this + * value directly, or by setting the `input.smoothFactor` property in the Game Config. + * + * Positions are only smoothed when the pointer moves. If the primary button on this Pointer enters an Up or Down state, then the position + * is always precise, and not smoothed. + * + * @name Phaser.Input.Pointer#smoothFactor + * @type {number} + * @default 0 + * @since 3.16.0 + */ + this.smoothFactor = 0; + + /** + * The factor applied to the motion smoothing each frame. + * + * This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, + * angle and distance of the Pointer. It's applied every frame, until the midPoint reaches the current + * position of the Pointer. 0.2 provides a good average but can be increased if you need a + * quicker update and are working in a high performance environment. Never set this value to + * zero. + * + * @name Phaser.Input.Pointer#motionFactor + * @type {number} + * @default 0.2 + * @since 3.16.0 + */ + this.motionFactor = 0.2; + + /** + * The x position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. + * + * If you wish to use this value _outside_ of an input event handler then you should update it first by calling + * the `Pointer.updateWorldPoint` method. + * + * @name Phaser.Input.Pointer#worldX + * @type {number} + * @default 0 + * @since 3.10.0 + */ + this.worldX = 0; + + /** + * The y position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. + * + * If you wish to use this value _outside_ of an input event handler then you should update it first by calling + * the `Pointer.updateWorldPoint` method. + * + * @name Phaser.Input.Pointer#worldY + * @type {number} + * @default 0 + * @since 3.10.0 + */ + this.worldY = 0; + + /** + * Time when this Pointer was most recently moved (regardless of the state of its buttons, if any) + * + * @name Phaser.Input.Pointer#moveTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.moveTime = 0; + + /** + * X coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. + * + * @name Phaser.Input.Pointer#downX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downX = 0; + + /** + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. + * + * @name Phaser.Input.Pointer#downY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downY = 0; + + /** + * The Event timestamp when the first button, or Touch input, was pressed. Used for dragging objects. + * + * @name Phaser.Input.Pointer#downTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downTime = 0; + + /** + * X coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. + * + * @name Phaser.Input.Pointer#upX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upX = 0; + + /** + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. + * + * @name Phaser.Input.Pointer#upY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upY = 0; + + /** + * The Event timestamp when the final button, or Touch input, was released. Used for dragging objects. + * + * @name Phaser.Input.Pointer#upTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upTime = 0; + + /** + * Is the primary button down? (usually button 0, the left mouse button) + * + * @name Phaser.Input.Pointer#primaryDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.primaryDown = false; + + /** + * Is _any_ button on this pointer considered as being down? + * + * @name Phaser.Input.Pointer#isDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isDown = false; + + /** + * Did the previous input event come from a Touch input (true) or Mouse? (false) + * + * @name Phaser.Input.Pointer#wasTouch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.wasTouch = false; + + /** + * Did this Pointer get canceled by a touchcancel event? + * + * Note: "canceled" is the American-English spelling of "cancelled". Please don't submit PRs correcting it! + * + * @name Phaser.Input.Pointer#wasCanceled + * @type {boolean} + * @default false + * @since 3.15.0 + */ + this.wasCanceled = false; + + /** + * If the mouse is locked, the horizontal relative movement of the Pointer in pixels since last frame. + * + * @name Phaser.Input.Pointer#movementX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.movementX = 0; + + /** + * If the mouse is locked, the vertical relative movement of the Pointer in pixels since last frame. + * + * @name Phaser.Input.Pointer#movementY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.movementY = 0; + + /** + * The identifier property of the Pointer as set by the DOM event when this Pointer is started. + * + * @name Phaser.Input.Pointer#identifier + * @type {number} + * @since 3.10.0 + */ + this.identifier = 0; + + /** + * The pointerId property of the Pointer as set by the DOM event when this Pointer is started. + * The browser can and will recycle this value. + * + * @name Phaser.Input.Pointer#pointerId + * @type {number} + * @since 3.10.0 + */ + this.pointerId = null; + + /** + * An active Pointer is one that is currently pressed down on the display. + * A Mouse is always considered as active. + * + * @name Phaser.Input.Pointer#active + * @type {boolean} + * @since 3.10.0 + */ + this.active = (id === 0) ? true : false; + + /** + * Is this pointer Pointer Locked? + * + * Only a mouse pointer can be locked and it only becomes locked when requested via + * the browsers Pointer Lock API. + * + * You can request this by calling the `this.input.mouse.requestPointerLock()` method from + * a `pointerdown` or `pointerup` event handler. + * + * @name Phaser.Input.Pointer#locked + * @readonly + * @type {boolean} + * @since 3.19.0 + */ + this.locked = false; + + /** + * The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * + * @name Phaser.Input.Pointer#deltaX + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaX = 0; + + /** + * The vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * This value will typically be less than 0 if the user scrolls up and greater than zero if scrolling down. + * + * @name Phaser.Input.Pointer#deltaY + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaY = 0; + + /** + * The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * + * @name Phaser.Input.Pointer#deltaZ + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaZ = 0; + }, + + /** + * Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are + * the result of a translation through the given Camera. + * + * Note that the values will be automatically replaced the moment the Pointer is + * updated by an input event, such as a mouse move, so should be used immediately. + * + * @method Phaser.Input.Pointer#updateWorldPoint + * @since 3.19.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * + * @return {this} This Pointer object. + */ + updateWorldPoint: function (camera) + { + // Stores the world point inside of tempPoint + var temp = camera.getWorldPoint(this.x, this.y); + + this.worldX = temp.x; + this.worldY = temp.y; + + return this; + }, + + /** + * Takes a Camera and returns a Vector2 containing the translated position of this Pointer + * within that Camera. This can be used to convert this Pointers position into camera space. + * + * @method Phaser.Input.Pointer#positionToCamera + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the translation. + * @param {(Phaser.Math.Vector2|object)} [output] - A Vector2-like object in which to store the translated position. + * + * @return {(Phaser.Math.Vector2|object)} A Vector2 containing the translated coordinates of this Pointer, based on the given camera. + */ + positionToCamera: function (camera, output) + { + return camera.getWorldPoint(this.x, this.y, output); + }, + + /** + * Calculates the motion of this Pointer, including its velocity and angle of movement. + * This method is called automatically each frame by the Input Manager. + * + * @method Phaser.Input.Pointer#updateMotion + * @private + * @since 3.16.0 + */ + updateMotion: function () + { + var cx = this.position.x; + var cy = this.position.y; + + var mx = this.midPoint.x; + var my = this.midPoint.y; + + if (cx === mx && cy === my) + { + // Nothing to do here + return; + } + + // Moving towards our goal ... + var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); + var vy = SmoothStepInterpolation(this.motionFactor, my, cy); + + if (FuzzyEqual(vx, cx, 0.1)) + { + vx = cx; + } + + if (FuzzyEqual(vy, cy, 0.1)) + { + vy = cy; + } + + this.midPoint.set(vx, vy); + + var dx = cx - vx; + var dy = cy - vy; + + this.velocity.set(dx, dy); + + this.angle = Angle(vx, vy, cx, cy); + + this.distance = Math.sqrt(dx * dx + dy * dy); + }, + + /** + * Internal method to handle a Mouse Up Event. + * + * @method Phaser.Input.Pointer#up + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + up: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + this.button = event.button; + + this.upElement = event.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + // 0: Main button pressed, usually the left button or the un-initialized state + if (event.button === 0) + { + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + } + + if (this.buttons === 0) + { + // No more buttons are still down + this.isDown = false; + + this.upTime = event.timeStamp; + + this.wasTouch = false; + } + }, + + /** + * Internal method to handle a Mouse Down Event. + * + * @method Phaser.Input.Pointer#down + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + down: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + this.button = event.button; + + this.downElement = event.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + // 0: Main button pressed, usually the left button or the un-initialized state + if (event.button === 0) + { + this.primaryDown = true; + this.downX = this.x; + this.downY = this.y; + } + + if (OS.macOS && event.ctrlKey) + { + // Override button settings on macOS + this.buttons = 2; + this.primaryDown = false; + } + + if (!this.isDown) + { + this.isDown = true; + + this.downTime = event.timeStamp; + } + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Mouse Move Event. + * + * @method Phaser.Input.Pointer#move + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + move: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, true); + + if (this.locked) + { + // Multiple DOM events may occur within one frame, but only one Phaser event will fire + this.movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; + this.movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; + } + + this.moveTime = event.timeStamp; + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Mouse Wheel Event. + * + * @method Phaser.Input.Pointer#wheel + * @private + * @since 3.18.0 + * + * @param {WheelEvent} event - The Wheel Event to process. + */ + wheel: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + this.deltaX = event.deltaX; + this.deltaY = event.deltaY; + this.deltaZ = event.deltaZ; + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Touch Start Event. + * + * @method Phaser.Input.Pointer#touchstart + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchstart: function (touch, event) + { + if (touch['pointerId']) + { + this.pointerId = touch.pointerId; + } + + this.identifier = touch.identifier; + this.target = touch.target; + this.active = true; + + this.buttons = 1; + + this.event = event; + + this.downElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = true; + this.downX = this.x; + this.downY = this.y; + this.downTime = event.timeStamp; + + this.isDown = true; + + this.wasTouch = true; + this.wasCanceled = false; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch Move Event. + * + * @method Phaser.Input.Pointer#touchmove + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchmove: function (touch, event) + { + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, true); + + this.moveTime = event.timeStamp; + + this.wasTouch = true; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch End Event. + * + * @method Phaser.Input.Pointer#touchend + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchend: function (touch, event) + { + this.buttons = 0; + + this.event = event; + + this.upElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; + + this.isDown = false; + + this.wasTouch = true; + this.wasCanceled = false; + + this.active = false; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch Cancel Event. + * + * @method Phaser.Input.Pointer#touchcancel + * @private + * @since 3.15.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchcancel: function (touch, event) + { + this.buttons = 0; + + this.event = event; + + this.upElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; + + this.isDown = false; + + this.wasTouch = true; + this.wasCanceled = true; + + this.active = false; + }, + + /** + * Checks to see if any buttons are being held down on this Pointer. + * + * @method Phaser.Input.Pointer#noButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if no buttons are being held down. + */ + noButtonDown: function () + { + return (this.buttons === 0); + }, + + /** + * Checks to see if the left button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#leftButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the left button is being held down. + */ + leftButtonDown: function () + { + return (this.buttons & 1) ? true : false; + }, + + /** + * Checks to see if the right button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#rightButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the right button is being held down. + */ + rightButtonDown: function () + { + return (this.buttons & 2) ? true : false; + }, + + /** + * Checks to see if the middle button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#middleButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the middle button is being held down. + */ + middleButtonDown: function () + { + return (this.buttons & 4) ? true : false; + }, + + /** + * Checks to see if the back button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#backButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the back button is being held down. + */ + backButtonDown: function () + { + return (this.buttons & 8) ? true : false; + }, + + /** + * Checks to see if the forward button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#forwardButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the forward button is being held down. + */ + forwardButtonDown: function () + { + return (this.buttons & 16) ? true : false; + }, + + /** + * Checks to see if the left button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#leftButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the left button was just released. + */ + leftButtonReleased: function () + { + return (this.button === 0 && !this.isDown); + }, + + /** + * Checks to see if the right button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#rightButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the right button was just released. + */ + rightButtonReleased: function () + { + return (this.button === 2 && !this.isDown); + }, + + /** + * Checks to see if the middle button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#middleButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the middle button was just released. + */ + middleButtonReleased: function () + { + return (this.button === 1 && !this.isDown); + }, + + /** + * Checks to see if the back button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#backButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the back button was just released. + */ + backButtonReleased: function () + { + return (this.button === 3 && !this.isDown); + }, + + /** + * Checks to see if the forward button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#forwardButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the forward button was just released. + */ + forwardButtonReleased: function () + { + return (this.button === 4 && !this.isDown); + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded distance, based on where + * the Pointer was when the button was released. + * + * If you wish to get the distance being travelled currently, based on the velocity of the Pointer, + * then see the `Pointer.distance` property. + * + * @method Phaser.Input.Pointer#getDistance + * @since 3.13.0 + * + * @return {number} The distance the Pointer moved. + */ + getDistance: function () + { + if (this.isDown) + { + return Distance(this.downX, this.downY, this.x, this.y); + } + else + { + return Distance(this.downX, this.downY, this.upX, this.upY); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * horizontal distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded horizontal distance, based on where + * the Pointer was when the button was released. + * + * @method Phaser.Input.Pointer#getDistanceX + * @since 3.16.0 + * + * @return {number} The horizontal distance the Pointer moved. + */ + getDistanceX: function () + { + if (this.isDown) + { + return Math.abs(this.downX - this.x); + } + else + { + return Math.abs(this.downX - this.upX); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * vertical distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded vertical distance, based on where + * the Pointer was when the button was released. + * + * @method Phaser.Input.Pointer#getDistanceY + * @since 3.16.0 + * + * @return {number} The vertical distance the Pointer moved. + */ + getDistanceY: function () + { + if (this.isDown) + { + return Math.abs(this.downY - this.y); + } + else + { + return Math.abs(this.downY - this.upY); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * duration since the button was pressed down. + * + * If no button is held down, it will return the last recorded duration, based on the time + * the last button on the Pointer was released. + * + * @method Phaser.Input.Pointer#getDuration + * @since 3.16.0 + * + * @return {number} The duration the Pointer was held down for in milliseconds. + */ + getDuration: function () + { + if (this.isDown) + { + return (this.manager.time - this.downTime); + } + else + { + return (this.upTime - this.downTime); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * angle between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded angle, based on where + * the Pointer was when the button was released. + * + * The angle is based on the old position facing to the current position. + * + * If you wish to get the current angle, based on the velocity of the Pointer, then + * see the `Pointer.angle` property. + * + * @method Phaser.Input.Pointer#getAngle + * @since 3.16.0 + * + * @return {number} The angle between the Pointer's coordinates in radians. + */ + getAngle: function () + { + if (this.isDown) + { + return Angle(this.downX, this.downY, this.x, this.y); + } + else + { + return Angle(this.downX, this.downY, this.upX, this.upY); + } + }, + + /** + * Takes the previous and current Pointer positions and then generates an array of interpolated values between + * the two. The array will be populated up to the size of the `steps` argument. + * + * ```javaScript + * var points = pointer.getInterpolatedPosition(4); + * + * // points[0] = { x: 0, y: 0 } + * // points[1] = { x: 2, y: 1 } + * // points[2] = { x: 3, y: 2 } + * // points[3] = { x: 6, y: 3 } + * ``` + * + * Use this if you need to get smoothed values between the previous and current pointer positions. DOM pointer + * events can often fire faster than the main browser loop, and this will help you avoid janky movement + * especially if you have an object following a Pointer. + * + * Note that if you provide an output array it will only be populated up to the number of steps provided. + * It will not clear any previous data that may have existed beyond the range of the steps count. + * + * Internally it uses the Smooth Step interpolation calculation. + * + * @method Phaser.Input.Pointer#getInterpolatedPosition + * @since 3.11.0 + * + * @param {number} [steps=10] - The number of interpolation steps to use. + * @param {array} [out] - An array to store the results in. If not provided a new one will be created. + * + * @return {array} An array of interpolated values. + */ + getInterpolatedPosition: function (steps, out) + { + if (steps === undefined) { steps = 10; } + if (out === undefined) { out = []; } + + var prevX = this.prevPosition.x; + var prevY = this.prevPosition.y; + + var curX = this.position.x; + var curY = this.position.y; + + for (var i = 0; i < steps; i++) + { + var t = (1 / steps) * i; + + out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; + } + + return out; + }, + + /** + * Destroys this Pointer instance and resets its external references. + * + * @method Phaser.Input.Pointer#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.camera = null; + this.manager = null; + this.position = null; + }, + + /** + * The x position of this Pointer. + * The value is in screen space. + * See `worldX` to get a camera converted position. + * + * @name Phaser.Input.Pointer#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.position.x = value; + } + + }, + + /** + * The y position of this Pointer. + * The value is in screen space. + * See `worldY` to get a camera converted position. + * + * @name Phaser.Input.Pointer#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.position.y = value; + } + + }, + + /** + * Time when this Pointer was most recently updated by a DOM Event. + * This comes directly from the `event.timeStamp` property. + * If no event has yet taken place, it will return zero. + * + * @name Phaser.Input.Pointer#time + * @type {number} + * @readonly + * @since 3.16.0 + */ + time: { + + get: function () + { + return (this.event) ? this.event.timeStamp : 0; + } + + } + +}); + +module.exports = Pointer; + + +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var InputEvents = __webpack_require__(49); +var NOOP = __webpack_require__(1); + +// https://developer.mozilla.org/en-US/docs/Web/API/Touch_events +// https://patrickhlauke.github.io/touch/tests/results/ +// https://www.html5rocks.com/en/mobile/touch/ + +/** + * @classdesc + * The Touch Manager is a helper class that belongs to the Input Manager. + * + * Its role is to listen for native DOM Touch Events and then pass them onto the Input Manager for further processing. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. + * + * @class TouchManager + * @memberof Phaser.Input.Touch + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var TouchManager = new Class({ + + initialize: + + function TouchManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Touch.TouchManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = inputManager; + + /** + * If true the DOM events will have event.preventDefault applied to them, if false they will propagate fully. + * + * @name Phaser.Input.Touch.TouchManager#capture + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.capture = true; + + /** + * A boolean that controls if the Touch Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Touch.TouchManager#enabled + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.enabled = false; + + /** + * The Touch Event target, as defined in the Game Config. + * Typically the canvas to which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Touch.TouchManager#target + * @type {any} + * @since 3.0.0 + */ + this.target; + + /** + * The Touch Start event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchStart + * @type {function} + * @since 3.0.0 + */ + this.onTouchStart = NOOP; + + /** + * The Touch Start event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchStartWindow + * @type {function} + * @since 3.17.0 + */ + this.onTouchStartWindow = NOOP; + + /** + * The Touch Move event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchMove + * @type {function} + * @since 3.0.0 + */ + this.onTouchMove = NOOP; + + /** + * The Touch End event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchEnd + * @type {function} + * @since 3.0.0 + */ + this.onTouchEnd = NOOP; + + /** + * The Touch End event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchEndWindow + * @type {function} + * @since 3.17.0 + */ + this.onTouchEndWindow = NOOP; + + /** + * The Touch Cancel event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchCancel + * @type {function} + * @since 3.15.0 + */ + this.onTouchCancel = NOOP; + + /** + * The Touch Cancel event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchCancelWindow + * @type {function} + * @since 3.18.0 + */ + this.onTouchCancelWindow = NOOP; + + /** + * The Touch Over event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchOver + * @type {function} + * @since 3.16.0 + */ + this.onTouchOver = NOOP; + + /** + * The Touch Out event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchOut + * @type {function} + * @since 3.16.0 + */ + this.onTouchOut = NOOP; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Touch Manager boot process. + * + * @method Phaser.Input.Touch.TouchManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputTouch; + this.target = config.inputTouchEventTarget; + this.capture = config.inputTouchCapture; + + if (!this.target) + { + this.target = this.manager.game.canvas; + } + + if (config.disableContextMenu) + { + this.disableContextMenu(); + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + }, + + /** + * Attempts to disable the context menu from appearing if you touch-hold on the browser. + * + * Works by listening for the `contextmenu` event and prevent defaulting it. + * + * Use this if you need to disable the OS context menu on mobile. + * + * @method Phaser.Input.Touch.TouchManager#disableContextMenu + * @since 3.20.0 + * + * @return {this} This Touch Manager instance. + */ + disableContextMenu: function () + { + document.body.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return false; + }); + + return this; + }, + + /** + * Starts the Touch Event listeners running as long as an input target is set. + * + * This method is called automatically if Touch Input is enabled in the game config, + * which it is by default. However, you can call it manually should you need to + * delay input capturing until later in the game. + * + * @method Phaser.Input.Touch.TouchManager#startListeners + * @since 3.0.0 + */ + startListeners: function () + { + var _this = this; + var canvas = this.manager.canvas; + var autoFocus = (window && window.focus && this.manager.game.config.autoFocus); + + this.onTouchStart = function (event) + { + if (autoFocus) + { + window.focus(); + } + + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchStart(event); + + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onTouchStartWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + _this.manager.onTouchStart(event); + } + }; + + this.onTouchMove = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchMove(event); + + if (_this.capture && event.cancelable) + { + event.preventDefault(); + } + } + }; + + this.onTouchEnd = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchEnd(event); + + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onTouchEndWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + _this.manager.onTouchEnd(event); + } + }; + + this.onTouchCancel = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchCancel(event); + + if (_this.capture) + { + event.preventDefault(); + } + } + }; + + this.onTouchCancelWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchCancel(event); + } + }; + + this.onTouchOver = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.setCanvasOver(event); + } + }; + + this.onTouchOut = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.setCanvasOut(event); + } + }; + + var target = this.target; + + if (!target) + { + return; + } + + var passive = { passive: true }; + var nonPassive = { passive: false }; + + target.addEventListener('touchstart', this.onTouchStart, (this.capture) ? nonPassive : passive); + target.addEventListener('touchmove', this.onTouchMove, (this.capture) ? nonPassive : passive); + target.addEventListener('touchend', this.onTouchEnd, (this.capture) ? nonPassive : passive); + target.addEventListener('touchcancel', this.onTouchCancel, (this.capture) ? nonPassive : passive); + target.addEventListener('touchover', this.onTouchOver, (this.capture) ? nonPassive : passive); + target.addEventListener('touchout', this.onTouchOut, (this.capture) ? nonPassive : passive); + + if (window && this.manager.game.config.inputWindowEvents) + { + window.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); + window.addEventListener('touchend', this.onTouchEndWindow, nonPassive); + window.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); + } + + this.enabled = true; + }, + + /** + * Stops the Touch Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Touch.TouchManager#stopListeners + * @since 3.0.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('touchstart', this.onTouchStart); + target.removeEventListener('touchmove', this.onTouchMove); + target.removeEventListener('touchend', this.onTouchEnd); + target.removeEventListener('touchcancel', this.onTouchCancel); + target.removeEventListener('touchover', this.onTouchOver); + target.removeEventListener('touchout', this.onTouchOut); + + if (window) + { + window.removeEventListener('touchstart', this.onTouchStartWindow); + window.removeEventListener('touchend', this.onTouchEndWindow); + } + }, + + /** + * Destroys this Touch Manager instance. + * + * @method Phaser.Input.Touch.TouchManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stopListeners(); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = TouchManager; + + +/***/ }), +/* 408 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GameEvents = __webpack_require__(22); +var EventEmitter = __webpack_require__(9); +var FileTypesManager = __webpack_require__(8); +var GameObjectCreator = __webpack_require__(16); +var GameObjectFactory = __webpack_require__(5); +var GetFastValue = __webpack_require__(2); +var PluginCache = __webpack_require__(24); +var Remove = __webpack_require__(89); + +/** + * @classdesc + * The PluginManager is responsible for installing and adding plugins to Phaser. + * + * It is a global system and therefore belongs to the Game instance, not a specific Scene. + * + * It works in conjunction with the PluginCache. Core internal plugins automatically register themselves + * with the Cache, but it's the Plugin Manager that is responsible for injecting them into the Scenes. + * + * There are two types of plugin: + * + * 1. A Global Plugin + * 2. A Scene Plugin + * + * A Global Plugin is a plugin that lives within the Plugin Manager rather than a Scene. You can get + * access to it by calling `PluginManager.get` and providing a key. Any Scene that requests a plugin in + * this way will all get access to the same plugin instance, allowing you to use a single plugin across + * multiple Scenes. + * + * A Scene Plugin is a plugin dedicated to running within a Scene. These are different to Global Plugins + * in that their instances do not live within the Plugin Manager, but within the Scene Systems class instead. + * And that every Scene created is given its own unique instance of a Scene Plugin. Examples of core Scene + * Plugins include the Input Plugin, the Tween Plugin and the physics Plugins. + * + * You can add a plugin to Phaser in three different ways: + * + * 1. Preload it + * 2. Include it in your source code and install it via the Game Config + * 3. Include it in your source code and install it within a Scene + * + * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. + * + * For information on creating your own plugin please see the Phaser 3 Plugin Template. + * + * @class PluginManager + * @memberof Phaser.Plugins + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. + */ +var PluginManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function PluginManager (game) + { + EventEmitter.call(this); + + /** + * The game instance that owns this Plugin Manager. + * + * @name Phaser.Plugins.PluginManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * The global plugins currently running and managed by this Plugin Manager. + * A plugin must have been started at least once in order to appear in this list. + * + * @name Phaser.Plugins.PluginManager#plugins + * @type {Phaser.Types.Plugins.GlobalPlugin[]} + * @since 3.8.0 + */ + this.plugins = []; + + /** + * A list of plugin keys that should be installed into Scenes as well as the Core Plugins. + * + * @name Phaser.Plugins.PluginManager#scenePlugins + * @type {string[]} + * @since 3.8.0 + */ + this.scenePlugins = []; + + /** + * A temporary list of plugins to install when the game has booted. + * + * @name Phaser.Plugins.PluginManager#_pendingGlobal + * @private + * @type {array} + * @since 3.8.0 + */ + this._pendingGlobal = []; + + /** + * A temporary list of scene plugins to install when the game has booted. + * + * @name Phaser.Plugins.PluginManager#_pendingScene + * @private + * @type {array} + * @since 3.8.0 + */ + this._pendingScene = []; + + if (game.isBooted) + { + this.boot(); + } + else + { + game.events.once(GameEvents.BOOT, this.boot, this); + } + }, + + /** + * Run once the game has booted and installs all of the plugins configured in the Game Config. + * + * @method Phaser.Plugins.PluginManager#boot + * @protected + * @since 3.0.0 + */ + boot: function () + { + var i; + var entry; + var key; + var plugin; + var start; + var mapping; + var data; + var config = this.game.config; + + // Any plugins to install? + var list = config.installGlobalPlugins; + + // Any plugins added outside of the game config, but before the game booted? + list = list.concat(this._pendingGlobal); + + for (i = 0; i < list.length; i++) + { + entry = list[i]; + + // { key: 'TestPlugin', plugin: TestPlugin, start: true, mapping: 'test', data: { msg: 'The plugin is alive' } } + + key = GetFastValue(entry, 'key', null); + plugin = GetFastValue(entry, 'plugin', null); + start = GetFastValue(entry, 'start', false); + mapping = GetFastValue(entry, 'mapping', null); + data = GetFastValue(entry, 'data', null); + + if (key) + { + if (plugin) + { + this.install(key, plugin, start, mapping, data); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } + + } + } + + // Any scene plugins to install? + list = config.installScenePlugins; + + // Any plugins added outside of the game config, but before the game booted? + list = list.concat(this._pendingScene); + + for (i = 0; i < list.length; i++) + { + entry = list[i]; + + // { key: 'moveSpritePlugin', plugin: MoveSpritePlugin, , mapping: 'move' } + + key = GetFastValue(entry, 'key', null); + plugin = GetFastValue(entry, 'plugin', null); + mapping = GetFastValue(entry, 'mapping', null); + + if (key) + { + if (plugin) + { + this.installScenePlugin(key, plugin, mapping); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } + } + } + + this._pendingGlobal = []; + this._pendingScene = []; + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * Called by the Scene Systems class. Tells the plugin manager to install all Scene plugins into it. + * + * First it will install global references, i.e. references from the Game systems into the Scene Systems (and Scene if mapped.) + * Then it will install Core Scene Plugins followed by Scene Plugins registered with the PluginManager. + * Finally it will install any references to Global Plugins that have a Scene mapping property into the Scene itself. + * + * @method Phaser.Plugins.PluginManager#addToScene + * @protected + * @since 3.8.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems class to install all the plugins in to. + * @param {array} globalPlugins - An array of global plugins to install. + * @param {array} scenePlugins - An array of scene plugins to install. + */ + addToScene: function (sys, globalPlugins, scenePlugins) + { + var i; + var pluginKey; + var pluginList; + var game = this.game; + var scene = sys.scene; + var map = sys.settings.map; + var isBooted = sys.settings.isBooted; + + // Reference the GlobalPlugins from Game into Scene.Systems + for (i = 0; i < globalPlugins.length; i++) + { + pluginKey = globalPlugins[i]; + + if (game[pluginKey]) + { + sys[pluginKey] = game[pluginKey]; + + // Scene level injection + if (map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = sys[pluginKey]; + } + } + else if (pluginKey === 'game' && map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = game; + } + } + + for (var s = 0; s < scenePlugins.length; s++) + { + pluginList = scenePlugins[s]; + + for (i = 0; i < pluginList.length; i++) + { + pluginKey = pluginList[i]; + + if (!PluginCache.hasCore(pluginKey)) + { + continue; + } + + var source = PluginCache.getCore(pluginKey); + + var plugin = new source.plugin(scene, this); + + sys[source.mapping] = plugin; + + // Scene level injection + if (source.custom) + { + scene[source.mapping] = plugin; + } + else if (map.hasOwnProperty(source.mapping)) + { + scene[map[source.mapping]] = plugin; + } + + // Scene is already booted, usually because this method is being called at run-time, so boot the plugin + if (isBooted) + { + plugin.boot(); + } + } + } + + // And finally, inject any 'global scene plugins' + pluginList = this.plugins; + + for (i = 0; i < pluginList.length; i++) + { + var entry = pluginList[i]; + + if (entry.mapping) + { + scene[entry.mapping] = entry.plugin; + } + } + }, + + /** + * Called by the Scene Systems class. Returns a list of plugins to be installed. + * + * @method Phaser.Plugins.PluginManager#getDefaultScenePlugins + * @protected + * @since 3.8.0 + * + * @return {string[]} A list keys of all the Scene Plugins to install. + */ + getDefaultScenePlugins: function () + { + var list = this.game.config.defaultPlugins; + + // Merge in custom Scene plugins + list = list.concat(this.scenePlugins); + + return list; + }, + + /** + * Installs a new Scene Plugin into the Plugin Manager and optionally adds it + * to the given Scene as well. A Scene Plugin added to the manager in this way + * will be automatically installed into all new Scenes using the key and mapping given. + * + * The `key` property is what the plugin is injected into Scene.Systems as. + * The `mapping` property is optional, and if specified is what the plugin is installed into + * the Scene as. For example: + * + * ```javascript + * this.plugins.installScenePlugin('powerupsPlugin', pluginCode, 'powerups'); + * + * // and from within the scene: + * this.sys.powerupsPlugin; // key value + * this.powerups; // mapping value + * ``` + * + * This method is called automatically by Phaser if you install your plugins using either the + * Game Configuration object, or by preloading them via the Loader. + * + * @method Phaser.Plugins.PluginManager#installScenePlugin + * @since 3.8.0 + * + * @param {string} key - The property key that will be used to add this plugin to Scene.Systems. + * @param {function} plugin - The plugin code. This should be the non-instantiated version. + * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. + * @param {Phaser.Scene} [addToScene] - Optionally automatically add this plugin to the given Scene. + * @param {boolean} [fromLoader=false] - Is this being called by the Loader? + */ + installScenePlugin: function (key, plugin, mapping, addToScene, fromLoader) + { + if (fromLoader === undefined) { fromLoader = false; } + + if (typeof plugin !== 'function') + { + console.warn('Invalid Scene Plugin: ' + key); + return; + } + + if (!PluginCache.hasCore(key)) + { + // Plugin is freshly loaded + PluginCache.register(key, plugin, mapping, true); + + this.scenePlugins.push(key); + } + else if (!fromLoader && PluginCache.hasCore(key)) + { + // Plugin wasn't from the loader but already exists + console.warn('Scene Plugin key in use: ' + key); + return; + } + + if (addToScene) + { + var instance = new plugin(addToScene, this); + + addToScene.sys[key] = instance; + + if (mapping && mapping !== '') + { + addToScene[mapping] = instance; + } + + instance.boot(); + } + }, + + /** + * Installs a new Global Plugin into the Plugin Manager and optionally starts it running. + * A global plugin belongs to the Plugin Manager, rather than a specific Scene, and can be accessed + * and used by all Scenes in your game. + * + * The `key` property is what you use to access this plugin from the Plugin Manager. + * + * ```javascript + * this.plugins.install('powerupsPlugin', pluginCode); + * + * // and from within the scene: + * this.plugins.get('powerupsPlugin'); + * ``` + * + * This method is called automatically by Phaser if you install your plugins using either the + * Game Configuration object, or by preloading them via the Loader. + * + * The same plugin can be installed multiple times into the Plugin Manager by simply giving each + * instance its own unique key. + * + * @method Phaser.Plugins.PluginManager#install + * @since 3.8.0 + * + * @param {string} key - The unique handle given to this plugin within the Plugin Manager. + * @param {function} plugin - The plugin code. This should be the non-instantiated version. + * @param {boolean} [start=false] - Automatically start the plugin running? This is always `true` if you provide a mapping value. + * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. + * @param {any} [data] - A value passed to the plugin's `init` method. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if `start` was false, or game isn't yet booted. + */ + install: function (key, plugin, start, mapping, data) + { + if (start === undefined) { start = false; } + if (mapping === undefined) { mapping = null; } + if (data === undefined) { data = null; } + + if (typeof plugin !== 'function') + { + console.warn('Invalid Plugin: ' + key); + return null; + } + + if (PluginCache.hasCustom(key)) + { + console.warn('Plugin key in use: ' + key); + return null; + } + + if (mapping !== null) + { + start = true; + } + + if (!this.game.isBooted) + { + this._pendingGlobal.push({ key: key, plugin: plugin, start: start, mapping: mapping, data: data }); + } + else + { + // Add it to the plugin store + PluginCache.registerCustom(key, plugin, mapping, data); + + if (start) + { + return this.start(key); + } + } + + return null; + }, + + /** + * Gets an index of a global plugin based on the given key. + * + * @method Phaser.Plugins.PluginManager#getIndex + * @protected + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {number} The index of the plugin within the plugins array. + */ + getIndex: function (key) + { + var list = this.plugins; + + for (var i = 0; i < list.length; i++) + { + var entry = list[i]; + + if (entry.key === key) + { + return i; + } + } + + return -1; + }, + + /** + * Gets a global plugin based on the given key. + * + * @method Phaser.Plugins.PluginManager#getEntry + * @protected + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {Phaser.Types.Plugins.GlobalPlugin} The plugin entry. + */ + getEntry: function (key) + { + var idx = this.getIndex(key); + + if (idx !== -1) + { + return this.plugins[idx]; + } + }, + + /** + * Checks if the given global plugin, based on its key, is active or not. + * + * @method Phaser.Plugins.PluginManager#isActive + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {boolean} `true` if the plugin is active, otherwise `false`. + */ + isActive: function (key) + { + var entry = this.getEntry(key); + + return (entry && entry.active); + }, + + /** + * Starts a global plugin running. + * + * If the plugin was previously active then calling `start` will reset it to an active state and then + * call its `start` method. + * + * If the plugin has never been run before a new instance of it will be created within the Plugin Manager, + * its active state set and then both of its `init` and `start` methods called, in that order. + * + * If the plugin is already running under the given key then nothing happens. + * + * @method Phaser.Plugins.PluginManager#start + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to start. + * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given or plugin is already stopped. + */ + start: function (key, runAs) + { + if (runAs === undefined) { runAs = key; } + + var entry = this.getEntry(runAs); + + // Plugin already running under this key? + if (entry && !entry.active) + { + // It exists, we just need to start it up again + entry.active = true; + entry.plugin.start(); + } + else if (!entry) + { + entry = this.createEntry(key, runAs); + } + + return (entry) ? entry.plugin : null; + }, + + /** + * Creates a new instance of a global plugin, adds an entry into the plugins array and returns it. + * + * @method Phaser.Plugins.PluginManager#createEntry + * @private + * @since 3.9.0 + * + * @param {string} key - The key of the plugin to create an instance of. + * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given. + */ + createEntry: function (key, runAs) + { + var entry = PluginCache.getCustom(key); + + if (entry) + { + var instance = new entry.plugin(this); + + entry = { + key: runAs, + plugin: instance, + active: true, + mapping: entry.mapping, + data: entry.data + }; + + this.plugins.push(entry); + + instance.init(entry.data); + instance.start(); + } + + return entry; + }, + + /** + * Stops a global plugin from running. + * + * If the plugin is active then its active state will be set to false and the plugins `stop` method + * will be called. + * + * If the plugin is not already running, nothing will happen. + * + * @method Phaser.Plugins.PluginManager#stop + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to stop. + * + * @return {this} The Plugin Manager. + */ + stop: function (key) + { + var entry = this.getEntry(key); + + if (entry && entry.active) + { + entry.active = false; + entry.plugin.stop(); + } + + return this; + }, + + /** + * Gets a global plugin from the Plugin Manager based on the given key and returns it. + * + * If it cannot find an active plugin based on the key, but there is one in the Plugin Cache with the same key, + * then it will create a new instance of the cached plugin and return that. + * + * @method Phaser.Plugins.PluginManager#get + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to get. + * @param {boolean} [autoStart=true] - Automatically start a new instance of the plugin if found in the cache, but not actively running. + * + * @return {?(Phaser.Plugins.BasePlugin|function)} The plugin, or `null` if no plugin was found matching the key. + */ + get: function (key, autoStart) + { + if (autoStart === undefined) { autoStart = true; } + + var entry = this.getEntry(key); + + if (entry) + { + return entry.plugin; + } + else + { + var plugin = this.getClass(key); + + if (plugin && autoStart) + { + entry = this.createEntry(key, key); + + return (entry) ? entry.plugin : null; + } + else if (plugin) + { + return plugin; + } + } + + return null; + }, + + /** + * Returns the plugin class from the cache. + * Used internally by the Plugin Manager. + * + * @method Phaser.Plugins.PluginManager#getClass + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to get. + * + * @return {Phaser.Plugins.BasePlugin} A Plugin object + */ + getClass: function (key) + { + return PluginCache.getCustomClass(key); + }, + + /** + * Removes a global plugin from the Plugin Manager and Plugin Cache. + * + * It is up to you to remove all references to this plugin that you may hold within your game code. + * + * @method Phaser.Plugins.PluginManager#removeGlobalPlugin + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to remove. + */ + removeGlobalPlugin: function (key) + { + var entry = this.getEntry(key); + + if (entry) + { + Remove(this.plugins, entry); + } + + PluginCache.removeCustom(key); + }, + + /** + * Removes a scene plugin from the Plugin Manager and Plugin Cache. + * + * This will not remove the plugin from any active Scenes that are already using it. + * + * It is up to you to remove all references to this plugin that you may hold within your game code. + * + * @method Phaser.Plugins.PluginManager#removeScenePlugin + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to remove. + */ + removeScenePlugin: function (key) + { + Remove(this.scenePlugins, key); + + PluginCache.remove(key); + }, + + /** + * Registers a new type of Game Object with the global Game Object Factory and / or Creator. + * This is usually called from within your Plugin code and is a helpful short-cut for creating + * new Game Objects. + * + * The key is the property that will be injected into the factories and used to create the + * Game Object. For example: + * + * ```javascript + * this.plugins.registerGameObject('clown', clownFactoryCallback, clownCreatorCallback); + * // later in your game code: + * this.add.clown(); + * this.make.clown(); + * ``` + * + * The callbacks are what are called when the factories try to create a Game Object + * matching the given key. It's important to understand that the callbacks are invoked within + * the context of the GameObjectFactory. In this context there are several properties available + * to use: + * + * this.scene - A reference to the Scene that owns the GameObjectFactory. + * this.displayList - A reference to the Display List the Scene owns. + * this.updateList - A reference to the Update List the Scene owns. + * + * See the GameObjectFactory and GameObjectCreator classes for more details. + * Any public property or method listed is available from your callbacks under `this`. + * + * @method Phaser.Plugins.PluginManager#registerGameObject + * @since 3.8.0 + * + * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. + * @param {function} [factoryCallback] - The callback to invoke when the Game Object Factory is called. + * @param {function} [creatorCallback] - The callback to invoke when the Game Object Creator is called. + */ + registerGameObject: function (key, factoryCallback, creatorCallback) + { + if (factoryCallback) + { + GameObjectFactory.register(key, factoryCallback); + } + + if (creatorCallback) + { + GameObjectCreator.register(key, creatorCallback); + } + + return this; + }, + + /** + * Removes a previously registered Game Object from the global Game Object Factory and / or Creator. + * This is usually called from within your Plugin destruction code to help clean-up after your plugin has been removed. + * + * @method Phaser.Plugins.PluginManager#removeGameObject + * @since 3.19.0 + * + * @param {string} key - The key of the Game Object to be removed from the factories. + * @param {boolean} [removeFromFactory=true] - Should the Game Object be removed from the Game Object Factory? + * @param {boolean} [removeFromCreator=true] - Should the Game Object be removed from the Game Object Creator? + */ + removeGameObject: function (key, removeFromFactory, removeFromCreator) + { + if (removeFromFactory === undefined) { removeFromFactory = true; } + if (removeFromCreator === undefined) { removeFromCreator = true; } + + if (removeFromFactory) + { + GameObjectFactory.remove(key); + } + + if (removeFromCreator) + { + GameObjectCreator.remove(key); + } + + return this; + }, + + /** + * Registers a new file type with the global File Types Manager, making it available to all Loader + * Plugins created after this. + * + * This is usually called from within your Plugin code and is a helpful short-cut for creating + * new loader file types. + * + * The key is the property that will be injected into the Loader Plugin and used to load the + * files. For example: + * + * ```javascript + * this.plugins.registerFileType('wad', doomWadLoaderCallback); + * // later in your preload code: + * this.load.wad(); + * ``` + * + * The callback is what is called when the loader tries to load a file matching the given key. + * It's important to understand that the callback is invoked within + * the context of the LoaderPlugin. In this context there are several properties / methods available + * to use: + * + * this.addFile - A method to add the new file to the load queue. + * this.scene - The Scene that owns the Loader Plugin instance. + * + * See the LoaderPlugin class for more details. Any public property or method listed is available from + * your callback under `this`. + * + * @method Phaser.Plugins.PluginManager#registerFileType + * @since 3.8.0 + * + * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. + * @param {function} callback - The callback to invoke when the Game Object Factory is called. + * @param {Phaser.Scene} [addToScene] - Optionally add this file type into the Loader Plugin owned by the given Scene. + */ + registerFileType: function (key, callback, addToScene) + { + FileTypesManager.register(key, callback); + + if (addToScene && addToScene.sys.load) + { + addToScene.sys.load[key] = callback; + } + }, + + /** + * Destroys this Plugin Manager and all associated plugins. + * It will iterate all plugins found and call their `destroy` methods. + * + * The PluginCache will remove all custom plugins. + * + * @method Phaser.Plugins.PluginManager#destroy + * @since 3.8.0 + */ + destroy: function () + { + for (var i = 0; i < this.plugins.length; i++) + { + this.plugins[i].plugin.destroy(); + } + + PluginCache.destroyCustomPlugins(); + + if (this.game.noReturn) + { + PluginCache.destroyCorePlugins(); + } + + this.game = null; + this.plugins = []; + this.scenePlugins = []; + } + +}); + +/* + * "Sometimes, the elegant implementation is just a function. + * Not a method. Not a class. Not a framework. Just a function." + * -- John Carmack + */ + +module.exports = PluginManager; + + +/***/ }), +/* 409 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(198); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(101); +var GameEvents = __webpack_require__(22); +var GetInnerHeight = __webpack_require__(395); +var GetTarget = __webpack_require__(401); +var GetScreenOrientation = __webpack_require__(396); +var NOOP = __webpack_require__(1); +var Rectangle = __webpack_require__(10); +var Size = __webpack_require__(410); +var SnapFloor = __webpack_require__(76); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * The Scale Manager handles the scaling, resizing and alignment of the game canvas. + * + * The way scaling is handled is by setting the game canvas to a fixed size, which is defined in the + * game configuration. You also define the parent container in the game config. If no parent is given, + * it will default to using the document body. The Scale Manager will then look at the available space + * within the _parent_ and scale the canvas accordingly. Scaling is handled by setting the canvas CSS + * width and height properties, leaving the width and height of the canvas element itself untouched. + * Scaling is therefore achieved by keeping the core canvas the same size and 'stretching' + * it via its CSS properties. This gives the same result and speed as using the `transform-scale` CSS + * property, without the need for browser prefix handling. + * + * The calculations for the scale are heavily influenced by the bounding parent size, which is the computed + * dimensions of the canvas's parent. The CSS rules of the parent element play an important role in the + * operation of the Scale Manager. For example, if the parent has no defined width or height, then actions + * like auto-centering will fail to achieve the required result. The Scale Manager works in tandem with the + * CSS you set-up on the page hosting your game, rather than taking control of it. + * + * #### Parent and Display canvas containment guidelines: + * + * - Style the Parent element (of the game canvas) to control the Parent size and thus the games size and layout. + * + * - The Parent element's CSS styles should _effectively_ apply maximum (and minimum) bounding behavior. + * + * - The Parent element should _not_ apply a padding as this is not accounted for. + * If a padding is required apply it to the Parent's parent or apply a margin to the Parent. + * If you need to add a border, margin or any other CSS around your game container, then use a parent element and + * apply the CSS to this instead, otherwise you'll be constantly resizing the shape of the game container. + * + * - The Display canvas layout CSS styles (i.e. margins, size) should not be altered / specified as + * they may be updated by the Scale Manager. + * + * #### Scale Modes + * + * The way the scaling is handled is determined by the `scaleMode` property. The default is `NONE`, + * which prevents Phaser from scaling or touching the canvas, or its parent, at all. In this mode, you are + * responsible for all scaling. The other scaling modes afford you automatic scaling. + * + * If you wish to scale your game so that it always fits into the available space within the parent, you + * should use the scale mode `FIT`. Look at the documentation for other scale modes to see what options are + * available. Here is a basic config showing how to set this scale mode: + * + * ```javascript + * scale: { + * parent: 'yourgamediv', + * mode: Phaser.Scale.FIT, + * width: 800, + * height: 600 + * } + * ``` + * + * Place the `scale` config object within your game config. + * + * If you wish for the canvas to be resized directly, so that the canvas itself fills the available space + * (i.e. it isn't scaled, it's resized) then use the `RESIZE` scale mode. This will give you a 1:1 mapping + * of canvas pixels to game size. In this mode CSS isn't used to scale the canvas, it's literally adjusted + * to fill all available space within the parent. You should be extremely careful about the size of the + * canvas you're creating when doing this, as the larger the area, the more work the GPU has to do and it's + * very easy to hit fill-rate limits quickly. + * + * For complex, custom-scaling requirements, you should probably consider using the `RESIZE` scale mode, + * with your own limitations in place re: canvas dimensions and managing the scaling with the game scenes + * yourself. For the vast majority of games, however, the `FIT` mode is likely to be the most used. + * + * Please appreciate that the Scale Manager cannot perform miracles. All it does is scale your game canvas + * as best it can, based on what it can infer from its surrounding area. There are all kinds of environments + * where it's up to you to guide and help the canvas position itself, especially when built into rendering + * frameworks like React and Vue. If your page requires meta tags to prevent user scaling gestures, or such + * like, then it's up to you to ensure they are present in the html. + * + * #### Centering + * + * You can also have the game canvas automatically centered. Again, this relies heavily on the parent being + * properly configured and styled, as the centering offsets are based entirely on the available space + * within the parent element. Centering is disabled by default, or can be applied horizontally, vertically, + * or both. Here's an example: + * + * ```javascript + * scale: { + * parent: 'yourgamediv', + * autoCenter: Phaser.Scale.CENTER_BOTH, + * width: 800, + * height: 600 + * } + * ``` + * + * #### Fullscreen API + * + * If the browser supports it, you can send your game into fullscreen mode. In this mode, the game will fill + * the entire display, removing all browser UI and anything else present on the screen. It will remain in this + * mode until your game either disables it, or until the user tabs out or presses ESCape if on desktop. It's a + * great way to achieve a desktop-game like experience from the browser, but it does require a modern browser + * to handle it. Some mobile browsers also support this. + * + * @class ScaleManager + * @memberof Phaser.Scale + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.16.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance. + */ +var ScaleManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function ScaleManager (game) + { + EventEmitter.call(this); + + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Scale.ScaleManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.15.0 + */ + this.game = game; + + /** + * A reference to the HTML Canvas Element that Phaser uses to render the game. + * + * @name Phaser.Scale.ScaleManager#canvas + * @type {HTMLCanvasElement} + * @since 3.16.0 + */ + this.canvas; + + /** + * The DOM bounds of the canvas element. + * + * @name Phaser.Scale.ScaleManager#canvasBounds + * @type {Phaser.Geom.Rectangle} + * @since 3.16.0 + */ + this.canvasBounds = new Rectangle(); + + /** + * The parent object of the Canvas. Often a div, or the browser window, or nothing in non-browser environments. + * + * This is set in the Game Config as the `parent` property. If undefined (or just not present), it will default + * to use the document body. If specifically set to `null` Phaser will ignore all parent operations. + * + * @name Phaser.Scale.ScaleManager#parent + * @type {?any} + * @since 3.16.0 + */ + this.parent = null; + + /** + * Is the parent element the browser window? + * + * @name Phaser.Scale.ScaleManager#parentIsWindow + * @type {boolean} + * @since 3.16.0 + */ + this.parentIsWindow = false; + + /** + * The Parent Size component. + * + * @name Phaser.Scale.ScaleManager#parentSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.parentSize = new Size(); + + /** + * The Game Size component. + * + * The un-modified game size, as requested in the game config (the raw width / height), + * as used for world bounds, cameras, etc + * + * @name Phaser.Scale.ScaleManager#gameSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.gameSize = new Size(); + + /** + * The Base Size component. + * + * The modified game size, which is the auto-rounded gameSize, used to set the canvas width and height + * (but not the CSS style) + * + * @name Phaser.Scale.ScaleManager#baseSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.baseSize = new Size(); + + /** + * The Display Size component. + * + * The size used for the canvas style, factoring in the scale mode, parent and other values. + * + * @name Phaser.Scale.ScaleManager#displaySize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.displaySize = new Size(); + + /** + * The game scale mode. + * + * @name Phaser.Scale.ScaleManager#scaleMode + * @type {Phaser.Scale.ScaleModeType} + * @since 3.16.0 + */ + this.scaleMode = CONST.SCALE_MODE.NONE; + + /** + * The game zoom factor. + * + * This value allows you to multiply your games base size by the given zoom factor. + * This is then used when calculating the display size, even in `NONE` situations. + * If you don't want Phaser to touch the canvas style at all, this value should be 1. + * + * Can also be set to `MAX_ZOOM` in which case the zoom value will be derived based + * on the game size and available space within the parent. + * + * @name Phaser.Scale.ScaleManager#zoom + * @type {number} + * @since 3.16.0 + */ + this.zoom = 1; + + /** + * Internal flag set when the game zoom factor is modified. + * + * @name Phaser.Scale.ScaleManager#_resetZoom + * @type {boolean} + * @readonly + * @since 3.19.0 + */ + this._resetZoom = false; + + /** + * The scale factor between the baseSize and the canvasBounds. + * + * @name Phaser.Scale.ScaleManager#displayScale + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ + this.displayScale = new Vector2(1, 1); + + /** + * If set, the canvas sizes will be automatically passed through Math.floor. + * This results in rounded pixel display values, which is important for performance on legacy + * and low powered devices, but at the cost of not achieving a 'perfect' fit in some browser windows. + * + * @name Phaser.Scale.ScaleManager#autoRound + * @type {boolean} + * @since 3.16.0 + */ + this.autoRound = false; + + /** + * Automatically center the canvas within the parent? The different centering modes are: + * + * 1. No centering. + * 2. Center both horizontally and vertically. + * 3. Center horizontally. + * 4. Center vertically. + * + * Please be aware that in order to center the game canvas, you must have specified a parent + * that has a size set, or the canvas parent is the document.body. + * + * @name Phaser.Scale.ScaleManager#autoCenter + * @type {Phaser.Scale.CenterType} + * @since 3.16.0 + */ + this.autoCenter = CONST.CENTER.NO_CENTER; + + /** + * The current device orientation. + * + * Orientation events are dispatched via the Device Orientation API, typically only on mobile browsers. + * + * @name Phaser.Scale.ScaleManager#orientation + * @type {Phaser.Scale.OrientationType} + * @since 3.16.0 + */ + this.orientation = CONST.ORIENTATION.LANDSCAPE; + + /** + * A reference to the Device.Fullscreen object. + * + * @name Phaser.Scale.ScaleManager#fullscreen + * @type {Phaser.Device.Fullscreen} + * @since 3.16.0 + */ + this.fullscreen; + + /** + * The DOM Element which is sent into fullscreen mode. + * + * @name Phaser.Scale.ScaleManager#fullscreenTarget + * @type {?any} + * @since 3.16.0 + */ + this.fullscreenTarget = null; + + /** + * Did Phaser create the fullscreen target div, or was it provided in the game config? + * + * @name Phaser.Scale.ScaleManager#_createdFullscreenTarget + * @type {boolean} + * @private + * @since 3.16.0 + */ + this._createdFullscreenTarget = false; + + /** + * The dirty state of the Scale Manager. + * Set if there is a change between the parent size and the current size. + * + * @name Phaser.Scale.ScaleManager#dirty + * @type {boolean} + * @since 3.16.0 + */ + this.dirty = false; + + /** + * How many milliseconds should elapse before checking if the browser size has changed? + * + * Most modern browsers dispatch a 'resize' event, which the Scale Manager will listen for. + * However, older browsers fail to do this, or do it consistently, so we fall back to a + * more traditional 'size check' based on a time interval. You can control how often it is + * checked here. + * + * @name Phaser.Scale.ScaleManager#resizeInterval + * @type {number} + * @since 3.16.0 + */ + this.resizeInterval = 500; + + /** + * Internal size interval tracker. + * + * @name Phaser.Scale.ScaleManager#_lastCheck + * @type {number} + * @private + * @since 3.16.0 + */ + this._lastCheck = 0; + + /** + * Internal flag to check orientation state. + * + * @name Phaser.Scale.ScaleManager#_checkOrientation + * @type {boolean} + * @private + * @since 3.16.0 + */ + this._checkOrientation = false; + + /** + * Internal object containing our defined event listeners. + * + * @name Phaser.Scale.ScaleManager#listeners + * @type {object} + * @private + * @since 3.16.0 + */ + this.listeners = { + + orientationChange: NOOP, + windowResize: NOOP, + fullScreenChange: NOOP, + fullScreenError: NOOP + + }; + }, + + /** + * Called _before_ the canvas object is created and added to the DOM. + * + * @method Phaser.Scale.ScaleManager#preBoot + * @protected + * @listens Phaser.Core.Events#BOOT + * @since 3.16.0 + */ + preBoot: function () + { + // Parse the config to get the scaling values we need + this.parseConfig(this.game.config); + + this.game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot handler is called by Phaser.Game when it first starts up. + * The renderer is available by now and the canvas has been added to the DOM. + * + * @method Phaser.Scale.ScaleManager#boot + * @protected + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + */ + boot: function () + { + var game = this.game; + + this.canvas = game.canvas; + + this.fullscreen = game.device.fullscreen; + + if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) + { + this.displaySize.setAspectMode(this.scaleMode); + } + + if (this.scaleMode === CONST.SCALE_MODE.NONE) + { + this.resize(this.width, this.height); + } + else + { + this.getParentBounds(); + + // Only set the parent bounds if the parent has an actual size + if (this.parentSize.width > 0 && this.parentSize.height > 0) + { + this.displaySize.setParent(this.parentSize); + } + + this.refresh(); + } + + game.events.on(GameEvents.PRE_STEP, this.step, this); + game.events.once(GameEvents.READY, this.refresh, this); + game.events.once(GameEvents.DESTROY, this.destroy, this); + + this.startListeners(); + }, + + /** + * Parses the game configuration to set-up the scale defaults. + * + * @method Phaser.Scale.ScaleManager#parseConfig + * @protected + * @since 3.16.0 + * + * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. + */ + parseConfig: function (config) + { + // Get the parent element, if any + this.getParent(config); + + // Get the size of the parent element + // This can often set a height of zero (especially for un-styled divs) + this.getParentBounds(); + + var width = config.width; + var height = config.height; + var scaleMode = config.scaleMode; + var zoom = config.zoom; + var autoRound = config.autoRound; + + // If width = '100%', or similar value + if (typeof width === 'string') + { + // If we have a parent with a height, we'll work it out from that + var parentWidth = this.parentSize.width; + + if (parentWidth === 0) + { + parentWidth = window.innerWidth; + } + + var parentScaleX = parseInt(width, 10) / 100; + + width = Math.floor(parentWidth * parentScaleX); + } + + // If height = '100%', or similar value + if (typeof height === 'string') + { + // If we have a parent with a height, we'll work it out from that + var parentHeight = this.parentSize.height; + + if (parentHeight === 0) + { + parentHeight = window.innerHeight; + } + + var parentScaleY = parseInt(height, 10) / 100; + + height = Math.floor(parentHeight * parentScaleY); + } + + this.scaleMode = scaleMode; + + this.autoRound = autoRound; + + this.autoCenter = config.autoCenter; + + this.resizeInterval = config.resizeInterval; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.setSize(width, height); + + if (zoom === CONST.ZOOM.MAX_ZOOM) + { + zoom = this.getMaxZoom(); + } + + this.zoom = zoom; + + if (zoom !== 1) + { + this._resetZoom = true; + } + + // The modified game size + this.baseSize.setSize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + if (config.minWidth > 0) + { + this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom); + } + + if (config.maxWidth > 0) + { + this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) + this.displaySize.setSize(width, height); + + this.orientation = GetScreenOrientation(width, height); + }, + + /** + * Determines the parent element of the game canvas, if any, based on the game configuration. + * + * @method Phaser.Scale.ScaleManager#getParent + * @since 3.16.0 + * + * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. + */ + getParent: function (config) + { + var parent = config.parent; + + if (parent === null) + { + // User is responsible for managing the parent + return; + } + + this.parent = GetTarget(parent); + this.parentIsWindow = (this.parent === document.body); + + if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) + { + var DOMRect = this.parent.getBoundingClientRect(); + + if (this.parentIsWindow || DOMRect.height === 0) + { + document.documentElement.style.height = '100%'; + document.body.style.height = '100%'; + + DOMRect = this.parent.getBoundingClientRect(); + + // The parent STILL has no height, clearly no CSS + // has been set on it even though we fixed the body :( + if (!this.parentIsWindow && DOMRect.height === 0) + { + this.parent.style.overflow = 'hidden'; + this.parent.style.width = '100%'; + this.parent.style.height = '100%'; + } + } + } + + // And now get the fullscreenTarget + if (config.fullscreenTarget && !this.fullscreenTarget) + { + this.fullscreenTarget = GetTarget(config.fullscreenTarget); + } + }, + + /** + * Calculates the size of the parent bounds and updates the `parentSize` component, if the canvas has a dom parent. + * + * @method Phaser.Scale.ScaleManager#getParentBounds + * @since 3.16.0 + * + * @return {boolean} `true` if the parent bounds have changed size, otherwise `false`. + */ + getParentBounds: function () + { + if (!this.parent) + { + return false; + } + + var parentSize = this.parentSize; + + // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect + + var DOMRect = this.parent.getBoundingClientRect(); + + if (this.parentIsWindow && this.game.device.os.iOS) + { + DOMRect.height = GetInnerHeight(true); + } + + var newWidth = DOMRect.width; + var newHeight = DOMRect.height; + + if (parentSize.width !== newWidth || parentSize.height !== newHeight) + { + parentSize.setSize(newWidth, newHeight); + + return true; + } + else + { + return false; + } + }, + + /** + * Attempts to lock the orientation of the web browser using the Screen Orientation API. + * + * This API is only available on modern mobile browsers. + * See https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation for details. + * + * @method Phaser.Scale.ScaleManager#lockOrientation + * @since 3.16.0 + * + * @param {string} orientation - The orientation you'd like to lock the browser in. Should be an API string such as 'landscape', 'landscape-primary', 'portrait', etc. + * + * @return {boolean} `true` if the orientation was successfully locked, otherwise `false`. + */ + lockOrientation: function (orientation) + { + var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation; + + if (lock) + { + return lock.call(screen, orientation); + } + + return false; + }, + + /** + * This method will set the size of the Parent Size component, which is used in scaling + * and centering calculations. You only need to call this method if you have explicitly + * disabled the use of a parent in your game config, but still wish to take advantage of + * other Scale Manager features. + * + * @method Phaser.Scale.ScaleManager#setParentSize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the parent. + * @param {number} height - The new height of the parent. + * + * @return {this} The Scale Manager instance. + */ + setParentSize: function (width, height) + { + this.parentSize.setSize(width, height); + + return this.refresh(); + }, + + /** + * This method will set a new size for your game. + * + * It should only be used if you're looking to change the base size of your game and are using + * one of the Scale Manager scaling modes, i.e. `FIT`. If you're using `NONE` and wish to + * change the game and canvas size directly, then please use the `resize` method instead. + * + * @method Phaser.Scale.ScaleManager#setGameSize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the game. + * @param {number} height - The new height of the game. + * + * @return {this} The Scale Manager instance. + */ + setGameSize: function (width, height) + { + var autoRound = this.autoRound; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + var previousWidth = this.width; + var previousHeight = this.height; + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.resize(width, height); + + // The modified game size + this.baseSize.resize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // Update the aspect ratio + this.displaySize.setAspectRatio(width / height); + + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; + + return this.refresh(previousWidth, previousHeight); + }, + + /** + * Call this to modify the size of the Phaser canvas element directly. + * You should only use this if you are using the `NONE` scale mode, + * it will update all internal components completely. + * + * If all you want to do is change the size of the parent, see the `setParentSize` method. + * + * If all you want is to change the base size of the game, but still have the Scale Manager + * manage all the scaling (i.e. you're **not** using `NONE`), then see the `setGameSize` method. + * + * This method will set the `gameSize`, `baseSize` and `displaySize` components to the given + * dimensions. It will then resize the canvas width and height to the values given, by + * directly setting the properties. Finally, if you have set the Scale Manager zoom value + * to anything other than 1 (the default), it will set the canvas CSS width and height to + * be the given size multiplied by the zoom factor (the canvas pixel size remains untouched). + * + * If you have enabled `autoCenter`, it is then passed to the `updateCenter` method and + * the margins are set, allowing the canvas to be centered based on its parent element + * alone. Finally, the `displayScale` is adjusted and the RESIZE event dispatched. + * + * @method Phaser.Scale.ScaleManager#resize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the game. + * @param {number} height - The new height of the game. + * + * @return {this} The Scale Manager instance. + */ + resize: function (width, height) + { + var zoom = this.zoom; + var autoRound = this.autoRound; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + var previousWidth = this.width; + var previousHeight = this.height; + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.resize(width, height); + + // The modified game size + this.baseSize.resize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) + this.displaySize.setSize((width * zoom), (height * zoom)); + + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; + + var style = this.canvas.style; + + var styleWidth = width * zoom; + var styleHeight = height * zoom; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + if (styleWidth !== width || styleHeight !== height) + { + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + } + + return this.refresh(previousWidth, previousHeight); + }, + + /** + * Sets the zoom value of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#setZoom + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} value - The new zoom value of the game. + * + * @return {this} The Scale Manager instance. + */ + setZoom: function (value) + { + this.zoom = value; + this._resetZoom = true; + + return this.refresh(); + }, + + /** + * Sets the zoom to be the maximum possible based on the _current_ parent size. + * + * @method Phaser.Scale.ScaleManager#setMaxZoom + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @return {this} The Scale Manager instance. + */ + setMaxZoom: function () + { + this.zoom = this.getMaxZoom(); + this._resetZoom = true; + + return this.refresh(); + }, + + /** + * Refreshes the internal scale values, bounds sizes and orientation checks. + * + * Once finished, dispatches the resize event. + * + * This is called automatically by the Scale Manager when the browser window size changes, + * as long as it is using a Scale Mode other than 'NONE'. + * + * @method Phaser.Scale.ScaleManager#refresh + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} [previousWidth] - The previous width of the game. Only set if the gameSize has changed. + * @param {number} [previousHeight] - The previous height of the game. Only set if the gameSize has changed. + * + * @return {this} The Scale Manager instance. + */ + refresh: function (previousWidth, previousHeight) + { + if (previousWidth === undefined) { previousWidth = this.width; } + if (previousHeight === undefined) { previousHeight = this.height; } + + this.updateScale(); + this.updateBounds(); + this.updateOrientation(); + + this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); + + var domContainer = this.game.domContainer; + + if (domContainer) + { + this.baseSize.setCSS(domContainer); + + var canvasStyle = this.canvas.style; + var domStyle = domContainer.style; + + domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; + + domStyle.marginLeft = canvasStyle.marginLeft; + domStyle.marginTop = canvasStyle.marginTop; + } + + this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); + + return this; + }, + + /** + * Internal method that checks the current screen orientation, only if the internal check flag is set. + * + * If the orientation has changed it updates the orientation property and then dispatches the orientation change event. + * + * @method Phaser.Scale.ScaleManager#updateOrientation + * @fires Phaser.Scale.Events#ORIENTATION_CHANGE + * @since 3.16.0 + */ + updateOrientation: function () + { + if (this._checkOrientation) + { + this._checkOrientation = false; + + var newOrientation = GetScreenOrientation(this.width, this.height); + + if (newOrientation !== this.orientation) + { + this.orientation = newOrientation; + + this.emit(Events.ORIENTATION_CHANGE, newOrientation); + } + } + }, + + /** + * Internal method that manages updating the size components based on the scale mode. + * + * @method Phaser.Scale.ScaleManager#updateScale + * @since 3.16.0 + */ + updateScale: function () + { + var style = this.canvas.style; + + var width = this.gameSize.width; + var height = this.gameSize.height; + + var styleWidth; + var styleHeight; + + var zoom = this.zoom; + var autoRound = this.autoRound; + + if (this.scaleMode === CONST.SCALE_MODE.NONE) + { + // No scale + this.displaySize.setSize((width * zoom), (height * zoom)); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + if (this._resetZoom) + { + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + + this._resetZoom = false; + } + } + else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) + { + // Resize to match parent + + // This will constrain using min/max + this.displaySize.setSize(this.parentSize.width, this.parentSize.height); + + this.gameSize.setSize(this.displaySize.width, this.displaySize.height); + + this.baseSize.setSize(this.displaySize.width, this.displaySize.height); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + this.canvas.width = styleWidth; + this.canvas.height = styleHeight; + } + else + { + // All other scale modes + this.displaySize.setSize(this.parentSize.width, this.parentSize.height); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + } + + // Update the parentSize in case the canvas / style change modified it + this.getParentBounds(); + + // Finally, update the centering + this.updateCenter(); + }, + + /** + * Calculates and returns the largest possible zoom factor, based on the current + * parent and game sizes. If the parent has no dimensions (i.e. an unstyled div), + * or is smaller than the un-zoomed game, then this will return a value of 1 (no zoom) + * + * @method Phaser.Scale.ScaleManager#getMaxZoom + * @since 3.16.0 + * + * @return {number} The maximum possible zoom factor. At a minimum this value is always at least 1. + */ + getMaxZoom: function () + { + var zoomH = SnapFloor(this.parentSize.width, this.gameSize.width, 0, true); + var zoomV = SnapFloor(this.parentSize.height, this.gameSize.height, 0, true); + + return Math.max(Math.min(zoomH, zoomV), 1); + }, + + /** + * Calculates and updates the canvas CSS style in order to center it within the + * bounds of its parent. If you have explicitly set parent to be `null` in your + * game config then this method will likely give incorrect results unless you have called the + * `setParentSize` method first. + * + * It works by modifying the canvas CSS `marginLeft` and `marginTop` properties. + * + * If they have already been set by your own style sheet, or code, this will overwrite them. + * + * To prevent the Scale Manager from centering the canvas, either do not set the + * `autoCenter` property in your game config, or make sure it is set to `NO_CENTER`. + * + * @method Phaser.Scale.ScaleManager#updateCenter + * @since 3.16.0 + */ + updateCenter: function () + { + var autoCenter = this.autoCenter; + + if (autoCenter === CONST.CENTER.NO_CENTER) + { + return; + } + + var canvas = this.canvas; + + var style = canvas.style; + + var bounds = canvas.getBoundingClientRect(); + + // var width = parseInt(canvas.style.width, 10) || canvas.width; + // var height = parseInt(canvas.style.height, 10) || canvas.height; + + var width = bounds.width; + var height = bounds.height; + + var offsetX = Math.floor((this.parentSize.width - width) / 2); + var offsetY = Math.floor((this.parentSize.height - height) / 2); + + if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) + { + offsetY = 0; + } + else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) + { + offsetX = 0; + } + + style.marginLeft = offsetX + 'px'; + style.marginTop = offsetY + 'px'; + }, + + /** + * Updates the `canvasBounds` rectangle to match the bounding client rectangle of the + * canvas element being used to track input events. + * + * @method Phaser.Scale.ScaleManager#updateBounds + * @since 3.16.0 + */ + updateBounds: function () + { + var bounds = this.canvasBounds; + var clientRect = this.canvas.getBoundingClientRect(); + + bounds.x = clientRect.left + (window.pageXOffset || 0) - (document.documentElement.clientLeft || 0); + bounds.y = clientRect.top + (window.pageYOffset || 0) - (document.documentElement.clientTop || 0); + bounds.width = clientRect.width; + bounds.height = clientRect.height; + }, + + /** + * Transforms the pageX value into the scaled coordinate space of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#transformX + * @since 3.16.0 + * + * @param {number} pageX - The DOM pageX value. + * + * @return {number} The translated value. + */ + transformX: function (pageX) + { + return (pageX - this.canvasBounds.left) * this.displayScale.x; + }, + + /** + * Transforms the pageY value into the scaled coordinate space of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#transformY + * @since 3.16.0 + * + * @param {number} pageY - The DOM pageY value. + * + * @return {number} The translated value. + */ + transformY: function (pageY) + { + return (pageY - this.canvasBounds.top) * this.displayScale.y; + }, + + /** + * Sends a request to the browser to ask it to go in to full screen mode, using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API Fullscreen API}. + * + * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. + * + * This method _must_ be called from a `pointerup` user-input gesture (**not** `pointerdown`). You cannot launch + * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked + * from fullscreen unless the iframe has the `allowfullscreen` attribute. + * + * On touch devices, such as Android and iOS Safari, you should always use `pointerup` and NOT `pointerdown`, + * otherwise the request will fail unless the document in which your game is embedded has already received + * some form of touch input, which you cannot guarantee. Activating fullscreen via `pointerup` circumvents + * this issue. + * + * Performing an action that navigates to another page, or opens another tab, will automatically cancel + * fullscreen mode, as will the user pressing the ESC key. To cancel fullscreen mode directly from your game, + * i.e. by clicking an icon, call the `stopFullscreen` method. + * + * A browser can only send one DOM element into fullscreen. You can control which element this is by + * setting the `fullscreenTarget` property in your game config, or changing the property in the Scale Manager. + * Note that the game canvas _must_ be a child of the target. If you do not give a target, Phaser will + * automatically create a blank `
` element and move the canvas into it, before going fullscreen. + * When it leaves fullscreen, the div will be removed. + * + * @method Phaser.Scale.ScaleManager#startFullscreen + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_FAILED + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. + */ + startFullscreen: function (fullscreenOptions) + { + if (fullscreenOptions === undefined) { fullscreenOptions = { navigationUI: 'hide' }; } + + var fullscreen = this.fullscreen; + + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); + + return; + } + + if (!fullscreen.active) + { + var fsTarget = this.getFullscreenTarget(); + + if (fullscreen.keyboard) + { + fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); + } + else + { + fsTarget[fullscreen.request](fullscreenOptions); + } + } + }, + + /** + * The browser has successfully entered fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#fullscreenSuccessHandler + * @private + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#RESIZE + * @since 3.17.0 + */ + fullscreenSuccessHandler: function () + { + this.getParentBounds(); + + this.refresh(); + + this.emit(Events.ENTER_FULLSCREEN); + }, + + /** + * The browser failed to enter fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#fullscreenErrorHandler + * @private + * @fires Phaser.Scale.Events#FULLSCREEN_FAILED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.17.0 + * + * @param {any} error - The DOM error event. + */ + fullscreenErrorHandler: function (error) + { + this.removeFullscreenTarget(); + + this.emit(Events.FULLSCREEN_FAILED, error); + }, + + /** + * An internal method that gets the target element that is used when entering fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#getFullscreenTarget + * @since 3.16.0 + * + * @return {object} The fullscreen target element. + */ + getFullscreenTarget: function () + { + if (!this.fullscreenTarget) + { + var fsTarget = document.createElement('div'); + + fsTarget.style.margin = '0'; + fsTarget.style.padding = '0'; + fsTarget.style.width = '100%'; + fsTarget.style.height = '100%'; + + this.fullscreenTarget = fsTarget; + + this._createdFullscreenTarget = true; + } + + if (this._createdFullscreenTarget) + { + var canvasParent = this.canvas.parentNode; + + canvasParent.insertBefore(this.fullscreenTarget, this.canvas); + + this.fullscreenTarget.appendChild(this.canvas); + } + + return this.fullscreenTarget; + }, + + /** + * Removes the fullscreen target that was added to the DOM. + * + * @method Phaser.Scale.ScaleManager#removeFullscreenTarget + * @since 3.17.0 + */ + removeFullscreenTarget: function () + { + if (this._createdFullscreenTarget) + { + var fsTarget = this.fullscreenTarget; + + if (fsTarget && fsTarget.parentNode) + { + var parent = fsTarget.parentNode; + + parent.insertBefore(this.canvas, fsTarget); + + parent.removeChild(fsTarget); + } + } + }, + + /** + * Calling this method will cancel fullscreen mode, if the browser has entered it. + * + * @method Phaser.Scale.ScaleManager#stopFullscreen + * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @since 3.16.0 + */ + stopFullscreen: function () + { + var fullscreen = this.fullscreen; + + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); + + return false; + } + + if (fullscreen.active) + { + document[fullscreen.cancel](); + } + + this.removeFullscreenTarget(); + + // Get the parent size again as it will have changed + this.getParentBounds(); + + this.emit(Events.LEAVE_FULLSCREEN); + + this.refresh(); + }, + + /** + * Toggles the fullscreen mode. If already in fullscreen, calling this will cancel it. + * If not in fullscreen, this will request the browser to enter fullscreen mode. + * + * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. + * + * This method _must_ be called from a user-input gesture, such as `pointerdown`. You cannot launch + * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked + * from fullscreen unless the iframe has the `allowfullscreen` attribute. + * + * @method Phaser.Scale.ScaleManager#toggleFullscreen + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. + */ + toggleFullscreen: function (fullscreenOptions) + { + if (this.fullscreen.active) + { + this.stopFullscreen(); + } + else + { + this.startFullscreen(fullscreenOptions); + } + }, + + /** + * An internal method that starts the different DOM event listeners running. + * + * @method Phaser.Scale.ScaleManager#startListeners + * @since 3.16.0 + */ + startListeners: function () + { + var _this = this; + var listeners = this.listeners; + + listeners.orientationChange = function () + { + _this.updateBounds(); + + _this._checkOrientation = true; + _this.dirty = true; + }; + + listeners.windowResize = function () + { + _this.updateBounds(); + + _this.dirty = true; + }; + + // Only dispatched on mobile devices + window.addEventListener('orientationchange', listeners.orientationChange, false); + + window.addEventListener('resize', listeners.windowResize, false); + + if (this.fullscreen.available) + { + listeners.fullScreenChange = function (event) + { + return _this.onFullScreenChange(event); + }; + + listeners.fullScreenError = function (event) + { + return _this.onFullScreenError(event); + }; + + var vendors = [ 'webkit', 'moz', '' ]; + + vendors.forEach(function (prefix) + { + document.addEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); + document.addEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); + }); + + // MS Specific + document.addEventListener('MSFullscreenChange', listeners.fullScreenChange, false); + document.addEventListener('MSFullscreenError', listeners.fullScreenError, false); + } + }, + + /** + * Triggered when a fullscreenchange event is dispatched by the DOM. + * + * @method Phaser.Scale.ScaleManager#onFullScreenChange + * @protected + * @since 3.16.0 + */ + onFullScreenChange: function () + { + if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) + { + this.fullscreenSuccessHandler(); + } + else + { + // They pressed ESC while in fullscreen mode + this.stopFullscreen(); + } + }, + + /** + * Triggered when a fullscreenerror event is dispatched by the DOM. + * + * @method Phaser.Scale.ScaleManager#onFullScreenError + * @since 3.16.0 + */ + onFullScreenError: function () + { + this.removeFullscreenTarget(); + }, + + /** + * Internal method, called automatically by the game step. + * Monitors the elapsed time and resize interval to see if a parent bounds check needs to take place. + * + * @method Phaser.Scale.ScaleManager#step + * @since 3.16.0 + * + * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). + * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. + */ + step: function (time, delta) + { + if (!this.parent) + { + return; + } + + this._lastCheck += delta; + + if (this.dirty || this._lastCheck > this.resizeInterval) + { + // Returns true if the parent bounds have changed size + if (this.getParentBounds()) + { + this.refresh(); + } + + this.dirty = false; + this._lastCheck = 0; + } + }, + + /** + * Stops all DOM event listeners. + * + * @method Phaser.Scale.ScaleManager#stopListeners + * @since 3.16.0 + */ + stopListeners: function () + { + var listeners = this.listeners; + + window.removeEventListener('orientationchange', listeners.orientationChange, false); + window.removeEventListener('resize', listeners.windowResize, false); + + var vendors = [ 'webkit', 'moz', '' ]; + + vendors.forEach(function (prefix) + { + document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); + document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); + }); + + // MS Specific + document.removeEventListener('MSFullscreenChange', listeners.fullScreenChange, false); + document.removeEventListener('MSFullscreenError', listeners.fullScreenError, false); + }, + + /** + * Destroys this Scale Manager, releasing all references to external resources. + * Once destroyed, the Scale Manager cannot be used again. + * + * @method Phaser.Scale.ScaleManager#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.stopListeners(); + + this.game = null; + this.canvas = null; + this.canvasBounds = null; + this.parent = null; + this.fullscreenTarget = null; + + this.parentSize.destroy(); + this.gameSize.destroy(); + this.baseSize.destroy(); + this.displaySize.destroy(); + }, + + /** + * Is the browser currently in fullscreen mode or not? + * + * @name Phaser.Scale.ScaleManager#isFullscreen + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isFullscreen: { + + get: function () + { + return this.fullscreen.active; + } + + }, + + /** + * The game width. + * + * This is typically the size given in the game configuration. + * + * @name Phaser.Scale.ScaleManager#width + * @type {number} + * @readonly + * @since 3.16.0 + */ + width: { + + get: function () + { + return this.gameSize.width; + } + + }, + + /** + * The game height. + * + * This is typically the size given in the game configuration. + * + * @name Phaser.Scale.ScaleManager#height + * @type {number} + * @readonly + * @since 3.16.0 + */ + height: { + + get: function () + { + return this.gameSize.height; + } + + }, + + /** + * Is the device in a portrait orientation as reported by the Orientation API? + * This value is usually only available on mobile devices. + * + * @name Phaser.Scale.ScaleManager#isPortrait + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isPortrait: { + + get: function () + { + return (this.orientation === CONST.ORIENTATION.PORTRAIT); + } + + }, + + /** + * Is the device in a landscape orientation as reported by the Orientation API? + * This value is usually only available on mobile devices. + * + * @name Phaser.Scale.ScaleManager#isLandscape + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isLandscape: { + + get: function () + { + return (this.orientation === CONST.ORIENTATION.LANDSCAPE); + } + + }, + + /** + * Are the game dimensions portrait? (i.e. taller than they are wide) + * + * This is different to the device itself being in a portrait orientation. + * + * @name Phaser.Scale.ScaleManager#isGamePortrait + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isGamePortrait: { + + get: function () + { + return (this.height > this.width); + } + + }, + + /** + * Are the game dimensions landscape? (i.e. wider than they are tall) + * + * This is different to the device itself being in a landscape orientation. + * + * @name Phaser.Scale.ScaleManager#isGameLandscape + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isGameLandscape: { + + get: function () + { + return (this.width > this.height); + } + + } + +}); + +module.exports = ScaleManager; + + +/***/ }), +/* 410 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(18); +var Class = __webpack_require__(0); +var SnapFloor = __webpack_require__(76); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * The Size component allows you to set `width` and `height` properties and define the relationship between them. + * + * The component can automatically maintain the aspect ratios between the two values, and clamp them + * to a defined min-max range. You can also control the dominant axis. When dimensions are given to the Size component + * that would cause it to exceed its min-max range, the dimensions are adjusted based on the dominant axis. + * + * @class Size + * @memberof Phaser.Structs + * @constructor + * @since 3.16.0 + * + * @param {number} [width=0] - The width of the Size component. + * @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`. + * @param {number} [aspectMode=0] - The aspect mode of the Size component. Defaults to 0, no mode. + * @param {any} [parent=null] - The parent of this Size component. Can be any object with public `width` and `height` properties. Dimensions are clamped to keep them within the parent bounds where possible. + */ +var Size = new Class({ + + initialize: + + function Size (width, height, aspectMode, parent) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + if (aspectMode === undefined) { aspectMode = 0; } + if (parent === undefined) { parent = null; } + + /** + * Internal width value. + * + * @name Phaser.Structs.Size#_width + * @type {number} + * @private + * @since 3.16.0 + */ + this._width = width; + + /** + * Internal height value. + * + * @name Phaser.Structs.Size#_height + * @type {number} + * @private + * @since 3.16.0 + */ + this._height = height; + + /** + * Internal parent reference. + * + * @name Phaser.Structs.Size#_parent + * @type {any} + * @private + * @since 3.16.0 + */ + this._parent = parent; + + /** + * The aspect mode this Size component will use when calculating its dimensions. + * This property is read-only. To change it use the `setAspectMode` method. + * + * @name Phaser.Structs.Size#aspectMode + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.aspectMode = aspectMode; + + /** + * The proportional relationship between the width and height. + * + * This property is read-only and is updated automatically when either the `width` or `height` properties are changed, + * depending on the aspect mode. + * + * @name Phaser.Structs.Size#aspectRatio + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.aspectRatio = (height === 0) ? 1 : width / height; + + /** + * The minimum allowed width. + * Cannot be less than zero. + * This value is read-only. To change it see the `setMin` method. + * + * @name Phaser.Structs.Size#minWidth + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.minWidth = 0; + + /** + * The minimum allowed height. + * Cannot be less than zero. + * This value is read-only. To change it see the `setMin` method. + * + * @name Phaser.Structs.Size#minHeight + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.minHeight = 0; + + /** + * The maximum allowed width. + * This value is read-only. To change it see the `setMax` method. + * + * @name Phaser.Structs.Size#maxWidth + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.maxWidth = Number.MAX_VALUE; + + /** + * The maximum allowed height. + * This value is read-only. To change it see the `setMax` method. + * + * @name Phaser.Structs.Size#maxHeight + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.maxHeight = Number.MAX_VALUE; + + /** + * A Vector2 containing the horizontal and vertical snap values, which the width and height are snapped to during resizing. + * + * By default this is disabled. + * + * This property is read-only. To change it see the `setSnap` method. + * + * @name Phaser.Structs.Size#snapTo + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.16.0 + */ + this.snapTo = new Vector2(); + }, + + /** + * Sets the aspect mode of this Size component. + * + * The aspect mode controls what happens when you modify the `width` or `height` properties, or call `setSize`. + * + * It can be a number from 0 to 4, or a Size constant: + * + * 0. NONE = Do not make the size fit the aspect ratio. Change the ratio when the size changes. + * 1. WIDTH_CONTROLS_HEIGHT = The height is automatically adjusted based on the width. + * 2. HEIGHT_CONTROLS_WIDTH = The width is automatically adjusted based on the height. + * 3. FIT = The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. + * 4. ENVELOP = The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. + * + * Calling this method automatically recalculates the `width` and the `height`, if required. + * + * @method Phaser.Structs.Size#setAspectMode + * @since 3.16.0 + * + * @param {number} [value=0] - The aspect mode value. + * + * @return {this} This Size component instance. + */ + setAspectMode: function (value) + { + if (value === undefined) { value = 0; } + + this.aspectMode = value; + + return this.setSize(this._width, this._height); + }, + + /** + * By setting a Snap To value when this Size component is modified its dimensions will automatically + * by snapped to the nearest grid slice, using floor. For example, if you have snap value of 16, + * and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored) + * + * Note that snapping takes place before adjustments by the parent, or the min / max settings. If these + * values are not multiples of the given snap values, then this can result in un-snapped dimensions. + * + * Call this method with no arguments to reset the snap values. + * + * Calling this method automatically recalculates the `width` and the `height`, if required. + * + * @method Phaser.Structs.Size#setSnap + * @since 3.16.0 + * + * @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero. + * @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero. + * + * @return {this} This Size component instance. + */ + setSnap: function (snapWidth, snapHeight) + { + if (snapWidth === undefined) { snapWidth = 0; } + if (snapHeight === undefined) { snapHeight = snapWidth; } + + this.snapTo.set(snapWidth, snapHeight); + + return this.setSize(this._width, this._height); + }, + + /** + * Sets, or clears, the parent of this Size component. + * + * To clear the parent call this method with no arguments. + * + * The parent influences the maximum extents to which this Size component can expand, + * based on the aspect mode: + * + * NONE - The parent clamps both the width and height. + * WIDTH_CONTROLS_HEIGHT - The parent clamps just the width. + * HEIGHT_CONTROLS_WIDTH - The parent clamps just the height. + * FIT - The parent clamps whichever axis is required to ensure the size fits within it. + * ENVELOP - The parent is used to ensure the size fully envelops the parent. + * + * Calling this method automatically calls `setSize`. + * + * @method Phaser.Structs.Size#setParent + * @since 3.16.0 + * + * @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent. + * + * @return {this} This Size component instance. + */ + setParent: function (parent) + { + this._parent = parent; + + return this.setSize(this._width, this._height); + }, + + /** + * Set the minimum width and height values this Size component will allow. + * + * The minimum values can never be below zero, or greater than the maximum values. + * + * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. + * + * Note that based on the aspect mode, and if this Size component has a parent set or not, the minimums set here + * _can_ be exceed in some situations. + * + * @method Phaser.Structs.Size#setMin + * @since 3.16.0 + * + * @param {number} [width=0] - The minimum allowed width of the Size component. + * @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setMin: function (width, height) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + + this.minWidth = Clamp(width, 0, this.maxWidth); + this.minHeight = Clamp(height, 0, this.maxHeight); + + return this.setSize(this._width, this._height); + }, + + /** + * Set the maximum width and height values this Size component will allow. + * + * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. + * + * Note that based on the aspect mode, and if this Size component has a parent set or not, the maximums set here + * _can_ be exceed in some situations. + * + * @method Phaser.Structs.Size#setMax + * @since 3.16.0 + * + * @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component. + * @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setMax: function (width, height) + { + if (width === undefined) { width = Number.MAX_VALUE; } + if (height === undefined) { height = width; } + + this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); + this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); + + return this.setSize(this._width, this._height); + }, + + /** + * Sets the width and height of this Size component based on the aspect mode. + * + * If the aspect mode is 'none' then calling this method will change the aspect ratio, otherwise the current + * aspect ratio is honored across all other modes. + * + * If snapTo values have been set then the given width and height are snapped first, prior to any further + * adjustment via min/max values, or a parent. + * + * If minimum and/or maximum dimensions have been specified, the values given to this method will be clamped into + * that range prior to adjustment, but may still exceed them depending on the aspect mode. + * + * If this Size component has a parent set, and the aspect mode is `fit` or `envelop`, then the given sizes will + * be clamped to the range specified by the parent. + * + * @method Phaser.Structs.Size#setSize + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setSize: function (width, height) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + + switch (this.aspectMode) + { + case Size.NONE: + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; + break; + + case Size.WIDTH_CONTROLS_HEIGHT: + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(this._width * (1 / this.aspectRatio), false); + break; + + case Size.HEIGHT_CONTROLS_WIDTH: + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this._width = this.getNewWidth(this._height * this.aspectRatio, false); + break; + + case Size.FIT: + this.constrain(width, height, true); + break; + + case Size.ENVELOP: + this.constrain(width, height, false); + break; + } + + return this; + }, + + /** + * Sets a new aspect ratio, overriding what was there previously. + * + * It then calls `setSize` immediately using the current dimensions. + * + * @method Phaser.Structs.Size#setAspectRatio + * @since 3.16.0 + * + * @param {number} ratio - The new aspect ratio. + * + * @return {this} This Size component instance. + */ + setAspectRatio: function (ratio) + { + this.aspectRatio = ratio; + + return this.setSize(this._width, this._height); + }, + + /** + * Sets a new width and height for this Size component and updates the aspect ratio based on them. + * + * It _doesn't_ change the `aspectMode` and still factors in size limits such as the min max and parent bounds. + * + * @method Phaser.Structs.Size#resize + * @since 3.16.0 + * + * @param {number} width - The new width of the Size component. + * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + resize: function (width, height) + { + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; + + return this; + }, + + /** + * Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width. + * + * @method Phaser.Structs.Size#getNewWidth + * @since 3.16.0 + * + * @param {number} value - The value to clamp and check. + * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * + * @return {number} The modified width value. + */ + getNewWidth: function (value, checkParent) + { + if (checkParent === undefined) { checkParent = true; } + + value = Clamp(value, this.minWidth, this.maxWidth); + + if (checkParent && this._parent && value > this._parent.width) + { + value = Math.max(this.minWidth, this._parent.width); + } + + return value; + }, + + /** + * Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height. + * + * @method Phaser.Structs.Size#getNewHeight + * @since 3.16.0 + * + * @param {number} value - The value to clamp and check. + * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * + * @return {number} The modified height value. + */ + getNewHeight: function (value, checkParent) + { + if (checkParent === undefined) { checkParent = true; } + + value = Clamp(value, this.minHeight, this.maxHeight); + + if (checkParent && this._parent && value > this._parent.height) + { + value = Math.max(this.minHeight, this._parent.height); + } + + return value; + }, + + /** + * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. + * + * If `fit` is true there may be some space inside the target area which is not covered if its aspect ratio differs. + * If `fit` is false the size may extend further out than the target area if the aspect ratios differ. + * + * If this Size component has a parent set, then the width and height passed to this method will be clamped so + * it cannot exceed that of the parent. + * + * @method Phaser.Structs.Size#constrain + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * @param {boolean} [fit=true] - Perform a `fit` (true) constraint, or an `envelop` (false) constraint. + * + * @return {this} This Size component instance. + */ + constrain: function (width, height, fit) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + if (fit === undefined) { fit = true; } + + width = this.getNewWidth(width); + height = this.getNewHeight(height); + + var snap = this.snapTo; + var newRatio = (height === 0) ? 1 : width / height; + + if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) + { + // We need to change the height to fit the width + + width = SnapFloor(width, snap.x); + + height = width / this.aspectRatio; + + if (snap.y > 0) + { + height = SnapFloor(height, snap.y); + + // Reduce the width accordingly + width = height * this.aspectRatio; + } + } + else if ((fit && this.aspectRatio < newRatio) || (!fit && this.aspectRatio > newRatio)) + { + // We need to change the width to fit the height + + height = SnapFloor(height, snap.y); + + width = height * this.aspectRatio; + + if (snap.x > 0) + { + width = SnapFloor(width, snap.x); + + // Reduce the height accordingly + height = width * (1 / this.aspectRatio); + } + } + + this._width = width; + this._height = height; + + return this; + }, + + /** + * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. + * + * There may be some space inside the target area which is not covered if its aspect ratio differs. + * + * If this Size component has a parent set, then the width and height passed to this method will be clamped so + * it cannot exceed that of the parent. + * + * @method Phaser.Structs.Size#fitTo + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * + * @return {this} This Size component instance. + */ + fitTo: function (width, height) + { + return this.constrain(width, height, true); + }, + + /** + * The current `width` and `height` are adjusted so that they fully envelope the given dimensions, while keeping the aspect ratio. + * + * The size may extend further out than the target area if the aspect ratios differ. + * + * If this Size component has a parent set, then the values are clamped so that it never exceeds the parent + * on the longest axis. + * + * @method Phaser.Structs.Size#envelop + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * + * @return {this} This Size component instance. + */ + envelop: function (width, height) + { + return this.constrain(width, height, false); + }, + + /** + * Sets the width of this Size component. + * + * Depending on the aspect mode, changing the width may also update the height and aspect ratio. + * + * @method Phaser.Structs.Size#setWidth + * @since 3.16.0 + * + * @param {number} width - The new width of the Size component. + * + * @return {this} This Size component instance. + */ + setWidth: function (value) + { + return this.setSize(value, this._height); + }, + + /** + * Sets the height of this Size component. + * + * Depending on the aspect mode, changing the height may also update the width and aspect ratio. + * + * @method Phaser.Structs.Size#setHeight + * @since 3.16.0 + * + * @param {number} height - The new height of the Size component. + * + * @return {this} This Size component instance. + */ + setHeight: function (value) + { + return this.setSize(this._width, value); + }, + + /** + * Returns a string representation of this Size component. + * + * @method Phaser.Structs.Size#toString + * @since 3.16.0 + * + * @return {string} A string representation of this Size component. + */ + toString: function () + { + return '[{ Size (width=' + this._width + ' height=' + this._height + ' aspectRatio=' + this.aspectRatio + ' aspectMode=' + this.aspectMode + ') }]'; + }, + + /** + * Sets the values of this Size component to the `element.style.width` and `height` + * properties of the given DOM Element. The properties are set as `px` values. + * + * @method Phaser.Structs.Size#setCSS + * @since 3.17.0 + * + * @param {HTMLElement} element - The DOM Element to set the CSS style on. + */ + setCSS: function (element) + { + if (element && element.style) + { + element.style.width = this._width + 'px'; + element.style.height = this._height + 'px'; + } + }, + + /** + * Copies the aspect mode, aspect ratio, width and height from this Size component + * to the given Size component. Note that the parent, if set, is not copied across. + * + * @method Phaser.Structs.Size#copy + * @since 3.16.0 + * + * @param {Phaser.Structs.Size} destination - The Size component to copy the values to. + * + * @return {Phaser.Structs.Size} The updated destination Size component. + */ + copy: function (destination) + { + destination.setAspectMode(this.aspectMode); + + destination.aspectRatio = this.aspectRatio; + + return destination.setSize(this.width, this.height); + }, + + /** + * Destroys this Size component. + * + * This clears the local properties and any parent object, if set. + * + * A destroyed Size component cannot be re-used. + * + * @method Phaser.Structs.Size#destroy + * @since 3.16.0 + */ + destroy: function () + { + this._parent = null; + this.snapTo = null; + }, + + /** + * The width of this Size component. + * + * This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled. + * + * A width can never be less than zero. + * + * Changing this value will automatically update the `height` if the aspect ratio lock is enabled. + * You can also use the `setWidth` and `getWidth` methods. + * + * @name Phaser.Structs.Size#width + * @type {number} + * @since 3.16.0 + */ + width: { + + get: function () + { + return this._width; + }, + + set: function (value) + { + this.setSize(value, this._height); + } + + }, + + /** + * The height of this Size component. + * + * This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled. + * + * A height can never be less than zero. + * + * Changing this value will automatically update the `width` if the aspect ratio lock is enabled. + * You can also use the `setHeight` and `getHeight` methods. + * + * @name Phaser.Structs.Size#height + * @type {number} + * @since 3.16.0 + */ + height: { + + get: function () + { + return this._height; + }, + + set: function (value) + { + this.setSize(this._width, value); + } + + } + +}); + +/** + * Do not make the size fit the aspect ratio. Change the ratio when the size changes. + * + * @name Phaser.Structs.Size.NONE + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.NONE = 0; + +/** + * The height is automatically adjusted based on the width. + * + * @name Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.WIDTH_CONTROLS_HEIGHT = 1; + +/** + * The width is automatically adjusted based on the height. + * + * @name Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.HEIGHT_CONTROLS_WIDTH = 2; + +/** + * The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. + * + * @name Phaser.Structs.Size.FIT + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.FIT = 3; + +/** + * The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. + * + * @name Phaser.Structs.Size.ENVELOP + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.ENVELOP = 4; + +module.exports = Size; + + +/***/ }), +/* 411 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(142); +var Events = __webpack_require__(21); +var GameEvents = __webpack_require__(22); +var GetValue = __webpack_require__(6); +var LoaderEvents = __webpack_require__(91); +var NOOP = __webpack_require__(1); +var Scene = __webpack_require__(412); +var Systems = __webpack_require__(201); + +/** + * @classdesc + * The Scene Manager. + * + * The Scene Manager is a Game level system, responsible for creating, processing and updating all of the + * Scenes in a Game instance. +ó * + * + * @class SceneManager + * @memberof Phaser.Scenes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance this Scene Manager belongs to. + * @param {object} sceneConfig - Scene specific configuration settings. + */ +var SceneManager = new Class({ + + initialize: + + function SceneManager (game, sceneConfig) + { + /** + * The Game that this SceneManager belongs to. + * + * @name Phaser.Scenes.SceneManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * An object that maps the keys to the scene so we can quickly get a scene from a key without iteration. + * + * @name Phaser.Scenes.SceneManager#keys + * @type {object} + * @since 3.0.0 + */ + this.keys = {}; + + /** + * The array in which all of the scenes are kept. + * + * @name Phaser.Scenes.SceneManager#scenes + * @type {array} + * @since 3.0.0 + */ + this.scenes = []; + + /** + * Scenes pending to be added are stored in here until the manager has time to add it. + * + * @name Phaser.Scenes.SceneManager#_pending + * @type {array} + * @private + * @since 3.0.0 + */ + this._pending = []; + + /** + * An array of scenes waiting to be started once the game has booted. + * + * @name Phaser.Scenes.SceneManager#_start + * @type {array} + * @private + * @since 3.0.0 + */ + this._start = []; + + /** + * An operations queue, because we don't manipulate the scenes array during processing. + * + * @name Phaser.Scenes.SceneManager#_queue + * @type {array} + * @private + * @since 3.0.0 + */ + this._queue = []; + + /** + * Boot time data to merge. + * + * @name Phaser.Scenes.SceneManager#_data + * @type {object} + * @private + * @since 3.4.0 + */ + this._data = {}; + + /** + * Is the Scene Manager actively processing the Scenes list? + * + * @name Phaser.Scenes.SceneManager#isProcessing + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isProcessing = false; + + /** + * Has the Scene Manager properly started? + * + * @name Phaser.Scenes.SceneManager#isBooted + * @type {boolean} + * @default false + * @readonly + * @since 3.4.0 + */ + this.isBooted = false; + + /** + * Do any of the Cameras in any of the Scenes require a custom viewport? + * If not we can skip scissor tests. + * + * @name Phaser.Scenes.SceneManager#customViewports + * @type {number} + * @default 0 + * @since 3.12.0 + */ + this.customViewports = 0; + + if (sceneConfig) + { + if (!Array.isArray(sceneConfig)) + { + sceneConfig = [ sceneConfig ]; + } + + for (var i = 0; i < sceneConfig.length; i++) + { + // The i === 0 part just autostarts the first Scene given (unless it says otherwise in its config) + this._pending.push({ + key: 'default', + scene: sceneConfig[i], + autoStart: (i === 0), + data: {} + }); + } + } + + game.events.once(GameEvents.READY, this.bootQueue, this); + }, + + /** + * Internal first-time Scene boot handler. + * + * @method Phaser.Scenes.SceneManager#bootQueue + * @private + * @since 3.2.0 + */ + bootQueue: function () + { + if (this.isBooted) + { + return; + } + + var i; + var entry; + var key; + var sceneConfig; + + for (i = 0; i < this._pending.length; i++) + { + entry = this._pending[i]; + + key = entry.key; + sceneConfig = entry.scene; + + var newScene; + + if (sceneConfig instanceof Scene) + { + newScene = this.createSceneFromInstance(key, sceneConfig); + } + else if (typeof sceneConfig === 'object') + { + newScene = this.createSceneFromObject(key, sceneConfig); + } + else if (typeof sceneConfig === 'function') + { + newScene = this.createSceneFromFunction(key, sceneConfig); + } + + // Replace key in case the scene changed it + key = newScene.sys.settings.key; + + this.keys[key] = newScene; + + this.scenes.push(newScene); + + // Any data to inject? + if (this._data[key]) + { + newScene.sys.settings.data = this._data[key].data; + + if (this._data[key].autoStart) + { + entry.autoStart = true; + } + } + + if (entry.autoStart || newScene.sys.settings.active) + { + this._start.push(key); + } + } + + // Clear the pending lists + this._pending.length = 0; + + this._data = {}; + + this.isBooted = true; + + // _start might have been populated by the above + for (i = 0; i < this._start.length; i++) + { + entry = this._start[i]; + + this.start(entry); + } + + this._start.length = 0; + }, + + /** + * Process the Scene operations queue. + * + * @method Phaser.Scenes.SceneManager#processQueue + * @since 3.0.0 + */ + processQueue: function () + { + var pendingLength = this._pending.length; + var queueLength = this._queue.length; + + if (pendingLength === 0 && queueLength === 0) + { + return; + } + + var i; + var entry; + + if (pendingLength) + { + for (i = 0; i < pendingLength; i++) + { + entry = this._pending[i]; + + this.add(entry.key, entry.scene, entry.autoStart, entry.data); + } + + // _start might have been populated by this.add + for (i = 0; i < this._start.length; i++) + { + entry = this._start[i]; + + this.start(entry); + } + + // Clear the pending lists + this._start.length = 0; + this._pending.length = 0; + + return; + } + + for (i = 0; i < this._queue.length; i++) + { + entry = this._queue[i]; + + this[entry.op](entry.keyA, entry.keyB); + } + + this._queue.length = 0; + }, + + /** + * Adds a new Scene into the SceneManager. + * You must give each Scene a unique key by which you'll identify it. + * + * The `sceneConfig` can be: + * + * * A `Phaser.Scene` object, or an object that extends it. + * * A plain JavaScript object + * * A JavaScript ES6 Class that extends `Phaser.Scene` + * * A JavaScript ES5 prototype based Class + * * A JavaScript function + * + * If a function is given then a new Scene will be created by calling it. + * + * @method Phaser.Scenes.SceneManager#add + * @since 3.0.0 + * + * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. + * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig|function)} sceneConfig - The config for the Scene + * @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added. + * @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. + * + * @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`. + */ + add: function (key, sceneConfig, autoStart, data) + { + if (autoStart === undefined) { autoStart = false; } + if (data === undefined) { data = {}; } + + // If processing or not booted then put scene into a holding pattern + if (this.isProcessing || !this.isBooted) + { + this._pending.push({ + key: key, + scene: sceneConfig, + autoStart: autoStart, + data: data + }); + + if (!this.isBooted) + { + this._data[key] = { data: data }; + } + + return null; + } + + key = this.getKey(key, sceneConfig); + + var newScene; + + if (sceneConfig instanceof Scene) + { + newScene = this.createSceneFromInstance(key, sceneConfig); + } + else if (typeof sceneConfig === 'object') + { + sceneConfig.key = key; + + newScene = this.createSceneFromObject(key, sceneConfig); + } + else if (typeof sceneConfig === 'function') + { + newScene = this.createSceneFromFunction(key, sceneConfig); + } + + // Any data to inject? + newScene.sys.settings.data = data; + + // Replace key in case the scene changed it + key = newScene.sys.settings.key; + + this.keys[key] = newScene; + + this.scenes.push(newScene); + + if (autoStart || newScene.sys.settings.active) + { + if (this._pending.length) + { + this._start.push(key); + } + else + { + this.start(key); + } + } + + return newScene; + }, + + /** + * Removes a Scene from the SceneManager. + * + * The Scene is removed from the local scenes array, it's key is cleared from the keys + * cache and Scene.Systems.destroy is then called on it. + * + * If the SceneManager is processing the Scenes when this method is called it will + * queue the operation for the next update sequence. + * + * @method Phaser.Scenes.SceneManager#remove + * @since 3.2.0 + * + * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + remove: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'remove', keyA: key, keyB: null }); + } + else + { + var sceneToRemove = this.getScene(key); + + if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) + { + return this; + } + + var index = this.scenes.indexOf(sceneToRemove); + var sceneKey = sceneToRemove.sys.settings.key; + + if (index > -1) + { + delete this.keys[sceneKey]; + this.scenes.splice(index, 1); + + if (this._start.indexOf(sceneKey) > -1) + { + index = this._start.indexOf(sceneKey); + this._start.splice(index, 1); + } + + sceneToRemove.sys.destroy(); + } + } + + return this; + }, + + /** + * Boot the given Scene. + * + * @method Phaser.Scenes.SceneManager#bootScene + * @private + * @fires Phaser.Scenes.Events#TRANSITION_INIT + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to boot. + */ + bootScene: function (scene) + { + var sys = scene.sys; + var settings = sys.settings; + + sys.sceneUpdate = NOOP; + + if (scene.init) + { + scene.init.call(scene, settings.data); + + settings.status = CONST.INIT; + + if (settings.isTransition) + { + sys.events.emit(Events.TRANSITION_INIT, settings.transitionFrom, settings.transitionDuration); + } + } + + var loader; + + if (sys.load) + { + loader = sys.load; + + loader.reset(); + } + + if (loader && scene.preload) + { + scene.preload.call(scene); + + // Is the loader empty? + if (loader.list.size === 0) + { + this.create(scene); + } + else + { + settings.status = CONST.LOADING; + + // Start the loader going as we have something in the queue + loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); + + loader.start(); + } + } + else + { + // No preload? Then there was nothing to load either + this.create(scene); + } + }, + + /** + * Handles load completion for a Scene's Loader. + * + * Starts the Scene that the Loader belongs to. + * + * @method Phaser.Scenes.SceneManager#loadComplete + * @private + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading. + */ + loadComplete: function (loader) + { + var scene = loader.scene; + + // TODO - Remove. This should *not* be handled here + // Try to unlock HTML5 sounds every time any loader completes + if (this.game.sound && this.game.sound.onBlurPausedSounds) + { + this.game.sound.unlock(); + } + + this.create(scene); + }, + + /** + * Handle payload completion for a Scene. + * + * @method Phaser.Scenes.SceneManager#payloadComplete + * @private + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading its Scene's payload. + */ + payloadComplete: function (loader) + { + this.bootScene(loader.scene); + }, + + /** + * Updates the Scenes. + * + * @method Phaser.Scenes.SceneManager#update + * @since 3.0.0 + * + * @param {number} time - Time elapsed. + * @param {number} delta - Delta time from the last update. + */ + update: function (time, delta) + { + this.processQueue(); + + this.isProcessing = true; + + // Loop through the active scenes in reverse order + for (var i = this.scenes.length - 1; i >= 0; i--) + { + var sys = this.scenes[i].sys; + + if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) + { + sys.step(time, delta); + } + } + }, + + /** + * Renders the Scenes. + * + * @method Phaser.Scenes.SceneManager#render + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer to use. + */ + render: function (renderer) + { + // Loop through the scenes in forward order + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) + { + sys.render(renderer); + } + } + + this.isProcessing = false; + }, + + /** + * Calls the given Scene's {@link Phaser.Scene#create} method and updates its status. + * + * @method Phaser.Scenes.SceneManager#create + * @private + * @fires Phaser.Scenes.Events#CREATE + * @fires Phaser.Scenes.Events#TRANSITION_INIT + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to create. + */ + create: function (scene) + { + var sys = scene.sys; + var settings = sys.settings; + + if (scene.create) + { + settings.status = CONST.CREATING; + + scene.create.call(scene, settings.data); + + if (settings.status === CONST.DESTROYED) + { + return; + } + } + + if (settings.isTransition) + { + sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration); + } + + // If the Scene has an update function we'll set it now, otherwise it'll remain as NOOP + if (scene.update) + { + sys.sceneUpdate = scene.update; + } + + settings.status = CONST.RUNNING; + + sys.events.emit(Events.CREATE, scene); + }, + + /** + * Creates and initializes a Scene from a function. + * + * @method Phaser.Scenes.SceneManager#createSceneFromFunction + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {function} scene - The function to create the Scene from. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromFunction: function (key, scene) + { + var newScene = new scene(); + + if (newScene instanceof Scene) + { + var configKey = newScene.sys.settings.key; + + if (configKey !== '') + { + key = configKey; + } + + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } + + return this.createSceneFromInstance(key, newScene); + } + else + { + newScene.sys = new Systems(newScene); + + newScene.sys.settings.key = key; + + newScene.sys.init(this.game); + + return newScene; + } + }, + + /** + * Creates and initializes a Scene instance. + * + * @method Phaser.Scenes.SceneManager#createSceneFromInstance + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {Phaser.Scene} newScene - The Scene instance. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromInstance: function (key, newScene) + { + var configKey = newScene.sys.settings.key; + + if (configKey === '') + { + newScene.sys.settings.key = key; + } + + newScene.sys.init(this.game); + + return newScene; + }, + + /** + * Creates and initializes a Scene from an Object definition. + * + * @method Phaser.Scenes.SceneManager#createSceneFromObject + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {(string|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig)} sceneConfig - The Scene config. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromObject: function (key, sceneConfig) + { + var newScene = new Scene(sceneConfig); + + var configKey = newScene.sys.settings.key; + + if (configKey !== '') + { + key = configKey; + } + else + { + newScene.sys.settings.key = key; + } + + newScene.sys.init(this.game); + + // Extract callbacks + + var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; + + for (var i = 0; i < defaults.length; i++) + { + var sceneCallback = GetValue(sceneConfig, defaults[i], null); + + if (sceneCallback) + { + newScene[defaults[i]] = sceneCallback; + } + } + + // Now let's move across any other functions or properties that may exist in the extend object: + + /* + scene: { + preload: preload, + create: create, + extend: { + hello: 1, + test: 'atari', + addImage: addImage + } + } + */ + + if (sceneConfig.hasOwnProperty('extend')) + { + for (var propertyKey in sceneConfig.extend) + { + if (!sceneConfig.extend.hasOwnProperty(propertyKey)) + { + continue; + } + + var value = sceneConfig.extend[propertyKey]; + + if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') + { + // Populate the DataManager + newScene.data.merge(value); + } + else if (propertyKey !== 'sys') + { + newScene[propertyKey] = value; + } + } + } + + return newScene; + }, + + /** + * Retrieves the key of a Scene from a Scene config. + * + * @method Phaser.Scenes.SceneManager#getKey + * @private + * @since 3.0.0 + * + * @param {string} key - The key to check in the Scene config. + * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|function)} sceneConfig - The Scene config. + * + * @return {string} The Scene key. + */ + getKey: function (key, sceneConfig) + { + if (!key) { key = 'default'; } + + if (typeof sceneConfig === 'function') + { + return key; + } + else if (sceneConfig instanceof Scene) + { + key = sceneConfig.sys.settings.key; + } + else if (typeof sceneConfig === 'object' && sceneConfig.hasOwnProperty('key')) + { + key = sceneConfig.key; + } + + // By this point it's either 'default' or extracted from the Scene + + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } + else + { + return key; + } + }, + + /** + * Returns an array of all the current Scenes being managed by this Scene Manager. + * + * You can filter the output by the active state of the Scene and choose to have + * the array returned in normal or reversed order. + * + * @method Phaser.Scenes.SceneManager#getScenes + * @since 3.16.0 + * + * @param {boolean} [isActive=true] - Only include Scene's that are currently active? + * @param {boolean} [inReverse=false] - Return the array of Scenes in reverse? + * + * @return {Phaser.Scene[]} An array containing all of the Scenes in the Scene Manager. + */ + getScenes: function (isActive, inReverse) + { + if (isActive === undefined) { isActive = true; } + if (inReverse === undefined) { inReverse = false; } + + var out = []; + var scenes = this.scenes; + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene && (!isActive || (isActive && scene.sys.isActive()))) + { + out.push(scene); + } + } + + return (inReverse) ? out.reverse() : out; + }, + + /** + * Retrieves a Scene. + * + * @method Phaser.Scenes.SceneManager#getScene + * @since 3.0.0 + * + * @param {string|Phaser.Scene} key - The Scene to retrieve. + * + * @return {?Phaser.Scene} The Scene. + */ + getScene: function (key) + { + if (typeof key === 'string') + { + if (this.keys[key]) + { + return this.keys[key]; + } + } + else + { + for (var i = 0; i < this.scenes.length; i++) + { + if (key === this.scenes[i]) + { + return key; + } + } + } + + return null; + }, + + /** + * Determines whether a Scene is running. + * + * @method Phaser.Scenes.SceneManager#isActive + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is running. + */ + isActive: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isActive(); + } + + return null; + }, + + /** + * Determines whether a Scene is paused. + * + * @method Phaser.Scenes.SceneManager#isPaused + * @since 3.17.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is paused. + */ + isPaused: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isPaused(); + } + + return null; + }, + + /** + * Determines whether a Scene is visible. + * + * @method Phaser.Scenes.SceneManager#isVisible + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is visible. + */ + isVisible: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isVisible(); + } + + return null; + }, + + /** + * Determines whether a Scene is sleeping. + * + * @method Phaser.Scenes.SceneManager#isSleeping + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is sleeping. + */ + isSleeping: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isSleeping(); + } + + return null; + }, + + /** + * Pauses the given Scene. + * + * @method Phaser.Scenes.SceneManager#pause + * @since 3.0.0 + * + * @param {string} key - The Scene to pause. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its pause event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + pause: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.pause(data); + } + + return this; + }, + + /** + * Resumes the given Scene. + * + * @method Phaser.Scenes.SceneManager#resume + * @since 3.0.0 + * + * @param {string} key - The Scene to resume. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its resume event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + resume: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.resume(data); + } + + return this; + }, + + /** + * Puts the given Scene to sleep. + * + * @method Phaser.Scenes.SceneManager#sleep + * @since 3.0.0 + * + * @param {string} key - The Scene to put to sleep. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its sleep event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + sleep: function (key, data) + { + var scene = this.getScene(key); + + if (scene && !scene.sys.isTransitioning()) + { + scene.sys.sleep(data); + } + + return this; + }, + + /** + * Awakens the given Scene. + * + * @method Phaser.Scenes.SceneManager#wake + * @since 3.0.0 + * + * @param {string} key - The Scene to wake up. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its wake event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + wake: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.wake(data); + } + + return this; + }, + + /** + * Runs the given Scene. + * + * If the given Scene is paused, it will resume it. If sleeping, it will wake it. + * If not running at all, it will be started. + * + * Use this if you wish to open a modal Scene by calling `pause` on the current + * Scene, then `run` on the modal Scene. + * + * @method Phaser.Scenes.SceneManager#run + * @since 3.10.0 + * + * @param {string} key - The Scene to run. + * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. + * + * @return {Phaser.Scenes.SceneManager} This Scene Manager. + */ + run: function (key, data) + { + var scene = this.getScene(key); + + if (!scene) + { + for (var i = 0; i < this._pending.length; i++) + { + if (this._pending[i].key === key) + { + this.queueOp('start', key, data); + break; + } + } + return this; + } + + if (scene.sys.isSleeping()) + { + // Sleeping? + scene.sys.wake(data); + } + else if (scene.sys.isPaused()) + { + // Paused? + scene.sys.resume(data); + } + else + { + // Not actually running? + this.start(key, data); + } + }, + + /** + * Starts the given Scene. + * + * @method Phaser.Scenes.SceneManager#start + * @since 3.0.0 + * + * @param {string} key - The Scene to start. + * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + start: function (key, data) + { + // If the Scene Manager is not running, then put the Scene into a holding pattern + if (!this.isBooted) + { + this._data[key] = { + autoStart: true, + data: data + }; + + return this; + } + + var scene = this.getScene(key); + + if (scene) + { + var sys = scene.sys; + + // If the Scene is already running (perhaps they called start from a launched sub-Scene?) + // then we close it down before starting it again. + if (sys.isActive() || sys.isPaused()) + { + sys.shutdown(); + + sys.sceneUpdate = NOOP; + + sys.start(data); + } + else + { + sys.sceneUpdate = NOOP; + + sys.start(data); + + var loader; + + if (sys.load) + { + loader = sys.load; + } + + // Files payload? + if (loader && sys.settings.hasOwnProperty('pack')) + { + loader.reset(); + + if (loader.addPack({ payload: sys.settings.pack })) + { + sys.settings.status = CONST.LOADING; + + loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); + + loader.start(); + + return this; + } + } + } + + this.bootScene(scene); + } + + return this; + }, + + /** + * Stops the given Scene. + * + * @method Phaser.Scenes.SceneManager#stop + * @since 3.0.0 + * + * @param {string} key - The Scene to stop. + * @param {object} [data] - Optional data object to pass to Scene.shutdown. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + stop: function (key, data) + { + var scene = this.getScene(key); + + if (scene && !scene.sys.isTransitioning()) + { + scene.sys.shutdown(data); + } + + return this; + }, + + /** + * Sleeps one one Scene and starts the other. + * + * @method Phaser.Scenes.SceneManager#switch + * @since 3.0.0 + * + * @param {string} from - The Scene to sleep. + * @param {string} to - The Scene to start. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + switch: function (from, to) + { + var sceneA = this.getScene(from); + var sceneB = this.getScene(to); + + if (sceneA && sceneB && sceneA !== sceneB) + { + this.sleep(from); + + if (this.isSleeping(to)) + { + this.wake(to); + } + else + { + this.start(to); + } + } + + return this; + }, + + /** + * Retrieves a Scene by numeric index. + * + * @method Phaser.Scenes.SceneManager#getAt + * @since 3.0.0 + * + * @param {number} index - The index of the Scene to retrieve. + * + * @return {(Phaser.Scene|undefined)} The Scene. + */ + getAt: function (index) + { + return this.scenes[index]; + }, + + /** + * Retrieves the numeric index of a Scene. + * + * @method Phaser.Scenes.SceneManager#getIndex + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The key of the Scene. + * + * @return {number} The index of the Scene. + */ + getIndex: function (key) + { + var scene = this.getScene(key); + + return this.scenes.indexOf(scene); + }, + + /** + * Brings a Scene to the top of the Scenes list. + * + * This means it will render above all other Scenes. + * + * @method Phaser.Scenes.SceneManager#bringToTop + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + bringToTop: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'bringToTop', keyA: key, keyB: null }); + } + else + { + var index = this.getIndex(key); + + if (index !== -1 && index < this.scenes.length) + { + var scene = this.getScene(key); + + this.scenes.splice(index, 1); + this.scenes.push(scene); + } + } + + return this; + }, + + /** + * Sends a Scene to the back of the Scenes list. + * + * This means it will render below all other Scenes. + * + * @method Phaser.Scenes.SceneManager#sendToBack + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + sendToBack: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); + } + else + { + var index = this.getIndex(key); + + if (index !== -1 && index > 0) + { + var scene = this.getScene(key); + + this.scenes.splice(index, 1); + this.scenes.unshift(scene); + } + } + + return this; + }, + + /** + * Moves a Scene down one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveDown + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveDown: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'moveDown', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); + + if (indexA > 0) + { + var indexB = indexA - 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); + + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } + + return this; + }, + + /** + * Moves a Scene up one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveUp + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveUp: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); + + if (indexA < this.scenes.length - 1) + { + var indexB = indexA + 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); + + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } + + return this; + }, + + /** + * Moves a Scene so it is immediately above another Scene in the Scenes list. + * + * This means it will render over the top of the other Scene. + * + * @method Phaser.Scenes.SceneManager#moveAbove + * @since 3.2.0 + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. + * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveAbove: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexB); + + // Remove + this.scenes.splice(indexB, 1); + + // Add in new location + this.scenes.splice(indexA + 1, 0, tempScene); + } + } + + return this; + }, + + /** + * Moves a Scene so it is immediately below another Scene in the Scenes list. + * + * This means it will render behind the other Scene. + * + * @method Phaser.Scenes.SceneManager#moveBelow + * @since 3.2.0 + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. + * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveBelow: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'moveBelow', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexB); + + // Remove + this.scenes.splice(indexB, 1); + + if (indexA === 0) + { + this.scenes.unshift(tempScene); + } + else + { + // Add in new location + this.scenes.splice(indexA, 0, tempScene); + } + } + } + + return this; + }, + + /** + * Queue a Scene operation for the next update. + * + * @method Phaser.Scenes.SceneManager#queueOp + * @private + * @since 3.0.0 + * + * @param {string} op - The operation to perform. + * @param {(string|Phaser.Scene)} keyA - Scene A. + * @param {(any|string|Phaser.Scene)} [keyB] - Scene B, or a data object. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + queueOp: function (op, keyA, keyB) + { + this._queue.push({ op: op, keyA: keyA, keyB: keyB }); + + return this; + }, + + /** + * Swaps the positions of two Scenes in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#swapPosition + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. + * @param {(string|Phaser.Scene)} keyB - The second Scene to swap. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + swapPosition: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'swapPosition', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== indexB && indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexA); + + this.scenes[indexA] = this.scenes[indexB]; + this.scenes[indexB] = tempScene; + } + } + + return this; + }, + + /** + * Dumps debug information about each Scene to the developer console. + * + * @method Phaser.Scenes.SceneManager#dump + * @since 3.2.0 + */ + dump: function () + { + var out = []; + var map = [ 'pending', 'init', 'start', 'loading', 'creating', 'running', 'paused', 'sleeping', 'shutdown', 'destroyed' ]; + + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + var key = (sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED)) ? '[*] ' : '[-] '; + key += sys.settings.key + ' (' + map[sys.settings.status] + ')'; + + out.push(key); + } + + console.log(out.join('\n')); + }, + + /** + * Destroy the SceneManager and all of its Scene's systems. + * + * @method Phaser.Scenes.SceneManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + sys.destroy(); + } + + this.update = NOOP; + + this.scenes = []; + + this._pending = []; + this._start = []; + this._queue = []; + + this.game = null; + } + +}); + +module.exports = SceneManager; + + +/***/ }), +/* 412 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Systems = __webpack_require__(201); + +/** + * @classdesc + * A base Phaser.Scene class which can be extended for your own use. + * + * You can also define the optional methods {@link Phaser.Types.Scenes.SceneInitCallback init()}, {@link Phaser.Types.Scenes.ScenePreloadCallback preload()}, and {@link Phaser.Types.Scenes.SceneCreateCallback create()}. + * + * @class Scene + * @memberof Phaser + * @constructor + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. + */ +var Scene = new Class({ + + initialize: + + function Scene (config) + { + /** + * The Scene Systems. You must never overwrite this property, or all hell will break lose. + * + * @name Phaser.Scene#sys + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.sys = new Systems(this, config); + + /** + * A reference to the Phaser.Game instance. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game; + + /** + * A reference to the global Animation Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#anims + * @type {Phaser.Animations.AnimationManager} + * @since 3.0.0 + */ + this.anims; + + /** + * A reference to the global Cache. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#cache + * @type {Phaser.Cache.CacheManager} + * @since 3.0.0 + */ + this.cache; + + /** + * A reference to the game level Data Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#registry + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.registry; + + /** + * A reference to the Sound Manager. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#sound + * @type {Phaser.Sound.BaseSoundManager} + * @since 3.0.0 + */ + this.sound; + + /** + * A reference to the Texture Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#textures + * @type {Phaser.Textures.TextureManager} + * @since 3.0.0 + */ + this.textures; + + /** + * A scene level Event Emitter. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events; + + /** + * A scene level Camera System. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#cameras + * @type {Phaser.Cameras.Scene2D.CameraManager} + * @since 3.0.0 + */ + this.cameras; + + /** + * A scene level Game Object Factory. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#add + * @type {Phaser.GameObjects.GameObjectFactory} + * @since 3.0.0 + */ + this.add; + + /** + * A scene level Game Object Creator. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#make + * @type {Phaser.GameObjects.GameObjectCreator} + * @since 3.0.0 + */ + this.make; + + /** + * A reference to the Scene Manager Plugin. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#scene + * @type {Phaser.Scenes.ScenePlugin} + * @since 3.0.0 + */ + this.scene; + + /** + * A scene level Game Object Display List. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#children + * @type {Phaser.GameObjects.DisplayList} + * @since 3.0.0 + */ + this.children; + + /** + * A scene level Lights Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#lights + * @type {Phaser.GameObjects.LightsManager} + * @since 3.0.0 + */ + this.lights; + + /** + * A scene level Data Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#data + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.data; + + /** + * A scene level Input Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#input + * @type {Phaser.Input.InputPlugin} + * @since 3.0.0 + */ + this.input; + + /** + * A scene level Loader Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#load + * @type {Phaser.Loader.LoaderPlugin} + * @since 3.0.0 + */ + this.load; + + /** + * A scene level Time and Clock Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#time + * @type {Phaser.Time.Clock} + * @since 3.0.0 + */ + this.time; + + /** + * A scene level Tween Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#tweens + * @type {Phaser.Tweens.TweenManager} + * @since 3.0.0 + */ + this.tweens; + + /** + * A scene level Arcade Physics Plugin. + * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. + * + * @name Phaser.Scene#physics + * @type {Phaser.Physics.Arcade.ArcadePhysics} + * @since 3.0.0 + */ + this.physics; + + /** + * A scene level Matter Physics Plugin. + * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. + * + * @name Phaser.Scene#matter + * @type {Phaser.Physics.Matter.MatterPhysics} + * @since 3.0.0 + */ + this.matter; + + if (false) + {} + + /** + * A reference to the global Scale Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#scale + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.2 + */ + this.scale; + + /** + * A reference to the Plugin Manager. + * + * The Plugin Manager is a global system that allows plugins to register themselves with it, and can then install + * those plugins into Scenes as required. + * + * @name Phaser.Scene#plugins + * @type {Phaser.Plugins.PluginManager} + * @since 3.0.0 + */ + this.plugins; + + /** + * A reference to the renderer instance Phaser is using, either Canvas or WebGL. + * + * @name Phaser.Scene#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.50.0 + */ + this.renderer; + }, + + /** + * Should be overridden by your own Scenes. + * This method is called once per game step while the scene is running. + * + * @method Phaser.Scene#update + * @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. + */ + update: function () + { + } + +}); + +module.exports = Scene; + + +/***/ }), +/* 413 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var UppercaseFirst = __webpack_require__(202); + +/** + * Builds an array of which physics plugins should be activated for the given Scene. + * + * @function Phaser.Scenes.GetPhysicsPlugins + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - The scene system to get the physics systems of. + * + * @return {array} An array of Physics systems to start for this Scene. + */ +var GetPhysicsPlugins = function (sys) +{ + var defaultSystem = sys.game.config.defaultPhysicsSystem; + var sceneSystems = GetFastValue(sys.settings, 'physics', false); + + if (!defaultSystem && !sceneSystems) + { + // No default physics system or systems in this scene + return; + } + + // Let's build the systems array + var output = []; + + if (defaultSystem) + { + output.push(UppercaseFirst(defaultSystem + 'Physics')); + } + + if (sceneSystems) + { + for (var key in sceneSystems) + { + key = UppercaseFirst(key.concat('Physics')); + + if (output.indexOf(key) === -1) + { + output.push(key); + } + } + } + + // An array of Physics systems to start for this Scene + return output; +}; + +module.exports = GetPhysicsPlugins; + + +/***/ }), +/* 414 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); + +/** + * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. + * + * @function Phaser.Scenes.GetScenePlugins + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems object to check for plugins. + * + * @return {array} An array of all plugins which should be activated, either the default ones or the ones configured in the Scene Systems object. + */ +var GetScenePlugins = function (sys) +{ + var defaultPlugins = sys.plugins.getDefaultScenePlugins(); + + var scenePlugins = GetFastValue(sys.settings, 'plugins', false); + + // Scene Plugins always override Default Plugins + if (Array.isArray(scenePlugins)) + { + return scenePlugins; + } + else if (defaultPlugins) + { + return defaultPlugins; + } + else + { + // No default plugins or plugins in this scene + return []; + } +}; + +module.exports = GetScenePlugins; + + +/***/ }), +/* 415 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(142); +var GetValue = __webpack_require__(6); +var Merge = __webpack_require__(143); +var InjectionMap = __webpack_require__(974); + +/** + * @namespace Phaser.Scenes.Settings + */ + +var Settings = { + + /** + * Takes a Scene configuration object and returns a fully formed System Settings object. + * + * @function Phaser.Scenes.Settings.create + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - The Scene configuration object used to create this Scene Settings. + * + * @return {Phaser.Types.Scenes.SettingsObject} The Scene Settings object created as a result of the config and default settings. + */ + create: function (config) + { + if (typeof config === 'string') + { + config = { key: config }; + } + else if (config === undefined) + { + // Pass the 'hasOwnProperty' checks + config = {}; + } + + return { + + status: CONST.PENDING, + + key: GetValue(config, 'key', ''), + active: GetValue(config, 'active', false), + visible: GetValue(config, 'visible', true), + + isBooted: false, + + isTransition: false, + transitionFrom: null, + transitionDuration: 0, + transitionAllowInput: true, + + // Loader payload array + + data: {}, + + pack: GetValue(config, 'pack', false), + + // Cameras + + cameras: GetValue(config, 'cameras', null), + + // Scene Property Injection Map + + map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), + + // Physics + + physics: GetValue(config, 'physics', {}), + + // Loader + + loader: GetValue(config, 'loader', {}), + + // Plugins + + plugins: GetValue(config, 'plugins', false), + + // Input + + input: GetValue(config, 'input', {}) + + }; + } + +}; + +module.exports = Settings; + + +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); +var CanvasTexture = __webpack_require__(417); +var Class = __webpack_require__(0); +var Color = __webpack_require__(36); +var CONST = __webpack_require__(39); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(103); +var GameEvents = __webpack_require__(22); +var GenerateTexture = __webpack_require__(382); +var GetValue = __webpack_require__(6); +var Parser = __webpack_require__(419); +var Texture = __webpack_require__(203); + +/** + * @callback EachTextureCallback + * + * @param {Phaser.Textures.Texture} texture - Each texture in Texture Manager. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ + +/** + * @classdesc + * Textures are managed by the global TextureManager. This is a singleton class that is + * responsible for creating and delivering Textures and their corresponding Frames to Game Objects. + * + * Sprites and other Game Objects get the texture data they need from the TextureManager. + * + * Access it via `scene.textures`. + * + * @class TextureManager + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Textures + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. + */ +var TextureManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function TextureManager (game) + { + EventEmitter.call(this); + + /** + * The Game that this TextureManager belongs to. + * + * @name Phaser.Textures.TextureManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * The name of this manager. + * + * @name Phaser.Textures.TextureManager#name + * @type {string} + * @since 3.0.0 + */ + this.name = 'TextureManager'; + + /** + * An object that has all of textures that Texture Manager creates. + * Textures are assigned to keys so we can access to any texture that this object has directly by key value without iteration. + * + * @name Phaser.Textures.TextureManager#list + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.list = {}; + + /** + * The temporary canvas element to save an pixel data of an arbitrary texture in getPixel() and getPixelAlpha() method. + * + * @name Phaser.Textures.TextureManager#_tempCanvas + * @type {HTMLCanvasElement} + * @private + * @since 3.0.0 + */ + this._tempCanvas = CanvasPool.create2D(this, 1, 1); + + /** + * The context of the temporary canvas element made to save an pixel data in getPixel() and getPixelAlpha() method. + * + * @name Phaser.Textures.TextureManager#_tempContext + * @type {CanvasRenderingContext2D} + * @private + * @since 3.0.0 + */ + this._tempContext = this._tempCanvas.getContext('2d'); + + /** + * An counting value used for emitting 'ready' event after all of managers in game is loaded. + * + * @name Phaser.Textures.TextureManager#_pending + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._pending = 0; + + game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot Handler called by Phaser.Game when it first starts up. + * + * @method Phaser.Textures.TextureManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + this.on(Events.LOAD, this.updatePending, this); + this.on(Events.ERROR, this.updatePending, this); + + var config = this.game.config; + + this.addBase64('__DEFAULT', config.defaultImage); + this.addBase64('__MISSING', config.missingImage); + this.addBase64('__WHITE', config.whiteImage); + + this._pending = 3; + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * After 'onload' or 'onerror' invoked twice, emit 'ready' event. + * + * @method Phaser.Textures.TextureManager#updatePending + * @private + * @since 3.0.0 + */ + updatePending: function () + { + this._pending--; + + if (this._pending === 0) + { + this.off(Events.LOAD); + this.off(Events.ERROR); + + this.emit(Events.READY); + } + }, + + /** + * Checks the given texture key and throws a console.warn if the key is already in use, then returns false. + * If you wish to avoid the console.warn then use `TextureManager.exists` instead. + * + * @method Phaser.Textures.TextureManager#checkKey + * @since 3.7.0 + * + * @param {string} key - The texture key to check. + * + * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. + */ + checkKey: function (key) + { + if (this.exists(key)) + { + // eslint-disable-next-line no-console + console.error('Texture key already in use: ' + key); + + return false; + } + + return true; + }, + + /** + * Removes a Texture from the Texture Manager and destroys it. This will immediately + * clear all references to it from the Texture Manager, and if it has one, destroy its + * WebGLTexture. This will emit a `removetexture` event. + * + * Note: If you have any Game Objects still using this texture they will start throwing + * errors the next time they try to render. Make sure that removing the texture is the final + * step when clearing down to avoid this. + * + * @method Phaser.Textures.TextureManager#remove + * @fires Phaser.Textures.Events#REMOVE + * @since 3.7.0 + * + * @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it. + * + * @return {Phaser.Textures.TextureManager} The Texture Manager. + */ + remove: function (key) + { + if (typeof key === 'string') + { + if (this.exists(key)) + { + key = this.get(key); + } + else + { + console.warn('No texture found matching key: ' + key); + return this; + } + } + + // By this point key should be a Texture, if not, the following fails anyway + if (this.list.hasOwnProperty(key.key)) + { + key.destroy(); + + this.emit(Events.REMOVE, key.key); + } + + return this; + }, + + /** + * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. + * + * @method Phaser.Textures.TextureManager#removeKey + * @since 3.17.0 + * + * @param {string} key - The key to remove from the texture list. + * + * @return {Phaser.Textures.TextureManager} The Texture Manager. + */ + removeKey: function (key) + { + if (this.list.hasOwnProperty(key)) + { + delete this.list[key]; + } + + return this; + }, + + /** + * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. + * + * It works by creating an `Image` DOM object, then setting the `src` attribute to + * the given base64 encoded data. As a result, the process is asynchronous by its nature, + * so be sure to listen for the events this method dispatches before using the texture. + * + * @method Phaser.Textures.TextureManager#addBase64 + * @fires Phaser.Textures.Events#ADD + * @fires Phaser.Textures.Events#ERROR + * @fires Phaser.Textures.Events#LOAD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {*} data - The Base64 encoded data. + * + * @return {this} This Texture Manager instance. + */ + addBase64: function (key, data) + { + if (this.checkKey(key)) + { + var _this = this; + + var image = new Image(); + + image.onerror = function () + { + _this.emit(Events.ERROR, key); + }; + + image.onload = function () + { + var texture = _this.create(key, image); + + Parser.Image(texture, 0); + + _this.emit(Events.ADD, key, texture); + + _this.emit(Events.LOAD, key, texture); + }; + + image.src = data; + } + + return this; + }, + + /** + * Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data. + * + * You can also provide the image type and encoder options. + * + * This will only work with bitmap based texture frames, such as those created from Texture Atlases. + * It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please + * see the WebGL Snapshot function instead. + * + * @method Phaser.Textures.TextureManager#getBase64 + * @since 3.12.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png. + * @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored. + * + * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. + */ + getBase64: function (key, frame, type, encoderOptions) + { + if (type === undefined) { type = 'image/png'; } + if (encoderOptions === undefined) { encoderOptions = 0.92; } + + var data = ''; + + var textureFrame = this.getFrame(key, frame); + + if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) + { + console.warn('Cannot getBase64 from WebGL Texture'); + } + else if (textureFrame) + { + var cd = textureFrame.canvasData; + + var canvas = CanvasPool.create2D(this, cd.width, cd.height); + var ctx = canvas.getContext('2d'); + + ctx.drawImage( + textureFrame.source.image, + cd.x, + cd.y, + cd.width, + cd.height, + 0, + 0, + cd.width, + cd.height + ); + + data = canvas.toDataURL(type, encoderOptions); + + CanvasPool.remove(canvas); + } + + return data; + }, + + /** + * Adds a new Texture to the Texture Manager created from the given Image element. + * + * @method Phaser.Textures.TextureManager#addImage + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addImage: function (key, source, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.Image(texture, 0); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Takes a WebGL Texture and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. + * + * This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites. + * + * If the `width` and `height` arguments are omitted, but the WebGL Texture was created by Phaser's WebGL Renderer + * and has `glTexture.width` and `glTexture.height` properties, these values will be used instead. + * + * This is a WebGL only feature. + * + * @method Phaser.Textures.TextureManager#addGLTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.19.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {WebGLTexture} glTexture - The source Render Texture. + * @param {number} [width] - The new width of the Texture. Read from `glTexture.width` if omitted. + * @param {number} [height] - The new height of the Texture. Read from `glTexture.height` if omitted. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addGLTexture: function (key, glTexture, width, height) + { + var texture = null; + + if (this.checkKey(key)) + { + if (width === undefined) { width = glTexture.width; } + if (height === undefined) { height = glTexture.height; } + + texture = this.create(key, glTexture, width, height); + + texture.add('__BASE', 0, 0, 0, width, height); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Render Texture to the Texture Manager using the given key. + * This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites. + * + * @method Phaser.Textures.TextureManager#addRenderTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.12.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addRenderTexture: function (key, renderTexture) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, renderTexture); + + texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Creates a new Texture using the given config values. + * + * Generated textures consist of a Canvas element to which the texture data is drawn. + * + * Generates a texture based on the given Create configuration object. + * + * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the + * data cells map to a single color. For example, if the texture config looked like this: + * + * ```javascript + * var star = [ + * '.....828.....', + * '....72227....', + * '....82228....', + * '...7222227...', + * '2222222222222', + * '8222222222228', + * '.72222222227.', + * '..787777787..', + * '..877777778..', + * '.78778887787.', + * '.27887.78872.', + * '.787.....787.' + * ]; + * + * this.textures.generate('star', { data: star, pixelWidth: 4 }); + * ``` + * + * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array + * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color + * number 8 in the palette. If a cell contains a period character `.` then it is transparent. + * + * The default palette is Arne16, but you can specify your own using the `palette` property. + * + * @method Phaser.Textures.TextureManager#generate + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.Types.Create.GenerateTextureConfig} config - The configuration object needed to generate the texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + generate: function (key, config) + { + if (this.checkKey(key)) + { + var canvas = CanvasPool.create(this, 1, 1); + + config.canvas = canvas; + + GenerateTexture(config); + + return this.addCanvas(key, canvas); + } + else + { + return null; + } + }, + + /** + * Creates a new Texture using a blank Canvas element of the size given. + * + * Canvas elements are automatically pooled and calling this method will + * extract a free canvas from the CanvasPool, or create one if none are available. + * + * @method Phaser.Textures.TextureManager#createCanvas + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {number} [width=256] - The width of the Canvas element. + * @param {number} [height=256] - The height of the Canvas element. + * + * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. + */ + createCanvas: function (key, width, height) + { + if (width === undefined) { width = 256; } + if (height === undefined) { height = 256; } + + if (this.checkKey(key)) + { + var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); + + return this.addCanvas(key, canvas); + } + + return null; + }, + + /** + * Creates a new Canvas Texture object from an existing Canvas element + * and adds it to this Texture Manager, unless `skipCache` is true. + * + * @method Phaser.Textures.TextureManager#addCanvas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture. + * @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache? + * + * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. + */ + addCanvas: function (key, source, skipCache) + { + if (skipCache === undefined) { skipCache = false; } + + var texture = null; + + if (skipCache) + { + texture = new CanvasTexture(this, key, source, source.width, source.height); + } + else if (this.checkKey(key)) + { + texture = new CanvasTexture(this, key, source, source.width, source.height); + + this.list[key] = texture; + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a new Texture Atlas to this Texture Manager. + * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. + * + * @method Phaser.Textures.TextureManager#addAtlas + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlas: function (key, source, data, dataSource) + { + // New Texture Packer format? + if (Array.isArray(data.textures) || Array.isArray(data.frames)) + { + return this.addAtlasJSONArray(key, source, data, dataSource); + } + else + { + return this.addAtlasJSONHash(key, source, data, dataSource); + } + }, + + /** + * Adds a Texture Atlas to this Texture Manager. + * The frame data of the atlas must be stored in an Array within the JSON. + * This is known as a JSON Array in software such as Texture Packer. + * + * @method Phaser.Textures.TextureManager#addAtlasJSONArray + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|HTMLImageElement[])} source - The source Image element/s. + * @param {(object|object[])} data - The Texture Atlas data/s. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasJSONArray: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + // Multi-Atlas? + if (Array.isArray(data)) + { + var singleAtlasFile = (data.length === 1); // multi-pack with one atlas file for all images + + // !! Assumes the textures are in the same order in the source array as in the json data !! + for (var i = 0; i < texture.source.length; i++) + { + var atlasData = singleAtlasFile ? data[0] : data[i]; + + Parser.JSONArray(texture, i, atlasData); + } + } + else + { + Parser.JSONArray(texture, 0, data); + } + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Texture Atlas to this Texture Manager. + * The frame data of the atlas must be stored in an Object within the JSON. + * This is known as a JSON Hash in software such as Texture Packer. + * + * @method Phaser.Textures.TextureManager#addAtlasJSONHash + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasJSONHash: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + if (Array.isArray(data)) + { + for (var i = 0; i < data.length; i++) + { + Parser.JSONHash(texture, i, data[i]); + } + } + else + { + Parser.JSONHash(texture, 0, data); + } + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Texture Atlas to this Texture Manager, where the atlas data is given + * in the XML format. + * + * @method Phaser.Textures.TextureManager#addAtlasXML + * @fires Phaser.Textures.Events#ADD + * @since 3.7.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas XML data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasXML: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.AtlasXML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Unity Texture Atlas to this Texture Manager. + * The data must be in the form of a Unity YAML file. + * + * @method Phaser.Textures.TextureManager#addUnityAtlas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addUnityAtlas: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.UnityYAML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Sprite Sheet to this Texture Manager. + * + * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact + * same size and cannot be trimmed or rotated. + * + * @method Phaser.Textures.TextureManager#addSpriteSheet + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addSpriteSheet: function (key, source, config) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + var width = texture.source[0].width; + var height = texture.source[0].height; + + Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. + * + * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact + * same size and cannot be trimmed or rotated. + * + * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addSpriteSheetFromAtlas: function (key, config) + { + if (!this.checkKey(key)) + { + return null; + } + + var atlasKey = GetValue(config, 'atlas', null); + var atlasFrame = GetValue(config, 'frame', null); + + if (!atlasKey || !atlasFrame) + { + return; + } + + var atlas = this.get(atlasKey); + var sheet = atlas.get(atlasFrame); + + if (sheet) + { + var texture = this.create(key, sheet.source.image); + + if (sheet.trimmed) + { + // If trimmed we need to help the parser adjust + Parser.SpriteSheetFromAtlas(texture, sheet, config); + } + else + { + Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); + } + + this.emit(Events.ADD, key, texture); + + return texture; + } + }, + + /** + * Creates a new Texture using the given source and dimensions. + * + * @method Phaser.Textures.TextureManager#create + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {number} width - The width of the Texture. + * @param {number} height - The height of the Texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + create: function (key, source, width, height) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = new Texture(this, key, source, width, height); + + this.list[key] = texture; + } + + return texture; + }, + + /** + * Checks the given key to see if a Texture using it exists within this Texture Manager. + * + * @method Phaser.Textures.TextureManager#exists + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * + * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. + */ + exists: function (key) + { + return (this.list.hasOwnProperty(key)); + }, + + /** + * Returns a Texture from the Texture Manager that matches the given key. + * + * If the key is `undefined` it will return the `__DEFAULT` Texture. + * + * If the key is an instance of a Texture, it will return the key directly. + * + * Finally. if the key is given, but not found and not a Texture instance, it will return the `__MISSING` Texture. + * + * @method Phaser.Textures.TextureManager#get + * @since 3.0.0 + * + * @param {(string|Phaser.Textures.Texture)} key - The unique string-based key of the Texture, or a Texture instance. + * + * @return {Phaser.Textures.Texture} The Texture that was created. + */ + get: function (key) + { + if (key === undefined) { key = '__DEFAULT'; } + + if (this.list[key]) + { + return this.list[key]; + } + else if (key instanceof Texture) + { + return key; + } + else + { + return this.list['__MISSING']; + } + }, + + /** + * Takes a Texture key and Frame name and returns a clone of that Frame if found. + * + * @method Phaser.Textures.TextureManager#cloneFrame + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} frame - The string or index of the Frame to be cloned. + * + * @return {Phaser.Textures.Frame} A Clone of the given Frame. + */ + cloneFrame: function (key, frame) + { + if (this.list[key]) + { + return this.list[key].get(frame).clone(); + } + }, + + /** + * Takes a Texture key and Frame name and returns a reference to that Frame, if found. + * + * @method Phaser.Textures.TextureManager#getFrame + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * + * @return {Phaser.Textures.Frame} A Texture Frame object. + */ + getFrame: function (key, frame) + { + if (this.list[key]) + { + return this.list[key].get(frame); + } + }, + + /** + * Returns an array with all of the keys of all Textures in this Texture Manager. + * The output array will exclude the `__DEFAULT` and `__MISSING` keys. + * + * @method Phaser.Textures.TextureManager#getTextureKeys + * @since 3.0.0 + * + * @return {string[]} An array containing all of the Texture keys stored in this Texture Manager. + */ + getTextureKeys: function () + { + var output = []; + + for (var key in this.list) + { + if (key !== '__DEFAULT' && key !== '__MISSING') + { + output.push(key); + } + } + + return output; + }, + + /** + * Given a Texture and an `x` and `y` coordinate this method will return a new + * Color object that has been populated with the color and alpha values of the pixel + * at that location in the Texture. + * + * @method Phaser.Textures.TextureManager#getPixel + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the pixel within the Texture. + * @param {number} y - The y coordinate of the pixel within the Texture. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {?Phaser.Display.Color} A Color object populated with the color values of the requested pixel, + * or `null` if the coordinates were out of bounds. + */ + getPixel: function (x, y, key, frame) + { + var textureFrame = this.getFrame(key, frame); + + if (textureFrame) + { + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; + + var data = textureFrame.data.cut; + + x += data.x; + y += data.y; + + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; + + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); + + var rgb = ctx.getImageData(0, 0, 1, 1); + + return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); + } + } + + return null; + }, + + /** + * Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255 + * corresponding to the alpha value of the pixel at that location in the Texture. If the coordinate + * is out of bounds it will return null. + * + * @method Phaser.Textures.TextureManager#getPixelAlpha + * @since 3.10.0 + * + * @param {number} x - The x coordinate of the pixel within the Texture. + * @param {number} y - The y coordinate of the pixel within the Texture. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds. + */ + getPixelAlpha: function (x, y, key, frame) + { + var textureFrame = this.getFrame(key, frame); + + if (textureFrame) + { + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; + + var data = textureFrame.data.cut; + + x += data.x; + y += data.y; + + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; + + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); + + var rgb = ctx.getImageData(0, 0, 1, 1); + + return rgb.data[3]; + } + } + + return null; + }, + + /** + * Sets the given Game Objects `texture` and `frame` properties so that it uses + * the Texture and Frame specified in the `key` and `frame` arguments to this method. + * + * @method Phaser.Textures.TextureManager#setTexture + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the texture would be set on. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on. + */ + setTexture: function (gameObject, key, frame) + { + if (this.list[key]) + { + gameObject.texture = this.list[key]; + gameObject.frame = gameObject.texture.get(frame); + } + + return gameObject; + }, + + /** + * Changes the key being used by a Texture to the new key provided. + * + * The old key is removed, allowing it to be re-used. + * + * Game Objects are linked to Textures by a reference to the Texture object, so + * all existing references will be retained. + * + * @method Phaser.Textures.TextureManager#renameTexture + * @since 3.12.0 + * + * @param {string} currentKey - The current string-based key of the Texture you wish to rename. + * @param {string} newKey - The new unique string-based key to use for the Texture. + * + * @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`. + */ + renameTexture: function (currentKey, newKey) + { + var texture = this.get(currentKey); + + if (texture && currentKey !== newKey) + { + texture.key = newKey; + + this.list[newKey] = texture; + + delete this.list[currentKey]; + + return true; + } + + return false; + }, + + /** + * Passes all Textures to the given callback. + * + * @method Phaser.Textures.TextureManager#each + * @since 3.0.0 + * + * @param {EachTextureCallback} callback - The callback function to be sent the Textures. + * @param {object} scope - The value to use as `this` when executing the callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ + each: function (callback, scope) + { + var args = [ null ]; + + for (var i = 1; i < arguments.length; i++) + { + args.push(arguments[i]); + } + + for (var texture in this.list) + { + args[0] = this.list[texture]; + + callback.apply(scope, args); + } + }, + + /** + * Destroys the Texture Manager and all Textures stored within it. + * + * @method Phaser.Textures.TextureManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var texture in this.list) + { + this.list[texture].destroy(); + } + + this.list = {}; + + this.game = null; + + CanvasPool.remove(this._tempCanvas); + } + +}); + +module.exports = TextureManager; + + +/***/ }), +/* 417 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Clamp = __webpack_require__(18); +var Color = __webpack_require__(36); +var CONST = __webpack_require__(39); +var IsSizePowerOfTwo = __webpack_require__(136); +var Texture = __webpack_require__(203); + +/** + * @classdesc + * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. + * + * You can use the properties of this texture to draw to the canvas element directly, using all of the standard + * canvas operations available in the browser. Any Game Object can be given this texture and will render with it. + * + * Note: When running under WebGL the Canvas Texture needs to re-generate its base WebGLTexture and reupload it to + * the GPU every time you modify it, otherwise the changes you make to this texture will not be visible. To do this + * you should call `CanvasTexture.refresh()` once you are finished with your changes to the canvas. Try and keep + * this to a minimum, especially on large canvas sizes, or you may inadvertently thrash the GPU by constantly uploading + * texture data to it. This restriction does not apply if using the Canvas Renderer. + * + * It starts with only one frame that covers the whole of the canvas. You can add further frames, that specify + * sections of the canvas using the `add` method. + * + * Should you need to resize the canvas use the `setSize` method so that it accurately updates all of the underlying + * texture data as well. Forgetting to do this (i.e. by changing the canvas size directly from your code) could cause + * graphical errors. + * + * @class CanvasTexture + * @extends Phaser.Textures.Texture + * @memberof Phaser.Textures + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Textures.TextureManager} manager - A reference to the Texture Manager this Texture belongs to. + * @param {string} key - The unique string-based key of this Texture. + * @param {HTMLCanvasElement} source - The canvas element that is used as the base of this texture. + * @param {number} width - The width of the canvas. + * @param {number} height - The height of the canvas. + */ +var CanvasTexture = new Class({ + + Extends: Texture, + + initialize: + + function CanvasTexture (manager, key, source, width, height) + { + Texture.call(this, manager, key, source, width, height); + + this.add('__BASE', 0, 0, 0, width, height); + + /** + * A reference to the Texture Source of this Canvas. + * + * @name Phaser.Textures.CanvasTexture#_source + * @type {Phaser.Textures.TextureSource} + * @private + * @since 3.7.0 + */ + this._source = this.frames['__BASE'].source; + + /** + * The source Canvas Element. + * + * @name Phaser.Textures.CanvasTexture#canvas + * @readonly + * @type {HTMLCanvasElement} + * @since 3.7.0 + */ + this.canvas = this._source.image; + + /** + * The 2D Canvas Rendering Context. + * + * @name Phaser.Textures.CanvasTexture#context + * @readonly + * @type {CanvasRenderingContext2D} + * @since 3.7.0 + */ + this.context = this.canvas.getContext('2d'); + + /** + * The width of the Canvas. + * This property is read-only, if you wish to change it use the `setSize` method. + * + * @name Phaser.Textures.CanvasTexture#width + * @readonly + * @type {number} + * @since 3.7.0 + */ + this.width = width; + + /** + * The height of the Canvas. + * This property is read-only, if you wish to change it use the `setSize` method. + * + * @name Phaser.Textures.CanvasTexture#height + * @readonly + * @type {number} + * @since 3.7.0 + */ + this.height = height; + + /** + * The context image data. + * Use the `update` method to populate this when the canvas changes. + * + * @name Phaser.Textures.CanvasTexture#imageData + * @type {ImageData} + * @since 3.13.0 + */ + this.imageData = this.context.getImageData(0, 0, width, height); + + /** + * A Uint8ClampedArray view into the `buffer`. + * Use the `update` method to populate this when the canvas changes. + * Note that this is unavailable in some browsers, such as Epic Browser, due to their security restrictions. + * + * @name Phaser.Textures.CanvasTexture#data + * @type {Uint8ClampedArray} + * @since 3.13.0 + */ + this.data = null; + + if (this.imageData) + { + this.data = this.imageData.data; + } + + /** + * An Uint32Array view into the `buffer`. + * + * @name Phaser.Textures.CanvasTexture#pixels + * @type {Uint32Array} + * @since 3.13.0 + */ + this.pixels = null; + + /** + * An ArrayBuffer the same size as the context ImageData. + * + * @name Phaser.Textures.CanvasTexture#buffer + * @type {ArrayBuffer} + * @since 3.13.0 + */ + this.buffer; + + if (this.data) + { + if (this.imageData.data.buffer) + { + this.buffer = this.imageData.data.buffer; + this.pixels = new Uint32Array(this.buffer); + } + else if (window.ArrayBuffer) + { + this.buffer = new ArrayBuffer(this.imageData.data.length); + this.pixels = new Uint32Array(this.buffer); + } + else + { + this.pixels = this.imageData.data; + } + } + }, + + /** + * This re-creates the `imageData` from the current context. + * It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array. + * + * Warning: This is a very expensive operation, so use it sparingly. + * + * @method Phaser.Textures.CanvasTexture#update + * @since 3.13.0 + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + update: function () + { + this.imageData = this.context.getImageData(0, 0, this.width, this.height); + + this.data = this.imageData.data; + + if (this.imageData.data.buffer) + { + this.buffer = this.imageData.data.buffer; + this.pixels = new Uint32Array(this.buffer); + } + else if (window.ArrayBuffer) + { + this.buffer = new ArrayBuffer(this.imageData.data.length); + this.pixels = new Uint32Array(this.buffer); + } + else + { + this.pixels = this.imageData.data; + } + + if (this.manager.game.config.renderType === CONST.WEBGL) + { + this.refresh(); + } + + return this; + }, + + /** + * Draws the given Image or Canvas element to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. + * + * @method Phaser.Textures.CanvasTexture#draw + * @since 3.13.0 + * + * @param {number} x - The x coordinate to draw the source at. + * @param {number} y - The y coordinate to draw the source at. + * @param {(HTMLImageElement|HTMLCanvasElement)} source - The element to draw to this canvas. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + draw: function (x, y, source) + { + this.context.drawImage(source, x, y); + + return this.update(); + }, + + /** + * Draws the given texture frame to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. + * + * @method Phaser.Textures.CanvasTexture#drawFrame + * @since 3.16.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * @param {number} [x=0] - The x coordinate to draw the source at. + * @param {number} [y=0] - The y coordinate to draw the source at. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + drawFrame: function (key, frame, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + var textureFrame = this.manager.getFrame(key, frame); + + if (textureFrame) + { + var cd = textureFrame.canvasData; + + var width = textureFrame.cutWidth; + var height = textureFrame.cutHeight; + var res = textureFrame.source.resolution; + + this.context.drawImage( + textureFrame.source.image, + cd.x, cd.y, + width, + height, + x, y, + width / res, + height / res + ); + + return this.update(); + } + else + { + return this; + } + }, + + /** + * Sets a pixel in the CanvasTexture to the given color and alpha values. + * + * This is an expensive operation to run in large quantities, so use sparingly. + * + * @method Phaser.Textures.CanvasTexture#setPixel + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} red - The red color value. A number between 0 and 255. + * @param {number} green - The green color value. A number between 0 and 255. + * @param {number} blue - The blue color value. A number between 0 and 255. + * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. + * + * @return {this} This CanvasTexture. + */ + setPixel: function (x, y, red, green, blue, alpha) + { + if (alpha === undefined) { alpha = 255; } + + x = Math.abs(Math.floor(x)); + y = Math.abs(Math.floor(y)); + + var index = this.getIndex(x, y); + + if (index > -1) + { + var imageData = this.context.getImageData(x, y, 1, 1); + + imageData.data[0] = red; + imageData.data[1] = green; + imageData.data[2] = blue; + imageData.data[3] = alpha; + + this.context.putImageData(imageData, x, y); + } + + return this; + }, + + /** + * Puts the ImageData into the context of this CanvasTexture at the given coordinates. + * + * @method Phaser.Textures.CanvasTexture#putData + * @since 3.16.0 + * + * @param {ImageData} imageData - The ImageData to put at the given location. + * @param {number} x - The x coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [dirtyX=0] - Horizontal position (x coordinate) of the top-left corner from which the image data will be extracted. + * @param {number} [dirtyY=0] - Vertical position (x coordinate) of the top-left corner from which the image data will be extracted. + * @param {number} [dirtyWidth] - Width of the rectangle to be painted. Defaults to the width of the image data. + * @param {number} [dirtyHeight] - Height of the rectangle to be painted. Defaults to the height of the image data. + * + * @return {this} This CanvasTexture. + */ + putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + { + if (dirtyX === undefined) { dirtyX = 0; } + if (dirtyY === undefined) { dirtyY = 0; } + if (dirtyWidth === undefined) { dirtyWidth = imageData.width; } + if (dirtyHeight === undefined) { dirtyHeight = imageData.height; } + + this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight); + + return this; + }, + + /** + * Gets an ImageData region from this CanvasTexture from the position and size specified. + * You can write this back using `CanvasTexture.putData`, or manipulate it. + * + * @method Phaser.Textures.CanvasTexture#getData + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} width - The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left. + * @param {number} height - The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up. + * + * @return {ImageData} The ImageData extracted from this CanvasTexture. + */ + getData: function (x, y, width, height) + { + x = Clamp(Math.floor(x), 0, this.width - 1); + y = Clamp(Math.floor(y), 0, this.height - 1); + width = Clamp(width, 1, this.width - x); + height = Clamp(height, 1, this.height - y); + + var imageData = this.context.getImageData(x, y, width, height); + + return imageData; + }, + + /** + * Get the color of a specific pixel from this texture and store it in a Color object. + * + * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, + * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. + * + * @method Phaser.Textures.CanvasTexture#getPixel + * @since 3.13.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {Phaser.Display.Color} [out] - A Color object to store the pixel values in. If not provided a new Color object will be created. + * + * @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties. + */ + getPixel: function (x, y, out) + { + if (!out) + { + out = new Color(); + } + + var index = this.getIndex(x, y); + + if (index > -1) + { + var data = this.data; + + var r = data[index + 0]; + var g = data[index + 1]; + var b = data[index + 2]; + var a = data[index + 3]; + + out.setTo(r, g, b, a); + } + + return out; + }, + + /** + * Returns an array containing all of the pixels in the given region. + * + * If the requested region extends outside the bounds of this CanvasTexture, + * the region is truncated to fit. + * + * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, + * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. + * + * @method Phaser.Textures.CanvasTexture#getPixels + * @since 3.16.0 + * + * @param {number} [x=0] - The x coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [y=0] - The y coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [width] - The width of the region to get. Must be an integer. Defaults to the canvas width if not given. + * @param {number} [height] - The height of the region to get. Must be an integer. If not given will be set to the `width`. + * + * @return {Phaser.Types.Textures.PixelConfig[][]} A 2d array of Pixel objects. + */ + getPixels: function (x, y, width, height) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = width; } + + x = Math.abs(Math.round(x)); + y = Math.abs(Math.round(y)); + + var left = Clamp(x, 0, this.width); + var right = Clamp(x + width, 0, this.width); + var top = Clamp(y, 0, this.height); + var bottom = Clamp(y + height, 0, this.height); + + var pixel = new Color(); + + var out = []; + + for (var py = top; py < bottom; py++) + { + var row = []; + + for (var px = left; px < right; px++) + { + pixel = this.getPixel(px, py, pixel); + + row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); + } + + out.push(row); + } + + return out; + }, + + /** + * Returns the Image Data index for the given pixel in this CanvasTexture. + * + * The index can be used to read directly from the `this.data` array. + * + * The index points to the red value in the array. The subsequent 3 indexes + * point to green, blue and alpha respectively. + * + * @method Phaser.Textures.CanvasTexture#getIndex + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * + * @return {number} + */ + getIndex: function (x, y) + { + x = Math.abs(Math.round(x)); + y = Math.abs(Math.round(y)); + + if (x < this.width && y < this.height) + { + return (x + y * this.width) * 4; + } + else + { + return -1; + } + }, + + /** + * This should be called manually if you are running under WebGL. + * It will refresh the WebGLTexture from the Canvas source. Only call this if you know that the + * canvas has changed, as there is a significant GPU texture allocation cost involved in doing so. + * + * @method Phaser.Textures.CanvasTexture#refresh + * @since 3.7.0 + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + refresh: function () + { + this._source.update(); + + return this; + }, + + /** + * Gets the Canvas Element. + * + * @method Phaser.Textures.CanvasTexture#getCanvas + * @since 3.7.0 + * + * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. + */ + getCanvas: function () + { + return this.canvas; + }, + + /** + * Gets the 2D Canvas Rendering Context. + * + * @method Phaser.Textures.CanvasTexture#getContext + * @since 3.7.0 + * + * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. + */ + getContext: function () + { + return this.context; + }, + + /** + * Clears the given region of this Canvas Texture, resetting it back to transparent. + * If no region is given, the whole Canvas Texture is cleared. + * + * @method Phaser.Textures.CanvasTexture#clear + * @since 3.7.0 + * + * @param {number} [x=0] - The x coordinate of the top-left of the region to clear. + * @param {number} [y=0] - The y coordinate of the top-left of the region to clear. + * @param {number} [width] - The width of the region. + * @param {number} [height] - The height of the region. + * + * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + */ + clear: function (x, y, width, height) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + + this.context.clearRect(x, y, width, height); + + return this.update(); + }, + + /** + * Changes the size of this Canvas Texture. + * + * @method Phaser.Textures.CanvasTexture#setSize + * @since 3.7.0 + * + * @param {number} width - The new width of the Canvas. + * @param {number} [height] - The new height of the Canvas. If not given it will use the width as the height. + * + * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + */ + setSize: function (width, height) + { + if (height === undefined) { height = width; } + + if (width !== this.width || height !== this.height) + { + // Update the Canvas + this.canvas.width = width; + this.canvas.height = height; + + // Update the Texture Source + this._source.width = width; + this._source.height = height; + this._source.isPowerOf2 = IsSizePowerOfTwo(width, height); + + // Update the Frame + this.frames['__BASE'].setSize(width, height, 0, 0); + + // Update this + this.width = width; + this.height = height; + + this.refresh(); + } + + return this; + }, + + /** + * Destroys this Texture and releases references to its sources and frames. + * + * @method Phaser.Textures.CanvasTexture#destroy + * @since 3.16.0 + */ + destroy: function () + { + Texture.prototype.destroy.call(this); + + this._source = null; + this.canvas = null; + this.context = null; + this.imageData = null; + this.data = null; + this.pixels = null; + this.buffer = null; + } + +}); + +module.exports = CanvasTexture; + + +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); +var Class = __webpack_require__(0); +var IsSizePowerOfTwo = __webpack_require__(136); +var ScaleModes = __webpack_require__(164); + +/** + * @classdesc + * A Texture Source is the encapsulation of the actual source data for a Texture. + * + * This is typically an Image Element, loaded from the file system or network, a Canvas Element or a Video Element. + * + * A Texture can contain multiple Texture Sources, which only happens when a multi-atlas is loaded. + * + * @class TextureSource + * @memberof Phaser.Textures + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Textures.Texture} texture - The Texture this TextureSource belongs to. + * @param {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} source - The source image data. + * @param {number} [width] - Optional width of the source image. If not given it's derived from the source itself. + * @param {number} [height] - Optional height of the source image. If not given it's derived from the source itself. + * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + */ +var TextureSource = new Class({ + + initialize: + + function TextureSource (texture, source, width, height, flipY) + { + if (flipY === undefined) { flipY = false; } + + var game = texture.manager.game; + + /** + * The Texture this TextureSource belongs to. + * + * @name Phaser.Textures.TextureSource#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.7.0 + */ + this.renderer = game.renderer; + + /** + * The Texture this TextureSource belongs to. + * + * @name Phaser.Textures.TextureSource#texture + * @type {Phaser.Textures.Texture} + * @since 3.0.0 + */ + this.texture = texture; + + /** + * The source of the image data. + * + * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. + * + * @name Phaser.Textures.TextureSource#source + * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} + * @since 3.12.0 + */ + this.source = source; + + /** + * The image data. + * + * This is either an Image element, Canvas element or a Video Element. + * + * @name Phaser.Textures.TextureSource#image + * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} + * @since 3.0.0 + */ + this.image = source; + + /** + * Currently un-used. + * + * @name Phaser.Textures.TextureSource#compressionAlgorithm + * @type {number} + * @default null + * @since 3.0.0 + */ + this.compressionAlgorithm = null; + + /** + * The resolution of the source image. + * + * @name Phaser.Textures.TextureSource#resolution + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.resolution = 1; + + /** + * The width of the source image. If not specified in the constructor it will check + * the `naturalWidth` and then `width` properties of the source image. + * + * @name Phaser.Textures.TextureSource#width + * @type {number} + * @since 3.0.0 + */ + this.width = width || source.naturalWidth || source.videoWidth || source.width || 0; + + /** + * The height of the source image. If not specified in the constructor it will check + * the `naturalHeight` and then `height` properties of the source image. + * + * @name Phaser.Textures.TextureSource#height + * @type {number} + * @since 3.0.0 + */ + this.height = height || source.naturalHeight || source.videoHeight || source.height || 0; + + /** + * The Scale Mode the image will use when rendering. + * Either Linear or Nearest. + * + * @name Phaser.Textures.TextureSource#scaleMode + * @type {number} + * @since 3.0.0 + */ + this.scaleMode = ScaleModes.DEFAULT; + + /** + * Is the source image a Canvas Element? + * + * @name Phaser.Textures.TextureSource#isCanvas + * @type {boolean} + * @since 3.0.0 + */ + this.isCanvas = (source instanceof HTMLCanvasElement); + + /** + * Is the source image a Video Element? + * + * @name Phaser.Textures.TextureSource#isVideo + * @type {boolean} + * @since 3.20.0 + */ + this.isVideo = (window.hasOwnProperty('HTMLVideoElement') && source instanceof HTMLVideoElement); + + /** + * Is the source image a Render Texture? + * + * @name Phaser.Textures.TextureSource#isRenderTexture + * @type {boolean} + * @since 3.12.0 + */ + this.isRenderTexture = (source.type === 'RenderTexture'); + + /** + * Is the source image a WebGLTexture? + * + * @name Phaser.Textures.TextureSource#isGLTexture + * @type {boolean} + * @since 3.19.0 + */ + this.isGLTexture = (window.hasOwnProperty('WebGLTexture') && source instanceof WebGLTexture); + + /** + * Are the source image dimensions a power of two? + * + * @name Phaser.Textures.TextureSource#isPowerOf2 + * @type {boolean} + * @since 3.0.0 + */ + this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height); + + /** + * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture + * already, then this is a reference to that WebGLTexture. + * + * @name Phaser.Textures.TextureSource#glTexture + * @type {?WebGLTexture} + * @default null + * @since 3.0.0 + */ + this.glTexture = null; + + /** + * The current texture unit index as assigned by the WebGL Renderer. + * Un-used in canvas. Should be treated as read-only. + * + * @name Phaser.Textures.TextureSource#glIndex + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.glIndex = 0; + + /** + * The counter value when this texture was last assigned an index by the WebGL Renderer. + * Un-used in canvas. Should be treated as read-only. + * + * @name Phaser.Textures.TextureSource#glIndexCounter + * @type {number} + * @default -1 + * @since 3.50.0 + */ + this.glIndexCounter = -1; + + /** + * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + * + * @name Phaser.Textures.TextureSource#flipY + * @type {boolean} + * @since 3.20.0 + */ + this.flipY = flipY; + + this.init(game); + }, + + /** + * Creates a WebGL Texture, if required, and sets the Texture filter mode. + * + * @method Phaser.Textures.TextureSource#init + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. + */ + init: function (game) + { + var renderer = this.renderer; + + if (renderer) + { + if (renderer.gl) + { + if (this.isCanvas) + { + this.glTexture = renderer.createCanvasTexture(this.image, false, this.flipY); + } + else if (this.isVideo) + { + this.glTexture = renderer.createVideoTexture(this.image, false, this.flipY); + } + else if (this.isRenderTexture) + { + this.image = this.source.canvas; + + this.glTexture = renderer.createTextureFromSource(null, this.width, this.height, this.scaleMode); + } + else if (this.isGLTexture) + { + this.glTexture = this.source; + } + else + { + this.glTexture = renderer.createTextureFromSource(this.image, this.width, this.height, this.scaleMode); + } + } + else if (this.isRenderTexture) + { + this.image = this.source.canvas; + } + } + + if (!game.config.antialias) + { + this.setFilter(1); + } + }, + + /** + * Sets the Filter Mode for this Texture. + * + * The mode can be either Linear, the default, or Nearest. + * + * For pixel-art you should use Nearest. + * + * @method Phaser.Textures.TextureSource#setFilter + * @since 3.0.0 + * + * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. + */ + setFilter: function (filterMode) + { + if (this.renderer.gl) + { + this.renderer.setTextureFilter(this.glTexture, filterMode); + } + + this.scaleMode = filterMode; + }, + + /** + * Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload. + * + * @method Phaser.Textures.TextureSource#setFlipY + * @since 3.20.0 + * + * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? + */ + setFlipY: function (value) + { + if (value === undefined) { value = true; } + + this.flipY = value; + + return this; + }, + + /** + * If this TextureSource is backed by a Canvas and is running under WebGL, + * it updates the WebGLTexture using the canvas data. + * + * @method Phaser.Textures.TextureSource#update + * @since 3.7.0 + */ + update: function () + { + var gl = this.renderer.gl; + + if (gl && this.isCanvas) + { + this.glTexture = this.renderer.updateCanvasTexture(this.image, this.glTexture, this.flipY); + } + else if (gl && this.isVideo) + { + this.glTexture = this.renderer.updateVideoTexture(this.image, this.glTexture, this.flipY); + } + }, + + /** + * Destroys this Texture Source and nulls the references. + * + * @method Phaser.Textures.TextureSource#destroy + * @since 3.0.0 + */ + destroy: function () + { + if (this.glTexture) + { + this.renderer.deleteTexture(this.glTexture, false); + } + + if (this.isCanvas) + { + CanvasPool.remove(this.image); + } + + this.renderer = null; + this.texture = null; + this.source = null; + this.image = null; + this.glTexture = null; + } + +}); + +module.exports = TextureSource; + + +/***/ }), +/* 419 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Textures.Parsers + */ + +module.exports = { + + AtlasXML: __webpack_require__(975), + Canvas: __webpack_require__(976), + Image: __webpack_require__(977), + JSONArray: __webpack_require__(978), + JSONHash: __webpack_require__(979), + SpriteSheet: __webpack_require__(980), + SpriteSheetFromAtlas: __webpack_require__(981), + UnityYAML: __webpack_require__(982) + +}; + + +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var HTML5AudioSoundManager = __webpack_require__(421); +var NoAudioSoundManager = __webpack_require__(424); +var WebAudioSoundManager = __webpack_require__(426); + +/** + * Creates a Web Audio, HTML5 Audio or No Audio Sound Manager based on config and device settings. + * + * Be aware of https://developers.google.com/web/updates/2017/09/autoplay-policy-changes + * + * @function Phaser.Sound.SoundManagerCreator + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + * + * @return {(Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager|Phaser.Sound.NoAudioSoundManager)} The Sound Manager instance that was created. + */ +var SoundManagerCreator = { + + create: function (game) + { + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + return new NoAudioSoundManager(game); + } + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + return new WebAudioSoundManager(game); + } + + return new HTML5AudioSoundManager(game); + } + +}; + +module.exports = SoundManagerCreator; + + +/***/ }), +/* 421 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var HTML5AudioSound = __webpack_require__(423); + +/** + * HTML5 Audio implementation of the Sound Manager. + * + * To play multiple instances of the same HTML5 Audio sound, you need to provide an `instances` value when + * loading the sound with the Loader: + * + * ```javascript + * this.load.audio('explosion', 'explosion.mp3', { + * instances: 2 + * }); + * ``` + * + * Not all browsers can play all audio formats. + * + * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). + * + * @class HTML5AudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var HTML5AudioSoundManager = new Class({ + + Extends: BaseSoundManager, + + initialize: + + function HTML5AudioSoundManager (game) + { + /** + * Flag indicating whether if there are no idle instances of HTML5 Audio tag, + * for any particular sound, if one of the used tags should be hijacked and used + * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play + * call should be ignored. + * + * @name Phaser.Sound.HTML5AudioSoundManager#override + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.override = true; + + /** + * Value representing time difference, in seconds, between calling + * play method on an audio tag and when it actually starts playing. + * It is used to achieve more accurate delayed sound playback. + * + * You might need to tweak this value to get the desired results + * since audio play delay varies depending on the browser/platform. + * + * @name Phaser.Sound.HTML5AudioSoundManager#audioPlayDelay + * @type {number} + * @default 0.1 + * @since 3.0.0 + */ + this.audioPlayDelay = 0.1; + + /** + * A value by which we should offset the loop end marker of the + * looping sound to compensate for lag, caused by changing audio + * tag playback position, in order to achieve gapless looping. + * + * You might need to tweak this value to get the desired results + * since loop lag varies depending on the browser/platform. + * + * @name Phaser.Sound.HTML5AudioSoundManager#loopEndOffset + * @type {number} + * @default 0.05 + * @since 3.0.0 + */ + this.loopEndOffset = 0.05; + + /** + * An array for keeping track of all the sounds + * that were paused when game lost focus. + * + * @name Phaser.Sound.HTML5AudioSoundManager#onBlurPausedSounds + * @type {Phaser.Sound.HTML5AudioSound[]} + * @private + * @default [] + * @since 3.0.0 + */ + this.onBlurPausedSounds = []; + + this.locked = 'ontouchstart' in window; + + /** + * A queue of all actions performed on sound objects while audio was locked. + * Once the audio gets unlocked, after an explicit user interaction, + * all actions will be performed in chronological order. + * Array of object types: { sound: Phaser.Sound.HTML5AudioSound, name: string, value?: * } + * + * @name Phaser.Sound.HTML5AudioSoundManager#lockedActionsQueue + * @type {array} + * @private + * @since 3.0.0 + */ + this.lockedActionsQueue = this.locked ? [] : null; + + /** + * Property that actually holds the value of global mute + * for HTML5 Audio sound manager implementation. + * + * @name Phaser.Sound.HTML5AudioSoundManager#_mute + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._mute = false; + + /** + * Property that actually holds the value of global volume + * for HTML5 Audio sound manager implementation. + * + * @name Phaser.Sound.HTML5AudioSoundManager#_volume + * @type {boolean} + * @private + * @default 1 + * @since 3.0.0 + */ + this._volume = 1; + + BaseSoundManager.call(this, game); + }, + + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#add + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {Phaser.Sound.HTML5AudioSound} The new sound instance. + */ + add: function (key, config) + { + var sound = new HTML5AudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + /** + * Unlocks HTML5 Audio loading and playback on mobile + * devices on the initial explicit user interaction. + * + * @method Phaser.Sound.HTML5AudioSoundManager#unlock + * @since 3.0.0 + */ + unlock: function () + { + this.locked = false; + + var _this = this; + + this.game.cache.audio.entries.each(function (key, tags) + { + for (var i = 0; i < tags.length; i++) + { + if (tags[i].dataset.locked === 'true') + { + _this.locked = true; + + return false; + } + } + + return true; + }); + + if (!this.locked) + { + return; + } + + var moved = false; + + var detectMove = function () + { + moved = true; + }; + + var unlock = function () + { + if (moved) + { + moved = false; + return; + } + + document.body.removeEventListener('touchmove', detectMove); + document.body.removeEventListener('touchend', unlock); + + var lockedTags = []; + + _this.game.cache.audio.entries.each(function (key, tags) + { + for (var i = 0; i < tags.length; i++) + { + var tag = tags[i]; + + if (tag.dataset.locked === 'true') + { + lockedTags.push(tag); + } + } + + return true; + }); + + if (lockedTags.length === 0) + { + return; + } + + var lastTag = lockedTags[lockedTags.length - 1]; + + lastTag.oncanplaythrough = function () + { + lastTag.oncanplaythrough = null; + + lockedTags.forEach(function (tag) + { + tag.dataset.locked = 'false'; + }); + + _this.unlocked = true; + }; + + lockedTags.forEach(function (tag) + { + tag.load(); + }); + }; + + this.once(Events.UNLOCKED, function () + { + this.forEachActiveSound(function (sound) + { + if (sound.currentMarker === null && sound.duration === 0) + { + sound.duration = sound.tags[0].duration; + } + + sound.totalDuration = sound.tags[0].duration; + }); + + while (this.lockedActionsQueue.length) + { + var lockedAction = this.lockedActionsQueue.shift(); + + if (lockedAction.sound[lockedAction.prop].apply) + { + lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); + } + else + { + lockedAction.sound[lockedAction.prop] = lockedAction.value; + } + } + + }, this); + + document.body.addEventListener('touchmove', detectMove, false); + document.body.addEventListener('touchend', unlock, false); + }, + + /** + * Method used internally for pausing sound manager if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onBlur + * @protected + * @since 3.0.0 + */ + onBlur: function () + { + this.forEachActiveSound(function (sound) + { + if (sound.isPlaying) + { + this.onBlurPausedSounds.push(sound); + sound.onBlur(); + } + }); + }, + + /** + * Method used internally for resuming sound manager if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onFocus + * @protected + * @since 3.0.0 + */ + onFocus: function () + { + this.onBlurPausedSounds.forEach(function (sound) + { + sound.onFocus(); + }); + + this.onBlurPausedSounds.length = 0; + }, + + /** + * Calls Phaser.Sound.BaseSoundManager#destroy method + * and cleans up all HTML5 Audio related stuff. + * + * @method Phaser.Sound.HTML5AudioSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSoundManager.prototype.destroy.call(this); + + this.onBlurPausedSounds.length = 0; + this.onBlurPausedSounds = null; + }, + + /** + * Method used internally by Phaser.Sound.HTML5AudioSound class methods and property setters + * to check if sound manager is locked and then either perform action immediately or queue it + * to be performed once the sound manager gets unlocked. + * + * @method Phaser.Sound.HTML5AudioSoundManager#isLocked + * @protected + * @since 3.0.0 + * + * @param {Phaser.Sound.HTML5AudioSound} sound - Sound object on which to perform queued action. + * @param {string} prop - Name of the method to be called or property to be assigned a value to. + * @param {*} [value] - An optional parameter that either holds an array of arguments to be passed to the method call or value to be set to the property. + * + * @return {boolean} Whether the sound manager is locked. + */ + isLocked: function (sound, prop, value) + { + if (sound.tags[0].dataset.locked === 'true') + { + this.lockedActionsQueue.push({ + sound: sound, + prop: prop, + value: value + }); + + return true; + } + + return false; + }, + + /** + * Sets the muted state of all this Sound Manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#setMute + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.3.0 + * + * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * + * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * @name Phaser.Sound.HTML5AudioSoundManager#mute + * @type {boolean} + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return this._mute; + }, + + set: function (value) + { + this._mute = value; + + this.forEachActiveSound(function (sound) + { + sound.updateMute(); + }); + + this.emit(Events.GLOBAL_MUTE, this, value); + } + + }, + + /** + * Sets the volume of this Sound Manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#setVolume + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.3.0 + * + * @param {number} value - The global volume of this Sound Manager. + * + * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * @name Phaser.Sound.HTML5AudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this._volume; + }, + + set: function (value) + { + this._volume = value; + + this.forEachActiveSound(function (sound) + { + sound.updateVolume(); + }); + + this.emit(Events.GLOBAL_VOLUME, this, value); + } + + } + +}); + +module.exports = HTML5AudioSoundManager; + + +/***/ }), +/* 422 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SafeRange = __webpack_require__(78); + +/** + * 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 {number} [startIndex=0] - An optional start index to search from. + * @param {number} [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; + + +/***/ }), +/* 423 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var Clamp = __webpack_require__(18); + +/** + * @classdesc + * HTML5 Audio implementation of the sound. + * + * @class HTML5AudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.HTML5AudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var HTML5AudioSound = new Class({ + + Extends: BaseSound, + + initialize: + + function HTML5AudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } + + /** + * An array containing all HTML5 Audio tags that could be used for individual + * sound's playback. Number of instances depends on the config value passed + * to the Loader#audio method call, default is 1. + * + * @name Phaser.Sound.HTML5AudioSound#tags + * @type {HTMLAudioElement[]} + * @private + * @since 3.0.0 + */ + this.tags = manager.game.cache.audio.get(key); + + if (!this.tags) + { + throw new Error('There is no audio asset with key "' + key + '" in the audio cache'); + } + + /** + * Reference to an HTML5 Audio tag used for playing sound. + * + * @name Phaser.Sound.HTML5AudioSound#audio + * @type {HTMLAudioElement} + * @private + * @default null + * @since 3.0.0 + */ + this.audio = null; + + /** + * Timestamp as generated by the Request Animation Frame or SetTimeout + * representing the time at which the delayed sound playback should start. + * Set to 0 if sound playback is not delayed. + * + * @name Phaser.Sound.HTML5AudioSound#startTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * Audio tag's playback position recorded on previous + * update method call. Set to 0 if sound is not playing. + * + * @name Phaser.Sound.HTML5AudioSound#previousTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.previousTime = 0; + + this.duration = this.tags[0].duration; + + this.totalDuration = this.tags[0].duration; + + BaseSound.call(this, manager, key, config); + }, + + /** + * Play this sound, or a marked section of it. + * It always plays the sound from the start. If you want to start playback from a specific time + * you can set 'seek' setting of the config object, provided to this call, to that value. + * + * @method Phaser.Sound.HTML5AudioSound#play + * @fires Phaser.Sound.Events#PLAY + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} Whether the sound started playing successfully. + */ + play: function (markerName, config) + { + if (this.manager.isLocked(this, 'play', [ markerName, config ])) + { + return false; + } + + if (!BaseSound.prototype.play.call(this, markerName, config)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) + { + return false; + } + + this.emit(Events.PLAY, this); + + return true; + }, + + /** + * Pauses the sound. + * + * @method Phaser.Sound.HTML5AudioSound#pause + * @fires Phaser.Sound.Events#PAUSE + * @since 3.0.0 + * + * @return {boolean} Whether the sound was paused successfully. + */ + pause: function () + { + if (this.manager.isLocked(this, 'pause')) + { + return false; + } + + if (this.startTime > 0) + { + return false; + } + + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + + this.stopAndReleaseAudioTag(); + + this.emit(Events.PAUSE, this); + + return true; + }, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.HTML5AudioSound#resume + * @fires Phaser.Sound.Events#RESUME + * @since 3.0.0 + * + * @return {boolean} Whether the sound was resumed successfully. + */ + resume: function () + { + if (this.manager.isLocked(this, 'resume')) + { + return false; + } + + if (this.startTime > 0) + { + return false; + } + + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) + { + return false; + } + + this.emit(Events.RESUME, this); + + return true; + }, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.HTML5AudioSound#stop + * @fires Phaser.Sound.Events#STOP + * @since 3.0.0 + * + * @return {boolean} Whether the sound was stopped successfully. + */ + stop: function () + { + if (this.manager.isLocked(this, 'stop')) + { + return false; + } + + if (!BaseSound.prototype.stop.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = false \/\/\/ + this.stopAndReleaseAudioTag(); + + this.emit(Events.STOP, this); + + return true; + }, + + /** + * Used internally to do what the name says. + * + * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag + * @private + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAndPlayAudioTag: function () + { + if (!this.pickAudioTag()) + { + this.reset(); + return false; + } + + var seek = this.currentConfig.seek; + var delay = this.currentConfig.delay; + var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; + + this.previousTime = offset; + this.audio.currentTime = offset; + this.applyConfig(); + + if (delay === 0) + { + this.startTime = 0; + + if (this.audio.paused) + { + this.playCatchPromise(); + } + } + else + { + this.startTime = window.performance.now() + delay * 1000; + + if (!this.audio.paused) + { + this.audio.pause(); + } + } + + this.resetConfig(); + + return true; + }, + + /** + * This method performs the audio tag pooling logic. It first looks for + * unused audio tag to assign to this sound object. If there are no unused + * audio tags, based on HTML5AudioSoundManager#override property value, it + * looks for sound with most advanced playback and hijacks its audio tag or + * does nothing. + * + * @method Phaser.Sound.HTML5AudioSound#pickAudioTag + * @private + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAudioTag: function () + { + if (this.audio) + { + return true; + } + + for (var i = 0; i < this.tags.length; i++) + { + var audio = this.tags[i]; + + if (audio.dataset.used === 'false') + { + audio.dataset.used = 'true'; + this.audio = audio; + return true; + } + } + + if (!this.manager.override) + { + return false; + } + + var otherSounds = []; + + this.manager.forEachActiveSound(function (sound) + { + if (sound.key === this.key && sound.audio) + { + otherSounds.push(sound); + } + }, this); + + otherSounds.sort(function (a1, a2) + { + if (a1.loop === a2.loop) + { + // sort by progress + return (a2.seek / a2.duration) - (a1.seek / a1.duration); + } + return a1.loop ? 1 : -1; + }); + + var selectedSound = otherSounds[0]; + + this.audio = selectedSound.audio; + + selectedSound.reset(); + selectedSound.audio = null; + selectedSound.startTime = 0; + selectedSound.previousTime = 0; + + return true; + }, + + /** + * Method used for playing audio tag and catching possible exceptions + * thrown from rejected Promise returned from play method call. + * + * @method Phaser.Sound.HTML5AudioSound#playCatchPromise + * @private + * @since 3.0.0 + */ + playCatchPromise: function () + { + var playPromise = this.audio.play(); + + if (playPromise) + { + // eslint-disable-next-line no-unused-vars + playPromise.catch(function (reason) + { + console.warn(reason); + }); + } + }, + + /** + * Used internally to do what the name says. + * + * @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag + * @private + * @since 3.0.0 + */ + stopAndReleaseAudioTag: function () + { + this.startTime = 0; + this.previousTime = 0; + + if (this.audio) + { + this.audio.pause(); + this.audio.dataset.used = 'false'; + this.audio = null; + } + }, + + /** + * Method used internally to reset sound state, usually when stopping sound + * or when hijacking audio tag from another sound. + * + * @method Phaser.Sound.HTML5AudioSound#reset + * @private + * @since 3.0.0 + */ + reset: function () + { + BaseSound.prototype.stop.call(this); + }, + + /** + * Method used internally by sound manager for pausing sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onBlur + * @private + * @since 3.0.0 + */ + onBlur: function () + { + this.isPlaying = false; + this.isPaused = true; + + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + + this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); + + this.stopAndReleaseAudioTag(); + }, + + /** + * Method used internally by sound manager for resuming sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSound#onFocus + * @private + * @since 3.0.0 + */ + onFocus: function () + { + this.isPlaying = true; + this.isPaused = false; + this.pickAndPlayAudioTag(); + }, + + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.HTML5AudioSound#update + * @fires Phaser.Sound.Events#COMPLETE + * @fires Phaser.Sound.Events#LOOPED + * @protected + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + */ + update: function (time) + { + if (!this.isPlaying) + { + return; + } + + // handling delayed playback + if (this.startTime > 0) + { + if (this.startTime < time - this.manager.audioPlayDelay) + { + this.audio.currentTime += Math.max(0, time - this.startTime) / 1000; + this.startTime = 0; + this.previousTime = this.audio.currentTime; + this.playCatchPromise(); + } + + return; + } + + // handle looping and ending + var startTime = this.currentMarker ? this.currentMarker.start : 0; + var endTime = startTime + this.duration; + var currentTime = this.audio.currentTime; + + if (this.currentConfig.loop) + { + if (currentTime >= endTime - this.manager.loopEndOffset) + { + this.audio.currentTime = startTime + Math.max(0, currentTime - endTime); + currentTime = this.audio.currentTime; + } + else if (currentTime < startTime) + { + this.audio.currentTime += startTime; + currentTime = this.audio.currentTime; + } + + if (currentTime < this.previousTime) + { + this.emit(Events.LOOPED, this); + } + } + else if (currentTime >= endTime) + { + this.reset(); + + this.stopAndReleaseAudioTag(); + + this.emit(Events.COMPLETE, this); + + return; + } + + this.previousTime = currentTime; + }, + + /** + * Calls Phaser.Sound.BaseSound#destroy method + * and cleans up all HTML5 Audio related stuff. + * + * @method Phaser.Sound.HTML5AudioSound#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + + this.tags = null; + + if (this.audio) + { + this.stopAndReleaseAudioTag(); + } + }, + + /** + * Method used internally to determine mute setting of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateMute + * @private + * @since 3.0.0 + */ + updateMute: function () + { + if (this.audio) + { + this.audio.muted = this.currentConfig.mute || this.manager.mute; + } + }, + + /** + * Method used internally to calculate total volume of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateVolume + * @private + * @since 3.0.0 + */ + updateVolume: function () + { + if (this.audio) + { + this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1); + } + }, + + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#calculateRate + * @protected + * @since 3.0.0 + */ + calculateRate: function () + { + BaseSound.prototype.calculateRate.call(this); + + if (this.audio) + { + this.audio.playbackRate = this.totalRate; + } + }, + + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + * + * @name Phaser.Sound.HTML5AudioSound#mute + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return this.currentConfig.mute; + }, + + set: function (value) + { + this.currentConfig.mute = value; + + if (this.manager.isLocked(this, 'mute', value)) + { + return; + } + + this.updateMute(); + + this.emit(Events.MUTE, this, value); + } + }, + + /** + * Sets the muted state of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setMute + * @fires Phaser.Sound.Events#MUTE + * @since 3.4.0 + * + * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * + * @return {this} This Sound instance. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * + * @name Phaser.Sound.HTML5AudioSound#volume + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.currentConfig.volume; + }, + + set: function (value) + { + this.currentConfig.volume = value; + + if (this.manager.isLocked(this, 'volume', value)) + { + return; + } + + this.updateVolume(); + + this.emit(Events.VOLUME, this, value); + } + }, + + /** + * Sets the volume of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setVolume + * @fires Phaser.Sound.Events#VOLUME + * @since 3.4.0 + * + * @param {number} value - The volume of the sound. + * + * @return {this} This Sound instance. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * Rate at which this Sound will be played. + * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @name Phaser.Sound.HTML5AudioSound#rate + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#RATE + * @since 3.0.0 + */ + rate: { + + get: function () + { + return this.currentConfig.rate; + }, + + set: function (value) + { + this.currentConfig.rate = value; + + if (this.manager.isLocked(this, Events.RATE, value)) + { + return; + } + else + { + this.calculateRate(); + + this.emit(Events.RATE, this, value); + } + } + + }, + + /** + * Sets the playback rate of this Sound. + * + * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @method Phaser.Sound.HTML5AudioSound#setRate + * @fires Phaser.Sound.Events#RATE + * @since 3.3.0 + * + * @param {number} value - The playback rate at of this Sound. + * + * @return {this} This Sound instance. + */ + setRate: function (value) + { + this.rate = value; + + return this; + }, + + /** + * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @name Phaser.Sound.HTML5AudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE + * @since 3.0.0 + */ + detune: { + + get: function () + { + return this.currentConfig.detune; + }, + + set: function (value) + { + this.currentConfig.detune = value; + + if (this.manager.isLocked(this, Events.DETUNE, value)) + { + return; + } + else + { + this.calculateRate(); + + this.emit(Events.DETUNE, this, value); + } + } + + }, + + /** + * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @method Phaser.Sound.HTML5AudioSound#setDetune + * @fires Phaser.Sound.Events#DETUNE + * @since 3.3.0 + * + * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @return {this} This Sound instance. + */ + setDetune: function (value) + { + this.detune = value; + + return this; + }, + + /** + * Property representing the position of playback for this sound, in seconds. + * Setting it to a specific value moves current playback to that position. + * The value given is clamped to the range 0 to current marker duration. + * Setting seek of a stopped sound has no effect. + * + * @name Phaser.Sound.HTML5AudioSound#seek + * @type {number} + * @fires Phaser.Sound.Events#SEEK + * @since 3.0.0 + */ + seek: { + + get: function () + { + if (this.isPlaying) + { + return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + } + else if (this.isPaused) + { + return this.currentConfig.seek; + } + else + { + return 0; + } + }, + + set: function (value) + { + if (this.manager.isLocked(this, 'seek', value)) + { + return; + } + + if (this.startTime > 0) + { + return; + } + + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); + + if (this.isPlaying) + { + this.previousTime = value; + this.audio.currentTime = value; + } + else if (this.isPaused) + { + this.currentConfig.seek = value; + } + + this.emit(Events.SEEK, this, value); + } + } + }, + + /** + * Seeks to a specific point in this sound. + * + * @method Phaser.Sound.HTML5AudioSound#setSeek + * @fires Phaser.Sound.Events#SEEK + * @since 3.4.0 + * + * @param {number} value - The point in the sound to seek to. + * + * @return {this} This Sound instance. + */ + setSeek: function (value) + { + this.seek = value; + + return this; + }, + + /** + * Flag indicating whether or not the sound or current sound marker will loop. + * + * @name Phaser.Sound.HTML5AudioSound#loop + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#LOOP + * @since 3.0.0 + */ + loop: { + + get: function () + { + return this.currentConfig.loop; + }, + + set: function (value) + { + this.currentConfig.loop = value; + + if (this.manager.isLocked(this, 'loop', value)) + { + return; + } + + if (this.audio) + { + this.audio.loop = value; + } + + this.emit(Events.LOOP, this, value); + } + + }, + + /** + * Sets the loop state of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setLoop + * @fires Phaser.Sound.Events#LOOP + * @since 3.4.0 + * + * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * + * @return {Phaser.Sound.HTML5AudioSound} This Sound instance. + */ + setLoop: function (value) + { + this.loop = value; + + return this; + }, + + /** + * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * + * @name Phaser.Sound.HTML5AudioSound#pan + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + */ + pan: { + + get: function () + { + return this.currentConfig.pan; + }, + + set: function (value) + { + this.currentConfig.pan = value; + + this.emit(Events.PAN, this, value); + } + }, + + /** + * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * + * @method Phaser.Sound.HTML5AudioSound#setPan + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + * + * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + * + * @return {this} This Sound instance. + */ + setPan: function (value) + { + this.pan = value; + + return this; + } + +}); + +module.exports = HTML5AudioSound; + + +/***/ }), +/* 424 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var NoAudioSound = __webpack_require__(425); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * No-audio implementation of the Sound Manager. It is used if audio has been + * disabled in the game config or the device doesn't support any audio. + * + * It represents a graceful degradation of Sound Manager logic that provides + * minimal functionality and prevents Phaser projects that use audio from + * breaking on devices that don't support any audio playback technologies. + * + * @class NoAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var NoAudioSoundManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function NoAudioSoundManager (game) + { + EventEmitter.call(this); + + this.game = game; + this.sounds = []; + this.mute = false; + this.volume = 1; + this.rate = 1; + this.detune = 0; + this.pauseOnBlur = true; + this.locked = false; + }, + + add: function (key, config) + { + var sound = new NoAudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + addAudioSprite: function (key, config) + { + var sound = this.add(key, config); + + sound.spritemap = {}; + + return sound; + }, + + // eslint-disable-next-line no-unused-vars + play: function (key, extra) + { + return false; + }, + + // eslint-disable-next-line no-unused-vars + playAudioSprite: function (key, spriteName, config) + { + return false; + }, + + remove: function (sound) + { + return BaseSoundManager.prototype.remove.call(this, sound); + }, + + removeByKey: function (key) + { + return BaseSoundManager.prototype.removeByKey.call(this, key); + }, + + pauseAll: NOOP, + resumeAll: NOOP, + stopAll: NOOP, + update: NOOP, + setRate: NOOP, + setDetune: NOOP, + setMute: NOOP, + setVolume: NOOP, + + forEachActiveSound: function (callbackfn, scope) + { + BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); + }, + + destroy: function () + { + BaseSoundManager.prototype.destroy.call(this); + } + +}); + +module.exports = NoAudioSoundManager; + + +/***/ }), +/* 425 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Extend = __webpack_require__(17); + +var returnFalse = function () +{ + return false; +}; + +var returnNull = function () +{ + return null; +}; + +var returnThis = function () +{ + return this; +}; + +/** + * @classdesc + * No audio implementation of the sound. It is used if audio has been + * disabled in the game config or the device doesn't support any audio. + * + * It represents a graceful degradation of sound logic that provides + * minimal functionality and prevents Phaser projects that use audio from + * breaking on devices that don't support any audio playback technologies. + * + * @class NoAudioSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.NoAudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var NoAudioSound = new Class({ + + Extends: EventEmitter, + + initialize: + + function NoAudioSound (manager, key, config) + { + if (config === void 0) { config = {}; } + + EventEmitter.call(this); + + this.manager = manager; + this.key = key; + this.isPlaying = false; + this.isPaused = false; + this.totalRate = 1; + this.duration = 0; + this.totalDuration = 0; + + this.config = Extend({ + mute: false, + volume: 1, + rate: 1, + detune: 0, + seek: 0, + loop: false, + delay: 0, + pan: 0 + }, config); + + this.currentConfig = this.config; + this.mute = false; + this.volume = 1; + this.rate = 1; + this.detune = 0; + this.seek = 0; + this.loop = false; + this.pan = 0; + this.markers = {}; + this.currentMarker = null; + this.pendingRemove = false; + }, + + /** + * @method Phaser.Sound.NoAudioSound#addMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * + * @return {boolean} false + */ + addMarker: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#updateMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. + * + * @return {boolean} false + */ + updateMarker: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#removeMarker + * @since 3.0.0 + * + * @param {string} markerName - The name of the marker to remove. + * + * @return {null} null + */ + removeMarker: returnNull, + + /** + * @method Phaser.Sound.NoAudioSound#play + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} false + */ + play: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#pause + * @since 3.0.0 + * + * @return {boolean} false + */ + pause: returnFalse, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.NoAudioSound#resume + * @since 3.0.0 + * + * @return {boolean} false + */ + resume: returnFalse, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.NoAudioSound#stop + * @since 3.0.0 + * + * @return {boolean} false + */ + stop: returnFalse, + + /** + * Destroys this sound and all associated events and marks it for removal from the sound manager. + * + * @method Phaser.Sound.NoAudioSound#destroy + * @fires Phaser.Sound.Events#DESTROY + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + }, + + setMute: returnThis, + + setVolume: returnThis, + + setRate: returnThis, + + setDetune: returnThis, + + setSeek: returnThis, + + setLoop: returnThis, + + setPan: returnThis + +}); + +module.exports = NoAudioSound; + + +/***/ }), +/* 426 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Base64ToArrayBuffer = __webpack_require__(427); +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var GameEvents = __webpack_require__(22); +var WebAudioSound = __webpack_require__(428); + +/** + * @classdesc + * Web Audio API implementation of the Sound Manager. + * + * Not all browsers can play all audio formats. + * + * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). + * + * @class WebAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var WebAudioSoundManager = new Class({ + + Extends: BaseSoundManager, + + initialize: + + function WebAudioSoundManager (game) + { + /** + * The AudioContext being used for playback. + * + * @name Phaser.Sound.WebAudioSoundManager#context + * @type {AudioContext} + * @private + * @since 3.0.0 + */ + this.context = this.createAudioContext(game); + + /** + * Gain node responsible for controlling global muting. + * + * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.masterMuteNode = this.context.createGain(); + + /** + * Gain node responsible for controlling global volume. + * + * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.masterVolumeNode = this.context.createGain(); + + this.masterMuteNode.connect(this.masterVolumeNode); + + this.masterVolumeNode.connect(this.context.destination); + + /** + * Destination node for connecting individual sounds to. + * + * @name Phaser.Sound.WebAudioSoundManager#destination + * @type {AudioNode} + * @private + * @since 3.0.0 + */ + this.destination = this.masterMuteNode; + + this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); + + BaseSoundManager.call(this, game); + + if (this.locked && game.isBooted) + { + this.unlock(); + } + else + { + game.events.once(GameEvents.BOOT, this.unlock, this); + } + }, + + /** + * Method responsible for instantiating and returning AudioContext instance. + * If an instance of an AudioContext class was provided through the game config, + * that instance will be returned instead. This can come in handy if you are reloading + * a Phaser game on a page that never properly refreshes (such as in an SPA project) + * and you want to reuse already instantiated AudioContext. + * + * @method Phaser.Sound.WebAudioSoundManager#createAudioContext + * @private + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + * + * @return {AudioContext} The AudioContext instance to be used for playback. + */ + createAudioContext: function (game) + { + var audioConfig = game.config.audio; + + if (audioConfig.context) + { + audioConfig.context.resume(); + + return audioConfig.context; + } + + return new AudioContext(); + }, + + /** + * This method takes a new AudioContext reference and then sets + * this Sound Manager to use that context for all playback. + * + * As part of this call it also disconnects the master mute and volume + * nodes and then re-creates them on the new given context. + * + * @method Phaser.Sound.WebAudioSoundManager#setAudioContext + * @since 3.21.0 + * + * @param {AudioContext} context - Reference to an already created AudioContext instance. + * + * @return {this} The WebAudioSoundManager instance. + */ + setAudioContext: function (context) + { + if (this.context) + { + this.context.close(); + } + + if (this.masterMuteNode) + { + this.masterMuteNode.disconnect(); + } + + if (this.masterVolumeNode) + { + this.masterVolumeNode.disconnect(); + } + + this.context = context; + + this.masterMuteNode = context.createGain(); + this.masterVolumeNode = context.createGain(); + + this.masterMuteNode.connect(this.masterVolumeNode); + this.masterVolumeNode.connect(context.destination); + + this.destination = this.masterMuteNode; + + return this; + }, + + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.WebAudioSoundManager#add + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {Phaser.Sound.WebAudioSound} The new sound instance. + */ + add: function (key, config) + { + var sound = new WebAudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + /** + * Decode audio data into a format ready for playback via Web Audio. + * + * The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + * + * The `audioKey` is the key that will be used to save the decoded audio to the audio cache. + * + * Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig` + * objects as the first and only argument. + * + * Decoding is an async process, so be sure to listen for the events to know when decoding has completed. + * + * Once the audio has decoded it can be added to the Sound Manager or played via its key. + * + * @method Phaser.Sound.WebAudioSoundManager#decodeAudio + * @fires Phaser.Sound.Events#DECODED + * @fires Phaser.Sound.Events#DECODED_ALL + * @since 3.18.0 + * + * @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects. + * @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + */ + decodeAudio: function (audioKey, audioData) + { + var audioFiles; + + if (!Array.isArray(audioKey)) + { + audioFiles = [ { key: audioKey, data: audioData } ]; + } + else + { + audioFiles = audioKey; + } + + var cache = this.game.cache.audio; + var remaining = audioFiles.length; + + for (var i = 0; i < audioFiles.length; i++) + { + var entry = audioFiles[i]; + + var key = entry.key; + var data = entry.data; + + if (typeof data === 'string') + { + data = Base64ToArrayBuffer(data); + } + + var success = function (key, audioBuffer) + { + cache.add(key, audioBuffer); + + this.emit(Events.DECODED, key); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + var failure = function (key, error) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + this.context.decodeAudioData(data, success, failure); + } + }, + + /** + * Unlocks Web Audio API on the initial input event. + * + * Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09). + * + * @method Phaser.Sound.WebAudioSoundManager#unlock + * @since 3.0.0 + */ + unlock: function () + { + var _this = this; + + var body = document.body; + + var unlockHandler = function unlockHandler () + { + if (_this.context) + { + _this.context.resume().then(function () + { + body.removeEventListener('touchstart', unlockHandler); + body.removeEventListener('touchend', unlockHandler); + body.removeEventListener('click', unlockHandler); + body.removeEventListener('keydown', unlockHandler); + + _this.unlocked = true; + }, function () + { + body.removeEventListener('touchstart', unlockHandler); + body.removeEventListener('touchend', unlockHandler); + body.removeEventListener('click', unlockHandler); + body.removeEventListener('keydown', unlockHandler); + }); + } + }; + + if (body) + { + body.addEventListener('touchstart', unlockHandler, false); + body.addEventListener('touchend', unlockHandler, false); + body.addEventListener('click', unlockHandler, false); + body.addEventListener('keydown', unlockHandler, false); + } + }, + + /** + * Method used internally for pausing sound manager if + * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.WebAudioSoundManager#onBlur + * @protected + * @since 3.0.0 + */ + onBlur: function () + { + if (!this.locked) + { + this.context.suspend(); + } + }, + + /** + * Method used internally for resuming sound manager if + * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.WebAudioSoundManager#onFocus + * @protected + * @since 3.0.0 + */ + onFocus: function () + { + if (!this.locked) + { + this.context.resume(); + } + }, + + /** + * Calls Phaser.Sound.BaseSoundManager#destroy method + * and cleans up all Web Audio API related stuff. + * + * @method Phaser.Sound.WebAudioSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.destination = null; + this.masterVolumeNode.disconnect(); + this.masterVolumeNode = null; + this.masterMuteNode.disconnect(); + this.masterMuteNode = null; + + if (this.game.config.audio.context) + { + this.context.suspend(); + } + else + { + var _this = this; + + this.context.close().then(function () + { + _this.context = null; + }); + } + + BaseSoundManager.prototype.destroy.call(this); + }, + + /** + * Sets the muted state of all this Sound Manager. + * + * @method Phaser.Sound.WebAudioSoundManager#setMute + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.3.0 + * + * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * + * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * @name Phaser.Sound.WebAudioSoundManager#mute + * @type {boolean} + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return (this.masterMuteNode.gain.value === 0); + }, + + set: function (value) + { + this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0); + + this.emit(Events.GLOBAL_MUTE, this, value); + } + + }, + + /** + * Sets the volume of this Sound Manager. + * + * @method Phaser.Sound.WebAudioSoundManager#setVolume + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.3.0 + * + * @param {number} value - The global volume of this Sound Manager. + * + * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * @name Phaser.Sound.WebAudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.masterVolumeNode.gain.value; + }, + + set: function (value) + { + this.masterVolumeNode.gain.setValueAtTime(value, 0); + + this.emit(Events.GLOBAL_VOLUME, this, value); + } + + } + +}); + +module.exports = WebAudioSoundManager; + + +/***/ }), +/* 427 */ +/***/ (function(module, exports) { + +/** + * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +// Use a lookup table to find the index. +var lookup = new Uint8Array(256); + +for (var i = 0; i < chars.length; i++) +{ + lookup[chars.charCodeAt(i)] = i; +} + +/** + * Converts a base64 string, either with or without a data uri, into an Array Buffer. + * + * @function Phaser.Utils.Base64.Base64ToArrayBuffer + * @since 3.18.0 + * + * @param {string} base64 - The base64 string to be decoded. Can optionally contain a data URI header, which will be stripped out prior to decoding. + * + * @return {ArrayBuffer} An ArrayBuffer decoded from the base64 data. + */ +var Base64ToArrayBuffer = function (base64) +{ + // Is it a data uri? if so, strip the header away + base64 = base64.substr(base64.indexOf(',') + 1); + + var len = base64.length; + var bufferLength = len * 0.75; + var p = 0; + var encoded1; + var encoded2; + var encoded3; + var encoded4; + + if (base64[len - 1] === '=') + { + bufferLength--; + + if (base64[len - 2] === '=') + { + bufferLength--; + } + } + + var arrayBuffer = new ArrayBuffer(bufferLength); + var bytes = new Uint8Array(arrayBuffer); + + for (var i = 0; i < len; i += 4) + { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; + + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } + + return arrayBuffer; +}; + +module.exports = Base64ToArrayBuffer; + + +/***/ }), +/* 428 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); + +/** + * @classdesc + * Web Audio API implementation of the sound. + * + * @class WebAudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.WebAudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var WebAudioSound = new Class({ + + Extends: BaseSound, + + initialize: + + function WebAudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } + + /** + * Audio buffer containing decoded data of the audio asset to be played. + * + * @name Phaser.Sound.WebAudioSound#audioBuffer + * @type {AudioBuffer} + * @private + * @since 3.0.0 + */ + this.audioBuffer = manager.game.cache.audio.get(key); + + if (!this.audioBuffer) + { + throw new Error('Audio key "' + key + '" missing from cache'); + } + + /** + * A reference to an audio source node used for playing back audio from + * audio data stored in Phaser.Sound.WebAudioSound#audioBuffer. + * + * @name Phaser.Sound.WebAudioSound#source + * @type {AudioBufferSourceNode} + * @private + * @default null + * @since 3.0.0 + */ + this.source = null; + + /** + * A reference to a second audio source used for gapless looped playback. + * + * @name Phaser.Sound.WebAudioSound#loopSource + * @type {AudioBufferSourceNode} + * @private + * @default null + * @since 3.0.0 + */ + this.loopSource = null; + + /** + * Gain node responsible for controlling this sound's muting. + * + * @name Phaser.Sound.WebAudioSound#muteNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.muteNode = manager.context.createGain(); + + /** + * Gain node responsible for controlling this sound's volume. + * + * @name Phaser.Sound.WebAudioSound#volumeNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.volumeNode = manager.context.createGain(); + + /** + * Panner node responsible for controlling this sound's pan. + * + * Doesn't work on iOS / Safari. + * + * @name Phaser.Sound.WebAudioSound#pannerNode + * @type {StereoPannerNode} + * @private + * @since 3.50.0 + */ + this.pannerNode = null; + + /** + * The time at which the sound should have started playback from the beginning. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#playTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.playTime = 0; + + /** + * The time at which the sound source should have actually started playback. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#startTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * The time at which the sound loop source should actually start playback. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#loopTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.loopTime = 0; + + /** + * An array where we keep track of all rate updates during playback. + * Array of object types: { time: number, rate: number } + * + * @name Phaser.Sound.WebAudioSound#rateUpdates + * @type {array} + * @private + * @default [] + * @since 3.0.0 + */ + this.rateUpdates = []; + + /** + * Used for keeping track when sound source playback has ended + * so its state can be updated accordingly. + * + * @name Phaser.Sound.WebAudioSound#hasEnded + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this.hasEnded = false; + + /** + * Used for keeping track when sound source has looped + * so its state can be updated accordingly. + * + * @name Phaser.Sound.WebAudioSound#hasLooped + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this.hasLooped = false; + + this.muteNode.connect(this.volumeNode); + + if (manager.context.createStereoPanner) + { + this.pannerNode = manager.context.createStereoPanner(); + + this.volumeNode.connect(this.pannerNode); + + this.pannerNode.connect(manager.destination); + } + else + { + this.volumeNode.connect(manager.destination); + } + + this.duration = this.audioBuffer.duration; + + this.totalDuration = this.audioBuffer.duration; + + BaseSound.call(this, manager, key, config); + }, + + /** + * Play this sound, or a marked section of it. + * + * It always plays the sound from the start. If you want to start playback from a specific time + * you can set 'seek' setting of the config object, provided to this call, to that value. + * + * @method Phaser.Sound.WebAudioSound#play + * @fires Phaser.Sound.Events#PLAY + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} Whether the sound started playing successfully. + */ + play: function (markerName, config) + { + if (!BaseSound.prototype.play.call(this, markerName, config)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + + this.emit(Events.PLAY, this); + + return true; + }, + + /** + * Pauses the sound. + * + * @method Phaser.Sound.WebAudioSound#pause + * @fires Phaser.Sound.Events#PAUSE + * @since 3.0.0 + * + * @return {boolean} Whether the sound was paused successfully. + */ + pause: function () + { + if (this.manager.context.currentTime < this.startTime) + { + return false; + } + + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time + this.stopAndRemoveBufferSource(); + + this.emit(Events.PAUSE, this); + + return true; + }, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.WebAudioSound#resume + * @fires Phaser.Sound.Events#RESUME + * @since 3.0.0 + * + * @return {boolean} Whether the sound was resumed successfully. + */ + resume: function () + { + if (this.manager.context.currentTime < this.startTime) + { + return false; + } + + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.createAndStartBufferSource(); + + this.emit(Events.RESUME, this); + + return true; + }, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.WebAudioSound#stop + * @fires Phaser.Sound.Events#STOP + * @since 3.0.0 + * + * @return {boolean} Whether the sound was stopped successfully. + */ + stop: function () + { + if (!BaseSound.prototype.stop.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = false \/\/\/ + this.stopAndRemoveBufferSource(); + + this.emit(Events.STOP, this); + + return true; + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createAndStartBufferSource + * @private + * @since 3.0.0 + */ + createAndStartBufferSource: function () + { + var seek = this.currentConfig.seek; + var delay = this.currentConfig.delay; + var when = this.manager.context.currentTime + delay; + var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; + var duration = this.duration - seek; + + this.playTime = when - seek; + this.startTime = when; + this.source = this.createBufferSource(); + + this.applyConfig(); + + this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); + + this.resetConfig(); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource + * @private + * @since 3.0.0 + */ + createAndStartLoopBufferSource: function () + { + var when = this.getLoopTime(); + var offset = this.currentMarker ? this.currentMarker.start : 0; + var duration = this.duration; + + this.loopTime = when; + this.loopSource = this.createBufferSource(); + this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0); + this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createBufferSource + * @private + * @since 3.0.0 + * + * @return {AudioBufferSourceNode} + */ + createBufferSource: function () + { + var _this = this; + var source = this.manager.context.createBufferSource(); + + source.buffer = this.audioBuffer; + + source.connect(this.muteNode); + + source.onended = function (ev) + { + if (ev.target === _this.source) + { + // sound ended + if (_this.currentConfig.loop) + { + _this.hasLooped = true; + } + else + { + _this.hasEnded = true; + } + } + + // else was stopped + }; + + return source; + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource + * @private + * @since 3.0.0 + */ + stopAndRemoveBufferSource: function () + { + if (this.source) + { + this.source.stop(); + this.source.disconnect(); + this.source = null; + } + + this.playTime = 0; + this.startTime = 0; + + this.stopAndRemoveLoopBufferSource(); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource + * @private + * @since 3.0.0 + */ + stopAndRemoveLoopBufferSource: function () + { + if (this.loopSource) + { + this.loopSource.stop(); + this.loopSource.disconnect(); + this.loopSource = null; + } + + this.loopTime = 0; + }, + + /** + * Method used internally for applying config values to some of the sound properties. + * + * @method Phaser.Sound.WebAudioSound#applyConfig + * @protected + * @since 3.0.0 + */ + applyConfig: function () + { + this.rateUpdates.length = 0; + + this.rateUpdates.push({ + time: 0, + rate: 1 + }); + + BaseSound.prototype.applyConfig.call(this); + }, + + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.WebAudioSound#update + * @fires Phaser.Sound.Events#COMPLETE + * @fires Phaser.Sound.Events#LOOPED + * @protected + * @since 3.0.0 + */ + update: function () + { + if (this.hasEnded) + { + this.hasEnded = false; + + BaseSound.prototype.stop.call(this); + + this.stopAndRemoveBufferSource(); + + this.emit(Events.COMPLETE, this); + } + else if (this.hasLooped) + { + this.hasLooped = false; + this.source = this.loopSource; + this.loopSource = null; + this.playTime = this.startTime = this.loopTime; + this.rateUpdates.length = 0; + + this.rateUpdates.push({ + time: 0, + rate: this.totalRate + }); + + this.createAndStartLoopBufferSource(); + + this.emit(Events.LOOPED, this); + } + }, + + /** + * Calls Phaser.Sound.BaseSound#destroy method + * and cleans up all Web Audio API related stuff. + * + * @method Phaser.Sound.WebAudioSound#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + + this.audioBuffer = null; + this.stopAndRemoveBufferSource(); + this.muteNode.disconnect(); + this.muteNode = null; + this.volumeNode.disconnect(); + this.volumeNode = null; + this.pannerNode.disconnect(); + this.pannerNode = null; + this.rateUpdates.length = 0; + this.rateUpdates = null; + }, + + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.WebAudioSound#calculateRate + * @protected + * @since 3.0.0 + */ + calculateRate: function () + { + BaseSound.prototype.calculateRate.call(this); + + var now = this.manager.context.currentTime; + + if (this.source && typeof this.totalRate === 'number') + { + this.source.playbackRate.setValueAtTime(this.totalRate, now); + } + + if (this.isPlaying) + { + this.rateUpdates.push({ + time: Math.max(this.startTime, now) - this.playTime, + rate: this.totalRate + }); + + if (this.loopSource) + { + this.stopAndRemoveLoopBufferSource(); + this.createAndStartLoopBufferSource(); + } + } + }, + + /** + * Method used internally for calculating current playback time of a playing sound. + * + * @method Phaser.Sound.WebAudioSound#getCurrentTime + * @private + * @since 3.0.0 + */ + getCurrentTime: function () + { + var currentTime = 0; + + for (var i = 0; i < this.rateUpdates.length; i++) + { + var nextTime = 0; + + if (i < this.rateUpdates.length - 1) + { + nextTime = this.rateUpdates[i + 1].time; + } + else + { + nextTime = this.manager.context.currentTime - this.playTime; + } + + currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } + + return currentTime; + }, + + /** + * Method used internally for calculating the time + * at witch the loop source should start playing. + * + * @method Phaser.Sound.WebAudioSound#getLoopTime + * @private + * @since 3.0.0 + */ + getLoopTime: function () + { + var lastRateUpdateCurrentTime = 0; + + for (var i = 0; i < this.rateUpdates.length - 1; i++) + { + lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } + + var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1]; + + return this.playTime + lastRateUpdate.time + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate; + }, + + /** + * Rate at which this Sound will be played. + * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @name Phaser.Sound.WebAudioSound#rate + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#RATE + * @since 3.0.0 + */ + rate: { + + get: function () + { + return this.currentConfig.rate; + }, + + set: function (value) + { + this.currentConfig.rate = value; + + this.calculateRate(); + + this.emit(Events.RATE, this, value); + } + + }, + + /** + * Sets the playback rate of this Sound. + * + * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @method Phaser.Sound.WebAudioSound#setRate + * @fires Phaser.Sound.Events#RATE + * @since 3.3.0 + * + * @param {number} value - The playback rate at of this Sound. + * + * @return {this} This Sound instance. + */ + setRate: function (value) + { + this.rate = value; + + return this; + }, + + /** + * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @name Phaser.Sound.WebAudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE + * @since 3.0.0 + */ + detune: { + + get: function () + { + return this.currentConfig.detune; + }, + + set: function (value) + { + this.currentConfig.detune = value; + + this.calculateRate(); + + this.emit(Events.DETUNE, this, value); + } + + }, + + /** + * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @method Phaser.Sound.WebAudioSound#setDetune + * @fires Phaser.Sound.Events#DETUNE + * @since 3.3.0 + * + * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @return {this} This Sound instance. + */ + setDetune: function (value) + { + this.detune = value; + + return this; + }, + + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + * + * @name Phaser.Sound.WebAudioSound#mute + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return (this.muteNode.gain.value === 0); + }, + + set: function (value) + { + this.currentConfig.mute = value; + this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0); + + this.emit(Events.MUTE, this, value); + } + + }, + + /** + * Sets the muted state of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setMute + * @fires Phaser.Sound.Events#MUTE + * @since 3.4.0 + * + * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * + * @return {this} This Sound instance. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * + * @name Phaser.Sound.WebAudioSound#volume + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.volumeNode.gain.value; + }, + + set: function (value) + { + this.currentConfig.volume = value; + this.volumeNode.gain.setValueAtTime(value, 0); + + this.emit(Events.VOLUME, this, value); + } + }, + + /** + * Sets the volume of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setVolume + * @fires Phaser.Sound.Events#VOLUME + * @since 3.4.0 + * + * @param {number} value - The volume of the sound. + * + * @return {this} This Sound instance. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * Property representing the position of playback for this sound, in seconds. + * Setting it to a specific value moves current playback to that position. + * The value given is clamped to the range 0 to current marker duration. + * Setting seek of a stopped sound has no effect. + * + * @name Phaser.Sound.WebAudioSound#seek + * @type {number} + * @fires Phaser.Sound.Events#SEEK + * @since 3.0.0 + */ + seek: { + + get: function () + { + if (this.isPlaying) + { + if (this.manager.context.currentTime < this.startTime) + { + return this.startTime - this.playTime; + } + + return this.getCurrentTime(); + } + else if (this.isPaused) + { + return this.currentConfig.seek; + } + else + { + return 0; + } + }, + + set: function (value) + { + if (this.manager.context.currentTime < this.startTime) + { + return; + } + + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); + + this.currentConfig.seek = value; + + if (this.isPlaying) + { + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + } + + this.emit(Events.SEEK, this, value); + } + } + }, + + /** + * Seeks to a specific point in this sound. + * + * @method Phaser.Sound.WebAudioSound#setSeek + * @fires Phaser.Sound.Events#SEEK + * @since 3.4.0 + * + * @param {number} value - The point in the sound to seek to. + * + * @return {this} This Sound instance. + */ + setSeek: function (value) + { + this.seek = value; + + return this; + }, + + /** + * Flag indicating whether or not the sound or current sound marker will loop. + * + * @name Phaser.Sound.WebAudioSound#loop + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#LOOP + * @since 3.0.0 + */ + loop: { + + get: function () + { + return this.currentConfig.loop; + }, + + set: function (value) + { + this.currentConfig.loop = value; + + if (this.isPlaying) + { + this.stopAndRemoveLoopBufferSource(); + + if (value) + { + this.createAndStartLoopBufferSource(); + } + } + + this.emit(Events.LOOP, this, value); + } + }, + + /** + * Sets the loop state of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setLoop + * @fires Phaser.Sound.Events#LOOP + * @since 3.4.0 + * + * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * + * @return {this} This Sound instance. + */ + setLoop: function (value) + { + this.loop = value; + + return this; + }, + + /** + * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Always returns zero on iOS / Safari as it doesn't support the stereo panner node. + * + * @name Phaser.Sound.WebAudioSound#pan + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + */ + pan: { + + get: function () + { + if (this.pannerNode) + { + return this.pannerNode.pan.value; + } + else + { + return 0; + } + }, + + set: function (value) + { + this.currentConfig.pan = value; + + if (this.pannerNode) + { + this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime); + } + + this.emit(Events.PAN, this, value); + } + }, + + /** + * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Note: iOS / Safari doesn't support the stereo panner node. + * + * @method Phaser.Sound.WebAudioSound#setPan + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + * + * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + * + * @return {this} This Sound instance. + */ + setPan: function (value) + { + this.pan = value; + + return this; + } + +}); + +module.exports = WebAudioSound; + + +/***/ }), +/* 429 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 430 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 {number} k - The k-th element index. + * @param {number} [left=0] - The index of the left part of the range. + * @param {number} [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; + + +/***/ }), +/* 431 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetValue = __webpack_require__(6); +var Shuffle = __webpack_require__(129); + +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; + + +/***/ }), +/* 432 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Structs.Events + */ + +module.exports = { + + PROCESS_QUEUE_ADD: __webpack_require__(1035), + PROCESS_QUEUE_REMOVE: __webpack_require__(1036) + +}; + + +/***/ }), +/* 433 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetAdvancedValue = __webpack_require__(13); + +/** + * Adds an Animation component to a Sprite and populates it based on the given config. + * + * @function Phaser.GameObjects.BuildGameObjectAnimation + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. + * @param {object} config - The animation config. + * + * @return {Phaser.GameObjects.Sprite} The updated Sprite. + */ +var BuildGameObjectAnimation = function (sprite, config) +{ + var animConfig = GetAdvancedValue(config, 'anims', null); + + if (animConfig === null) + { + return sprite; + } + + if (typeof animConfig === 'string') + { + // { anims: 'key' } + sprite.anims.play(animConfig); + } + else if (typeof animConfig === 'object') + { + // { anims: { + // key: string + // startFrame: [string|number] + // delay: [float] + // repeat: [integer] + // repeatDelay: [float] + // yoyo: [boolean] + // play: [boolean] + // delayedPlay: [boolean] + // } + // } + + var anims = sprite.anims; + + var key = GetAdvancedValue(animConfig, 'key', undefined); + + if (key) + { + var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); + + var delay = GetAdvancedValue(animConfig, 'delay', 0); + var repeat = GetAdvancedValue(animConfig, 'repeat', 0); + var repeatDelay = GetAdvancedValue(animConfig, 'repeatDelay', 0); + var yoyo = GetAdvancedValue(animConfig, 'yoyo', false); + + var play = GetAdvancedValue(animConfig, 'play', false); + var delayedPlay = GetAdvancedValue(animConfig, 'delayedPlay', 0); + + var playConfig = { + key: key, + delay: delay, + repeat: repeat, + repeatDelay: repeatDelay, + yoyo: yoyo, + startFrame: startFrame + }; + + if (play) + { + anims.play(playConfig); + } + else if (delayedPlay > 0) + { + anims.playAfterDelay(playConfig, delayedPlay); + } + else + { + anims.load(playConfig); + } + } + } + + return sprite; +}; + +module.exports = BuildGameObjectAnimation; + + +/***/ }), +/* 434 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Frame = __webpack_require__(106); + +/** + * @classdesc + * A Bob Game Object. + * + * A Bob belongs to a Blitter Game Object. The Blitter is responsible for managing and rendering this object. + * + * A Bob has a position, alpha value and a frame from a texture that it uses to render with. You can also toggle + * the flipped and visible state of the Bob. The Frame the Bob uses to render can be changed dynamically, but it + * must be a Frame within the Texture used by the parent Blitter. + * + * Bob positions are relative to the Blitter parent. So if you move the Blitter parent, all Bob children will + * have their positions impacted by this change as well. + * + * You can manipulate Bob objects directly from your game code, but the creation and destruction of them should be + * handled via the Blitter parent. + * + * @class Bob + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Blitter} blitter - The parent Blitter object is responsible for updating this Bob. + * @param {number} x - The horizontal position of this Game Object in the world, relative to the parent Blitter position. + * @param {number} y - The vertical position of this Game Object in the world, relative to the parent Blitter position. + * @param {(string|number)} frame - The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. + * @param {boolean} visible - Should the Bob render visible or not to start with? + */ +var Bob = new Class({ + + initialize: + + function Bob (blitter, x, y, frame, visible) + { + /** + * The Blitter object that this Bob belongs to. + * + * @name Phaser.GameObjects.Bob#parent + * @type {Phaser.GameObjects.Blitter} + * @since 3.0.0 + */ + this.parent = blitter; + + /** + * The x position of this Bob, relative to the x position of the Blitter. + * + * @name Phaser.GameObjects.Bob#x + * @type {number} + * @since 3.0.0 + */ + this.x = x; + + /** + * The y position of this Bob, relative to the y position of the Blitter. + * + * @name Phaser.GameObjects.Bob#y + * @type {number} + * @since 3.0.0 + */ + this.y = y; + + /** + * The frame that the Bob uses to render with. + * To change the frame use the `Bob.setFrame` method. + * + * @name Phaser.GameObjects.Bob#frame + * @type {Phaser.Textures.Frame} + * @protected + * @since 3.0.0 + */ + this.frame = frame; + + /** + * A blank object which can be used to store data related to this Bob in. + * + * @name Phaser.GameObjects.Bob#data + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.data = {}; + + /** + * The tint value of this Bob. + * + * @name Phaser.GameObjects.Bob#tint + * @type {number} + * @default 0xffffff + * @since 3.20.0 + */ + this.tint = 0xffffff; + + /** + * The visible state of this Bob. + * + * @name Phaser.GameObjects.Bob#_visible + * @type {boolean} + * @private + * @since 3.0.0 + */ + this._visible = visible; + + /** + * The alpha value of this Bob. + * + * @name Phaser.GameObjects.Bob#_alpha + * @type {number} + * @private + * @default 1 + * @since 3.0.0 + */ + this._alpha = 1; + + /** + * The horizontally flipped state of the Bob. + * A Bob that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture. + * + * @name Phaser.GameObjects.Bob#flipX + * @type {boolean} + * @since 3.0.0 + */ + this.flipX = false; + + /** + * The vertically flipped state of the Bob. + * A Bob 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. + * + * @name Phaser.GameObjects.Bob#flipY + * @type {boolean} + * @since 3.0.0 + */ + this.flipY = false; + }, + + /** + * Changes the Texture Frame being used by this Bob. + * The frame must be part of the Texture the parent Blitter is using. + * If no value is given it will use the default frame of the Blitter parent. + * + * @method Phaser.GameObjects.Bob#setFrame + * @since 3.0.0 + * + * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. + * + * @return {this} This Bob Game Object. + */ + setFrame: function (frame) + { + if (frame === undefined) + { + this.frame = this.parent.frame; + } + else if (frame instanceof Frame && frame.texture === this.parent.texture) + { + this.frame = frame; + } + else + { + this.frame = this.parent.texture.get(frame); + } + + return this; + }, + + /** + * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. + * + * @method Phaser.GameObjects.Bob#resetFlip + * @since 3.0.0 + * + * @return {this} This Bob Game Object. + */ + resetFlip: function () + { + this.flipX = false; + this.flipY = false; + + return this; + }, + + /** + * Resets this Bob. + * + * Changes the position to the values given, and optionally changes the frame. + * + * Also resets the flipX and flipY values, sets alpha back to 1 and visible to true. + * + * @method Phaser.GameObjects.Bob#reset + * @since 3.0.0 + * + * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. + * + * @return {this} This Bob Game Object. + */ + reset: function (x, y, frame) + { + this.x = x; + this.y = y; + + this.flipX = false; + this.flipY = false; + + this._alpha = 1; + this._visible = true; + + this.parent.dirty = true; + + if (frame) + { + this.setFrame(frame); + } + + return this; + }, + + /** + * Changes the position of this Bob to the values given. + * + * @method Phaser.GameObjects.Bob#setPosition + * @since 3.20.0 + * + * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * + * @return {this} This Bob Game Object. + */ + setPosition: function (x, y) + { + this.x = x; + this.y = y; + + return this; + }, + + /** + * Sets the horizontal flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#setFlipX + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. + */ + setFlipX: function (value) + { + this.flipX = value; + + return this; + }, + + /** + * Sets the vertical flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#setFlipY + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. + */ + setFlipY: function (value) + { + this.flipY = value; + + return this; + }, + + /** + * Sets the horizontal and vertical flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#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 Bob Game Object. + */ + setFlip: function (x, y) + { + this.flipX = x; + this.flipY = y; + + return this; + }, + + /** + * Sets the visibility of this Bob. + * + * An invisible Bob will skip rendering. + * + * @method Phaser.GameObjects.Bob#setVisible + * @since 3.0.0 + * + * @param {boolean} value - The visible state of the Game Object. + * + * @return {this} This Bob Game Object. + */ + setVisible: function (value) + { + this.visible = value; + + return this; + }, + + /** + * Set the Alpha level of this Bob. 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. + * + * A Bob with alpha 0 will skip rendering. + * + * @method Phaser.GameObjects.Bob#setAlpha + * @since 3.0.0 + * + * @param {number} value - The alpha value used for this Bob. Between 0 and 1. + * + * @return {this} This Bob Game Object. + */ + setAlpha: function (value) + { + this.alpha = value; + + return this; + }, + + /** + * Sets the tint of this Bob. + * + * @method Phaser.GameObjects.Bob#setTint + * @since 3.20.0 + * + * @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff. + * + * @return {this} This Bob Game Object. + */ + setTint: function (value) + { + this.tint = value; + + return this; + }, + + /** + * Destroys this Bob instance. + * Removes itself from the Blitter and clears the parent, frame and data properties. + * + * @method Phaser.GameObjects.Bob#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.parent.dirty = true; + + this.parent.children.remove(this); + + this.parent = undefined; + this.frame = undefined; + this.data = undefined; + }, + + /** + * The visible state of the Bob. + * + * An invisible Bob will skip rendering. + * + * @name Phaser.GameObjects.Bob#visible + * @type {boolean} + * @since 3.0.0 + */ + visible: { + + get: function () + { + return this._visible; + }, + + set: function (value) + { + this.parent.dirty |= (this._visible !== value); + this._visible = value; + } + + }, + + /** + * The alpha value of the Bob, between 0 and 1. + * + * A Bob with alpha 0 will skip rendering. + * + * @name Phaser.GameObjects.Bob#alpha + * @type {number} + * @since 3.0.0 + */ + alpha: { + + get: function () + { + return this._alpha; + }, + + set: function (value) + { + this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); + this._alpha = value; + } + + } + +}); + +module.exports = Bob; + + +/***/ }), +/* 435 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +/** + * 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; + + +/***/ }), +/* 436 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var DOMElementRender = __webpack_require__(1049); +var GameObject = __webpack_require__(15); +var IsPlainObject = __webpack_require__(7); +var RemoveFromDOM = __webpack_require__(199); +var SCENE_EVENTS = __webpack_require__(21); +var Vector4 = __webpack_require__(138); + +/** + * @classdesc + * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. + * + * In order for DOM Elements to display you have to enable them by adding the following to your game + * configuration object: + * + * ```javascript + * dom { + * createContainer: true + * } + * ``` + * + * When this is added, Phaser will automatically create a DOM Container div that is positioned over the top + * of the game canvas. This div is sized to match the canvas, and if the canvas size changes, as a result of + * settings within the Scale Manager, the dom container is resized accordingly. + * + * If you have not already done so, you have to provide a `parent` in the Game Configuration, or the DOM + * Container will fail to be created. + * + * You can create a DOM Element by either passing in DOMStrings, or by passing in a reference to an existing + * Element that you wish to be placed under the control of Phaser. For example: + * + * ```javascript + * this.add.dom(x, y, 'div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * The above code will insert a div element into the DOM Container at the given x/y coordinate. The DOMString in + * the 4th argument sets the initial CSS style of the div and the final argument is the inner text. In this case, + * it will create a lime colored div that is 220px by 100px in size with the text Phaser in it, in an Arial font. + * + * You should nearly always, without exception, use explicitly sized HTML Elements, in order to fully control + * alignment and positioning of the elements next to regular game content. + * + * Rather than specify the CSS and HTML directly you can use the `load.html` File Loader to load it into the + * cache and then use the `createFromCache` method instead. You can also use `createFromHTML` and various other + * methods available in this class to help construct your elements. + * + * Once the element has been created you can then control it like you would any other Game Object. You can set its + * position, scale, rotation, alpha and other properties. It will move as the main Scene Camera moves and be clipped + * at the edge of the canvas. It's important to remember some limitations of DOM Elements: The obvious one is that + * they appear above or below your game canvas. You cannot blend them into the display list, meaning you cannot have + * a DOM Element, then a Sprite, then another DOM Element behind it. + * + * They also cannot be enabled for input. To do that, you have to use the `addListener` method to add native event + * listeners directly. The final limitation is to do with cameras. The DOM Container is sized to match the game canvas + * entirely and clipped accordingly. DOM Elements respect camera scrolling and scrollFactor settings, but if you + * change the size of the camera so it no longer matches the size of the canvas, they won't be clipped accordingly. + * + * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. + * + * Note that you should only have DOM Elements in a Scene with a _single_ Camera. If you require multiple cameras, + * use parallel scenes to achieve this. + * + * DOM Elements are a powerful way to align native HTML with your Phaser Game Objects. For example, you can insert + * a login form for a multiplayer game directly into your title screen. Or a text input box for a highscore table. + * Or a banner ad from a 3rd party service. Or perhaps you'd like to use them for high resolution text display and + * UI. The choice is up to you, just remember that you're dealing with standard HTML and CSS floating over the top + * of your game, and should treat it accordingly. + * + * @class DOMElement + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.17.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.ScrollFactor + * @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 DOM Element in the world. + * @param {number} [y=0] - The vertical position of this DOM Element in the world. + * @param {(Element|string)} [element] - An existing DOM element, or a string. If a string starting with a # it will do a `getElementById` look-up on the string (minus the hash). Without a hash, it represents the type of element to create, i.e. 'div'. + * @param {(string|any)} [style] - If a string, will be set directly as the elements `style` property value. If a plain object, will be iterated and the values transferred. In both cases the values replacing whatever CSS styles may have been previously set. + * @param {string} [innerText] - If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. + */ +var DOMElement = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Origin, + Components.ScrollFactor, + Components.Transform, + Components.Visible, + DOMElementRender + ], + + initialize: + + function DOMElement (scene, x, y, element, style, innerText) + { + GameObject.call(this, scene, 'DOMElement'); + + /** + * A reference to the parent DOM Container that the Game instance created when it started. + * + * @name Phaser.GameObjects.DOMElement#parent + * @type {Element} + * @since 3.17.0 + */ + this.parent = scene.sys.game.domContainer; + + /** + * A reference to the HTML Cache. + * + * @name Phaser.GameObjects.DOMElement#cache + * @type {Phaser.Cache.BaseCache} + * @since 3.17.0 + */ + this.cache = scene.sys.cache.html; + + /** + * The actual DOM Element that this Game Object is bound to. For example, if you've created a `
` + * then this property is a direct reference to that element within the dom. + * + * @name Phaser.GameObjects.DOMElement#node + * @type {Element} + * @since 3.17.0 + */ + this.node; + + /** + * By default a DOM Element will have its transform, display, opacity, zIndex and blend mode properties + * updated when its rendered. If, for some reason, you don't want any of these changed other than the + * CSS transform, then set this flag to `true`. When `true` only the CSS Transform is applied and it's + * up to you to keep track of and set the other properties as required. + * + * This can be handy if, for example, you've a nested DOM Element and you don't want the opacity to be + * picked-up by any of its children. + * + * @name Phaser.GameObjects.DOMElement#transformOnly + * @type {boolean} + * @since 3.17.0 + */ + this.transformOnly = false; + + /** + * The angle, in radians, by which to skew the DOM Element on the horizontal axis. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @name Phaser.GameObjects.DOMElement#skewX + * @type {number} + * @since 3.17.0 + */ + this.skewX = 0; + + /** + * The angle, in radians, by which to skew the DOM Element on the vertical axis. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @name Phaser.GameObjects.DOMElement#skewY + * @type {number} + * @since 3.17.0 + */ + this.skewY = 0; + + /** + * A Vector4 that contains the 3D rotation of this DOM Element around a fixed axis in 3D space. + * + * All values in the Vector4 are treated as degrees, unless the `rotate3dAngle` property is changed. + * + * For more details see the following MDN page: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d + * + * @name Phaser.GameObjects.DOMElement#rotate3d + * @type {Phaser.Math.Vector4} + * @since 3.17.0 + */ + this.rotate3d = new Vector4(); + + /** + * The unit that represents the 3D rotation values. By default this is `deg` for degrees, but can + * be changed to any supported unit. See this page for further details: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d + * + * @name Phaser.GameObjects.DOMElement#rotate3dAngle + * @type {string} + * @since 3.17.0 + */ + this.rotate3dAngle = 'deg'; + + /** + * The native (un-scaled) width of this Game Object. + * + * For a DOM Element this property is read-only. + * + * The property `displayWidth` holds the computed bounds of this DOM Element, factoring in scaling. + * + * @name Phaser.GameObjects.DOMElement#width + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.width = 0; + + /** + * The native (un-scaled) height of this Game Object. + * + * For a DOM Element this property is read-only. + * + * The property `displayHeight` holds the computed bounds of this DOM Element, factoring in scaling. + * + * @name Phaser.GameObjects.DOMElement#height + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.height = 0; + + /** + * The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call. + * + * The property `width` holds the un-scaled width of this DOM Element. + * + * @name Phaser.GameObjects.DOMElement#displayWidth + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.displayWidth = 0; + + /** + * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. + * + * The property `height` holds the un-scaled height of this DOM Element. + * + * @name Phaser.GameObjects.DOMElement#displayHeight + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.displayHeight = 0; + + /** + * Internal native event handler. + * + * @name Phaser.GameObjects.DOMElement#handler + * @type {number} + * @private + * @since 3.17.0 + */ + this.handler = this.dispatchNativeEvent.bind(this); + + this.setPosition(x, y); + + if (typeof element === 'string') + { + // hash? + if (element[0] === '#') + { + this.setElement(element.substr(1), style, innerText); + } + else + { + this.createElement(element, style, innerText); + } + } + else if (element) + { + this.setElement(element, style, innerText); + } + + scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); + scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + }, + + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); + }, + + /** + * Handles a Scene Sleep and Wake event. + * + * @method Phaser.GameObjects.DOMElement#handleSceneEvent + * @private + * @since 3.22.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems. + */ + handleSceneEvent: function (sys) + { + var node = this.node; + var style = node.style; + + if (node) + { + style.display = (sys.settings.visible) ? 'block' : 'none'; + } + }, + + /** + * Sets the horizontal and vertical skew values of this DOM Element. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @method Phaser.GameObjects.DOMElement#setSkew + * @since 3.17.0 + * + * @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis. + * @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis. + * + * @return {this} This DOM Element instance. + */ + setSkew: function (x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this.skewX = x; + this.skewY = y; + + return this; + }, + + /** + * Sets the perspective CSS property of the _parent DOM Container_. This determines the distance between the z=0 + * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with + * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined + * by the value of this property. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * + * @method Phaser.GameObjects.DOMElement#setPerspective + * @since 3.17.0 + * + * @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user. + * + * @return {this} This DOM Element instance. + */ + setPerspective: function (value) + { + this.parent.style.perspective = value + 'px'; + + return this; + }, + + /** + * The perspective CSS property value of the _parent DOM Container_. This determines the distance between the z=0 + * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with + * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined + * by the value of this property. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * + * @name Phaser.GameObjects.DOMElement#perspective + * @type {number} + * @since 3.17.0 + */ + perspective: { + + get: function () + { + return parseFloat(this.parent.style.perspective); + }, + + set: function (value) + { + this.parent.style.perspective = value + 'px'; + } + + }, + + /** + * Adds one or more native DOM event listeners onto the underlying Element of this Game Object. + * The event is then dispatched via this Game Objects standard event emitter. + * + * For example: + * + * ```javascript + * var div = this.add.dom(x, y, element); + * + * div.addListener('click'); + * + * div.on('click', handler); + * ``` + * + * @method Phaser.GameObjects.DOMElement#addListener + * @since 3.17.0 + * + * @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces. + * + * @return {this} This DOM Element instance. + */ + addListener: function (events) + { + if (this.node) + { + events = events.split(' '); + + for (var i = 0; i < events.length; i++) + { + this.node.addEventListener(events[i], this.handler, false); + } + } + + return this; + }, + + /** + * Removes one or more native DOM event listeners from the underlying Element of this Game Object. + * + * @method Phaser.GameObjects.DOMElement#removeListener + * @since 3.17.0 + * + * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. + * + * @return {this} This DOM Element instance. + */ + removeListener: function (events) + { + if (this.node) + { + events = events.split(' '); + + for (var i = 0; i < events.length; i++) + { + this.node.removeEventListener(events[i], this.handler); + } + } + + return this; + }, + + /** + * Internal event proxy to dispatch native DOM Events via this Game Object. + * + * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent + * @private + * @since 3.17.0 + * + * @param {any} event - The native DOM event. + */ + dispatchNativeEvent: function (event) + { + this.emit(event.type, event); + }, + + /** + * Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object, + * so you can control it. The `tagName` should be a string and is passed to `document.createElement`: + * + * ```javascript + * this.add.dom().createElement('div'); + * ``` + * + * For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement + * + * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` + * value as well. Here is an example of a DOMString: + * + * ```javascript + * this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * And using a style object: + * + * ```javascript + * var style = { + * 'background-color': 'lime'; + * 'width': '200px'; + * 'height': '100px'; + * 'font': '48px Arial'; + * }; + * + * this.add.dom().createElement('div', style, 'Phaser'); + * ``` + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createElement + * @since 3.17.0 + * + * @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method. + * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. + * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. + * + * @return {this} This DOM Element instance. + */ + createElement: function (tagName, style, innerText) + { + return this.setElement(document.createElement(tagName), style, innerText); + }, + + /** + * Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM + * entirely first. Any event listeners you may have previously created will need to be re-created on the new element. + * + * The `element` argument you pass to this method can be either a string tagName: + * + * ```javascript + *

Phaser

+ * + * this.add.dom().setElement('heading'); + * ``` + * + * Or a reference to an Element instance: + * + * ```javascript + *

Phaser

+ * + * var h1 = document.getElementById('heading'); + * + * this.add.dom().setElement(h1); + * ``` + * + * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` + * value as well. Here is an example of a DOMString: + * + * ```javascript + * this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * And using a style object: + * + * ```javascript + * var style = { + * 'background-color': 'lime'; + * 'width': '200px'; + * 'height': '100px'; + * 'font': '48px Arial'; + * }; + * + * this.add.dom().setElement(h1, style, 'Phaser'); + * ``` + * + * @method Phaser.GameObjects.DOMElement#setElement + * @since 3.17.0 + * + * @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. + * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. + * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. + * + * @return {this} This DOM Element instance. + */ + setElement: function (element, style, innerText) + { + // Already got an element? Remove it first + this.removeElement(); + + var target; + + if (typeof element === 'string') + { + // hash? + if (element[0] === '#') + { + element = element.substr(1); + } + + target = document.getElementById(element); + } + else if (typeof element === 'object' && element.nodeType === 1) + { + target = element; + } + + if (!target) + { + return this; + } + + this.node = target; + + // style can be empty, a string or a plain object + if (style && IsPlainObject(style)) + { + for (var key in style) + { + target.style[key] = style[key]; + } + } + else if (typeof style === 'string') + { + target.style = style; + } + + // Add / Override the values we need + + target.style.zIndex = '0'; + target.style.display = 'inline'; + target.style.position = 'absolute'; + + // Node handler + + target.phaser = this; + + if (this.parent) + { + this.parent.appendChild(target); + } + + // InnerText + + if (innerText) + { + target.innerText = innerText; + } + + return this.updateSize(); + }, + + /** + * Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then + * creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created + * element. + * + * Assume the following html is stored in a file called `loginform.html`: + * + * ```html + * + * + * ``` + * + * Which is loaded into your game using the cache key 'login': + * + * ```javascript + * this.load.html('login', 'assets/loginform.html'); + * ``` + * + * You can create a DOM Element from it using the cache key: + * + * ```javascript + * this.add.dom().createFromCache('login'); + * ``` + * + * The optional `elementType` argument controls the container that is created, into which the loaded html is inserted. + * The default is a plain `div` object, but any valid tagName can be given. + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createFromCache + * @since 3.17.0 + * + * @param {string} The key of the html cache entry to use for this DOM Element. + * @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. + * + * @return {this} This DOM Element instance. + */ + createFromCache: function (key, tagName) + { + var html = this.cache.get(key); + + if (html) + { + this.createFromHTML(html, tagName); + } + + return this; + }, + + /** + * Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML` + * property of the created element. + * + * ```javascript + * let form = ` + * + * + * `; + * ``` + * + * You can create a DOM Element from it using the string: + * + * ```javascript + * this.add.dom().createFromHTML(form); + * ``` + * + * The optional `elementType` argument controls the type of container that is created, into which the html is inserted. + * The default is a plain `div` object, but any valid tagName can be given. + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createFromHTML + * @since 3.17.0 + * + * @param {string} A string of html to be set as the `innerHTML` property of the created element. + * @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. + * + * @return {this} This DOM Element instance. + */ + createFromHTML: function (html, tagName) + { + if (tagName === undefined) { tagName = 'div'; } + + // Already got an element? Remove it first + this.removeElement(); + + var element = document.createElement(tagName); + + this.node = element; + + element.style.zIndex = '0'; + element.style.display = 'inline'; + element.style.position = 'absolute'; + + // Node handler + + element.phaser = this; + + if (this.parent) + { + this.parent.appendChild(element); + } + + element.innerHTML = html; + + return this.updateSize(); + }, + + /** + * Removes the current DOM Element bound to this Game Object from the DOM entirely and resets the + * `node` property of this Game Object to be `null`. + * + * @method Phaser.GameObjects.DOMElement#removeElement + * @since 3.17.0 + * + * @return {this} This DOM Element instance. + */ + removeElement: function () + { + if (this.node) + { + RemoveFromDOM(this.node); + + this.node = null; + } + + return this; + }, + + /** + * Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width + * and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight` + * values into the `width` and `height` properties respectively. + * + * This is called automatically whenever a new element is created or set. + * + * @method Phaser.GameObjects.DOMElement#updateSize + * @since 3.17.0 + * + * @return {this} This DOM Element instance. + */ + updateSize: function () + { + var node = this.node; + + var nodeBounds = node.getBoundingClientRect(); + + this.width = node.clientWidth; + this.height = node.clientHeight; + + this.displayWidth = nodeBounds.width || 0; + this.displayHeight = nodeBounds.height || 0; + + return this; + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a property matching the given key and value. It then returns this child + * if found, or `null` if not. + * + * @method Phaser.GameObjects.DOMElement#getChildByProperty + * @since 3.17.0 + * + * @param {string} property - The property to search the children for. + * @param {string} value - The value the property must strictly equal. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByProperty: function (property, value) + { + if (this.node) + { + var children = this.node.querySelectorAll('*'); + + for (var i = 0; i < children.length; i++) + { + if (children[i][property] === value) + { + return children[i]; + } + } + } + + return null; + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not. + * + * Be aware that class and id names are case-sensitive. + * + * @method Phaser.GameObjects.DOMElement#getChildByID + * @since 3.17.0 + * + * @param {string} id - The id to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByID: function (id) + { + return this.getChildByProperty('id', id); + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not. + * + * Be aware that class and id names are case-sensitive. + * + * @method Phaser.GameObjects.DOMElement#getChildByName + * @since 3.17.0 + * + * @param {string} name - The name to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByName: function (name) + { + return this.getChildByProperty('name', name); + }, + + /** + * Sets the `className` property of the DOM Element node and updates the internal sizes. + * + * @method Phaser.GameObjects.DOMElement#setClassName + * @since 3.17.0 + * + * @param {string} className - A string representing the class or space-separated classes of the element. + * + * @return {this} This DOM Element instance. + */ + setClassName: function (className) + { + if (this.node) + { + this.node.className = className; + + this.updateSize(); + } + + return this; + }, + + /** + * Sets the `innerText` property of the DOM Element node and updates the internal sizes. + * + * Note that only certain types of Elements can have `innerText` set on them. + * + * @method Phaser.GameObjects.DOMElement#setText + * @since 3.17.0 + * + * @param {string} text - A DOMString representing the rendered text content of the element. + * + * @return {this} This DOM Element instance. + */ + setText: function (text) + { + if (this.node) + { + this.node.innerText = text; + + this.updateSize(); + } + + return this; + }, + + /** + * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. + * + * @method Phaser.GameObjects.DOMElement#setHTML + * @since 3.17.0 + * + * @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element. + * + * @return {this} This DOM Element instance. + */ + setHTML: function (html) + { + if (this.node) + { + this.node.innerHTML = html; + + this.updateSize(); + } + + return this; + }, + + /** + * Runs internal update tasks. + * + * @method Phaser.GameObjects.DOMElement#preUpdate + * @private + * @since 3.17.0 + */ + preUpdate: function () + { + var parent = this.parentContainer; + var node = this.node; + + if (node && parent && !parent.willRender()) + { + node.style.display = 'none'; + } + }, + + /** + * Compares the renderMask with the renderFlags to see if this Game Object will render or not. + * + * DOMElements always return `true` as they need to still set values during the render pass, even if not visible. + * + * @method Phaser.GameObjects.DOMElement#willRender + * @since 3.17.0 + * + * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. + */ + willRender: function () + { + return true; + }, + + /** + * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. + * + * @method Phaser.GameObjects.DOMElement#preDestroy + * @private + * @since 3.17.0 + */ + preDestroy: function () + { + this.removeElement(); + + this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); + this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + } + +}); + +module.exports = DOMElement; + + +/***/ }), +/* 437 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CSSBlendModes = __webpack_require__(1050); +var GameObject = __webpack_require__(15); +var TransformMatrix = __webpack_require__(25); + +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); + +/** + * 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.DOMElement#renderWebGL + * @since 3.17.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active renderer. + * @param {Phaser.GameObjects.DOMElement} 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 DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) +{ + var node = src.node; + var style = node.style; + var settings = src.scene.sys.settings; + + if (!node || !style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) + { + if (node) + { + style.display = 'none'; + } + + return; + } + + var parent = src.parentContainer; + var alpha = camera.alpha * src.alpha; + + if (parent) + { + alpha *= parent.alpha; + } + + var camMatrix = tempMatrix1; + var srcMatrix = tempMatrix2; + var calcMatrix = tempMatrix3; + + var dx = 0; + var dy = 0; + + var tx = '0%'; + var ty = '0%'; + + if (parentMatrix) + { + dx = (src.width * src.scaleX) * src.originX; + dy = (src.height * src.scaleY) * src.originY; + + srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); + + camMatrix.copyFrom(camera.matrix); + + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); + + // Undo the camera scroll + srcMatrix.e = src.x - dx; + srcMatrix.f = src.y - dy; + + // Multiply by the src matrix, store result in calcMatrix + camMatrix.multiply(srcMatrix, calcMatrix); + } + else + { + dx = (src.width) * src.originX; + dy = (src.height) * src.originY; + + srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); + + camMatrix.copyFrom(camera.matrix); + + tx = (100 * src.originX) + '%'; + ty = (100 * src.originY) + '%'; + + srcMatrix.e -= camera.scrollX * src.scrollFactorX; + srcMatrix.f -= camera.scrollY * src.scrollFactorY; + + // Multiply by the src matrix, store result in calcMatrix + camMatrix.multiply(srcMatrix, calcMatrix); + } + + if (!src.transformOnly) + { + style.display = 'block'; + style.opacity = alpha; + style.zIndex = src._depth; + style.pointerEvents = 'auto'; + style.mixBlendMode = CSSBlendModes[src._blendMode]; + } + + // https://developer.mozilla.org/en-US/docs/Web/CSS/transform + + style.transform = + calcMatrix.getCSSMatrix() + + ' skew(' + src.skewX + 'rad, ' + src.skewY + 'rad)' + + ' rotate3d(' + src.rotate3d.x + ',' + src.rotate3d.y + ',' + src.rotate3d.z + ',' + src.rotate3d.w + src.rotate3dAngle + ')'; + + style.transformOrigin = tx + ' ' + ty; +}; + +module.exports = DOMElementCSSRenderer; + + +/***/ }), +/* 438 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var GameObject = __webpack_require__(15); +var ExternRender = __webpack_require__(1054); + +/** + * @classdesc + * An Extern Game Object is a special type of Game Object that allows you to pass + * rendering off to a 3rd party. + * + * When you create an Extern and place it in the display list of a Scene, the renderer will + * process the list as usual. When it finds an Extern it will flush the current batch, + * clear down the pipeline and prepare a transform matrix which your render function can + * take advantage of, if required. + * + * The WebGL context is then left is a 'clean' state, ready for you to bind your own shaders, + * or draw to it, whatever you wish to do. Once you've finished, you should free-up any + * of your resources. The Extern will then rebind the Phaser pipeline and carry on + * rendering the display list. + * + * Although this object has lots of properties such as Alpha, Blend Mode and Tint, none of + * them are used during rendering unless you take advantage of them in your own render code. + * + * @class Extern + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.16.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Tint + * @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. + */ +var Extern = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.Origin, + Components.ScrollFactor, + Components.Size, + Components.Texture, + Components.Tint, + Components.Transform, + Components.Visible, + ExternRender + ], + + initialize: + + function Extern (scene) + { + GameObject.call(this, scene, 'Extern'); + }, + + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); + }, + + preUpdate: function () + { + // override this! + // Arguments: time, delta + }, + + render: function () + { + // override this! + // Arguments: renderer, camera, calcMatrix + } + +}); + +module.exports = Extern; + + +/***/ }), +/* 439 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircumferencePoint = __webpack_require__(215); +var FromPercent = __webpack_require__(95); +var MATH_CONST = __webpack_require__(14); +var Point = __webpack_require__(4); + +/** + * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse + * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point + * at 180 degrees around the circle. + * + * @function Phaser.Geom.Ellipse.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. + * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the ellipse. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. + */ +var GetPoint = function (ellipse, position, out) +{ + if (out === undefined) { out = new Point(); } + + var angle = FromPercent(position, 0, MATH_CONST.PI2); + + return CircumferencePoint(ellipse, angle, out); +}; + +module.exports = GetPoint; + + +/***/ }), +/* 440 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circumference = __webpack_require__(441); +var CircumferencePoint = __webpack_require__(215); +var FromPercent = __webpack_require__(95); +var MATH_CONST = __webpack_require__(14); + +/** + * Returns an array of Point objects containing the coordinates of the points around the circumference of the Ellipse, + * based on the given quantity or stepRate values. + * + * @function Phaser.Geom.Ellipse.GetPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the points from. + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the circumference of the ellipse and dividing it by the stepRate. + * @param {(array|Phaser.Geom.Point[])} [out] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse. + */ +var GetPoints = function (ellipse, 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 = Circumference(ellipse) / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); + + out.push(CircumferencePoint(ellipse, angle)); + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 441 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns the circumference of the given Ellipse. + * + * @function Phaser.Geom.Ellipse.Circumference + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference of. + * + * @return {number} The circumference of th Ellipse. + */ +var Circumference = function (ellipse) +{ + var rx = ellipse.width / 2; + var ry = ellipse.height / 2; + var h = Math.pow((rx - ry), 2) / Math.pow((rx + ry), 2); + + return (Math.PI * (rx + ry)) * (1 + ((3 * h) / (10 + Math.sqrt(4 - (3 * h))))); +}; + +module.exports = Circumference; + + +/***/ }), +/* 442 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Commands = __webpack_require__(214); +var SetTransform = __webpack_require__(30); + +/** + * 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.Graphics#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Graphics} 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 + * @param {CanvasRenderingContext2D} [renderTargetCtx] - The target rendering context. + * @param {boolean} allowClip - If `true` then path operations will be used instead of fill operations. + */ +var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) +{ + var commandBuffer = src.commandBuffer; + var commandBufferLength = commandBuffer.length; + + var ctx = renderTargetCtx || renderer.currentContext; + + if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + return; + } + + var lineAlpha = 1; + var fillAlpha = 1; + var lineColor = 0; + var fillColor = 0; + var lineWidth = 1; + var red = 0; + var green = 0; + var blue = 0; + + // Reset any currently active paths + ctx.beginPath(); + + for (var index = 0; index < commandBufferLength; ++index) + { + var commandID = commandBuffer[index]; + + switch (commandID) + { + case Commands.ARC: + ctx.arc( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4], + commandBuffer[index + 5], + commandBuffer[index + 6] + ); + + // +7 because overshoot is the 7th value, not used in Canvas + index += 7; + break; + + case Commands.LINE_STYLE: + lineWidth = commandBuffer[index + 1]; + lineColor = commandBuffer[index + 2]; + lineAlpha = commandBuffer[index + 3]; + red = ((lineColor & 0xFF0000) >>> 16); + green = ((lineColor & 0xFF00) >>> 8); + blue = (lineColor & 0xFF); + ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + lineAlpha + ')'; + ctx.lineWidth = lineWidth; + index += 3; + break; + + case Commands.FILL_STYLE: + fillColor = commandBuffer[index + 1]; + fillAlpha = commandBuffer[index + 2]; + red = ((fillColor & 0xFF0000) >>> 16); + green = ((fillColor & 0xFF00) >>> 8); + blue = (fillColor & 0xFF); + ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; + index += 2; + break; + + case Commands.BEGIN_PATH: + ctx.beginPath(); + break; + + case Commands.CLOSE_PATH: + ctx.closePath(); + break; + + case Commands.FILL_PATH: + if (!allowClip) + { + ctx.fill(); + } + break; + + case Commands.STROKE_PATH: + if (!allowClip) + { + ctx.stroke(); + } + break; + + case Commands.FILL_RECT: + if (!allowClip) + { + ctx.fillRect( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4] + ); + } + else + { + ctx.rect( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4] + ); + } + index += 4; + break; + + case Commands.FILL_TRIANGLE: + ctx.beginPath(); + ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); + ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); + ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); + ctx.closePath(); + if (!allowClip) + { + ctx.fill(); + } + index += 6; + break; + + case Commands.STROKE_TRIANGLE: + ctx.beginPath(); + ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); + ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); + ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); + ctx.closePath(); + if (!allowClip) + { + ctx.stroke(); + } + index += 6; + break; + + case Commands.LINE_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.MOVE_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.LINE_FX_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; + + case Commands.MOVE_FX_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; + + case Commands.SAVE: + ctx.save(); + break; + + case Commands.RESTORE: + ctx.restore(); + break; + + case Commands.TRANSLATE: + ctx.translate( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.SCALE: + ctx.scale( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.ROTATE: + ctx.rotate( + commandBuffer[index + 1] + ); + index += 1; + break; + + case Commands.GRADIENT_FILL_STYLE: + index += 5; + break; + + case Commands.GRADIENT_LINE_STYLE: + index += 6; + break; + } + } + + // Restore the context saved in SetTransform + ctx.restore(); +}; + +module.exports = GraphicsCanvasRenderer; + + +/***/ }), +/* 443 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var FloatBetween = __webpack_require__(135); +var GetEaseFunction = __webpack_require__(80); +var GetFastValue = __webpack_require__(2); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * A Particle Emitter property. + * + * Facilitates changing Particle properties as they are emitted and throughout their lifetime. + * + * @class EmitterOp + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for the Particle Emitter that owns this property. + * @param {string} key - The name of the property. + * @param {number} defaultValue - The default value of the property. + * @param {boolean} [emitOnly=false] - Whether the property can only be modified when a Particle is emitted. + */ +var EmitterOp = new Class({ + + initialize: + + function EmitterOp (config, key, defaultValue, emitOnly) + { + if (emitOnly === undefined) + { + emitOnly = false; + } + + /** + * The name of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#propertyKey + * @type {string} + * @since 3.0.0 + */ + this.propertyKey = key; + + /** + * The value of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue + * @type {number} + * @since 3.0.0 + */ + this.propertyValue = defaultValue; + + /** + * The default value of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue + * @type {number} + * @since 3.0.0 + */ + this.defaultValue = defaultValue; + + /** + * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. + * + * @name Phaser.GameObjects.Particles.EmitterOp#steps + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.steps = 0; + + /** + * The step counter for stepped easing, per emit. + * + * @name Phaser.GameObjects.Particles.EmitterOp#counter + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.counter = 0; + + /** + * The start value for this property to ease between. + * + * @name Phaser.GameObjects.Particles.EmitterOp#start + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.start = 0; + + /** + * The end value for this property to ease between. + * + * @name Phaser.GameObjects.Particles.EmitterOp#end + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.end = 0; + + /** + * The easing function to use for updating this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#ease + * @type {?function} + * @since 3.0.0 + */ + this.ease; + + /** + * Whether this property can only be modified when a Particle is emitted. + * + * Set to `true` to allow only {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} callbacks to be set and + * affect this property. + * + * Set to `false` to allow both {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks to be set and affect this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#emitOnly + * @type {boolean} + * @since 3.0.0 + */ + this.emitOnly = emitOnly; + + /** + * The callback to run for Particles when they are emitted from the Particle Emitter. + * + * @name Phaser.GameObjects.Particles.EmitterOp#onEmit + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback} + * @since 3.0.0 + */ + this.onEmit = this.defaultEmit; + + /** + * The callback to run for Particles when they are updated. + * + * @name Phaser.GameObjects.Particles.EmitterOp#onUpdate + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} + * @since 3.0.0 + */ + this.onUpdate = this.defaultUpdate; + + this.loadConfig(config); + }, + + /** + * Load the property from a Particle Emitter configuration object. + * + * Optionally accepts a new property key to use, replacing the current one. + * + * @method Phaser.GameObjects.Particles.EmitterOp#loadConfig + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Settings for the Particle Emitter that owns this property. + * @param {string} [newKey] - The new key to use for this property, if any. + */ + loadConfig: function (config, newKey) + { + if (config === undefined) + { + config = {}; + } + + if (newKey) + { + this.propertyKey = newKey; + } + + this.propertyValue = GetFastValue( + config, + this.propertyKey, + this.defaultValue + ); + + this.setMethods(); + + if (this.emitOnly) + { + // Reset it back again + this.onUpdate = this.defaultUpdate; + } + }, + + /** + * Build a JSON representation of this Particle Emitter property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#toJSON + * @since 3.0.0 + * + * @return {object} A JSON representation of this Particle Emitter property. + */ + toJSON: function () + { + return this.propertyValue; + }, + + /** + * Change the current value of the property and update its callback methods. + * + * @method Phaser.GameObjects.Particles.EmitterOp#onChange + * @since 3.0.0 + * + * @param {number} value - The value of the property. + * + * @return {this} This Emitter Op object. + */ + onChange: function (value) + { + this.propertyValue = value; + + return this.setMethods(); + }, + + /** + * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the type of the current + * {@link Phaser.GameObjects.Particles.EmitterOp#propertyValue}. + * + * @method Phaser.GameObjects.Particles.EmitterOp#setMethods + * @since 3.0.0 + * + * @return {this} This Emitter Op object. + */ + setMethods: function () + { + var value = this.propertyValue; + + var t = typeof value; + + // Reset them in case they're not changed below + this.onEmit = this.defaultEmit; + this.onUpdate = this.defaultUpdate; + + if (t === 'number') + { + // Explicit static value: + // x: 400 + + this.onEmit = this.staticValueEmit; + this.onUpdate = this.staticValueUpdate; // How? + } + else if (Array.isArray(value)) + { + // Picks a random element from the array: + // x: [ 100, 200, 300, 400 ] + + this.onEmit = this.randomStaticValueEmit; + } + else if (t === 'function') + { + // The same as setting just the onUpdate function and no onEmit (unless this op is an emitOnly one) + // Custom callback, must return a value: + + /* + x: function (particle, key, t, value) + { + return value + 50; + } + */ + + if (this.emitOnly) + { + this.onEmit = value; + } + else + { + this.onUpdate = value; + } + } + else if (t === 'object' && this.hasBoth(value, 'start', 'end')) + { + this.start = value.start; + this.end = value.end; + + // x: { start: 100, end: 400, random: true } (random optional) = eases between start and end + + var isRandom = this.has(value, 'random'); + + if (isRandom) + { + this.onEmit = this.randomRangedValueEmit; + } + + if (this.has(value, 'steps')) + { + // A stepped (per emit) range + + // x: { start: 100, end: 400, steps: 64 } + + // Increments a value stored in the emitter + + this.steps = value.steps; + this.counter = this.start; + + this.onEmit = this.steppedEmit; + } + else + { + // An eased range (defaults to Linear if not specified) + + // x: { start: 100, end: 400, [ ease: 'Linear' ] } + + var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; + + this.ease = GetEaseFunction(easeType, value.easeParams); + + if (!isRandom) + { + this.onEmit = this.easedValueEmit; + } + + this.onUpdate = this.easeValueUpdate; + } + } + else if (t === 'object' && this.hasBoth(value, 'min', 'max')) + { + // { min: 100, max: 400 } = pick a random number between min and max + + this.start = value.min; + this.end = value.max; + this.onEmit = this.randomRangedValueEmit; + } + else if (t === 'object' && this.has(value, 'random')) + { + // { random: [ 100, 400 ] } = pick a random number between the two elements of the array + + var rnd = value.random; + + if (Array.isArray(rnd)) + { + this.start = rnd[0]; + this.end = rnd[1]; + } + + this.onEmit = this.randomRangedValueEmit; + } + else if (t === 'object' && this.hasEither(value, 'onEmit', 'onUpdate')) + { + // Custom onEmit and onUpdate callbacks + + /* + x: { + // Called at the start of the particles life, when it is being created + onEmit: function (particle, key, t, value) + { + return value; + }, + + // Called during the particles life on each update + onUpdate: function (particle, key, t, value) + { + return value; + } + } + */ + + if (this.has(value, 'onEmit')) + { + this.onEmit = value.onEmit; + } + + if (this.has(value, 'onUpdate')) + { + this.onUpdate = value.onUpdate; + } + } + + return this; + }, + + /** + * Check whether an object has the given property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#has + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key - The key of the property to look for in the object. + * + * @return {boolean} `true` if the property exists in the object, `false` otherwise. + */ + has: function (object, key) + { + return object.hasOwnProperty(key); + }, + + /** + * Check whether an object has both of the given properties. + * + * @method Phaser.GameObjects.Particles.EmitterOp#hasBoth + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key1 - The key of the first property to check the object for. + * @param {string} key2 - The key of the second property to check the object for. + * + * @return {boolean} `true` if both properties exist in the object, `false` otherwise. + */ + hasBoth: function (object, key1, key2) + { + return object.hasOwnProperty(key1) && object.hasOwnProperty(key2); + }, + + /** + * Check whether an object has at least one of the given properties. + * + * @method Phaser.GameObjects.Particles.EmitterOp#hasEither + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key1 - The key of the first property to check the object for. + * @param {string} key2 - The key of the second property to check the object for. + * + * @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist. + */ + hasEither: function (object, key1, key2) + { + return object.hasOwnProperty(key1) || object.hasOwnProperty(key2); + }, + + /** + * The returned value sets what the property will be at the START of the particles life, on emit. + * + * @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} [value] - The current value of the property. + * + * @return {number} The new value of the property. + */ + defaultEmit: function (particle, key, value) + { + return value; + }, + + /** + * The returned value updates the property for the duration of the particles life. + * + * @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The T value (between 0 and 1) + * @param {number} value - The current value of the property. + * + * @return {number} The new value of the property. + */ + defaultUpdate: function (particle, key, t, value) + { + return value; + }, + + /** + * An `onEmit` callback that returns the current value of the property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit + * @since 3.0.0 + * + * @return {number} The current value of the property. + */ + staticValueEmit: function () + { + return this.propertyValue; + }, + + /** + * An `onUpdate` callback that returns the current value of the property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate + * @since 3.0.0 + * + * @return {number} The current value of the property. + */ + staticValueUpdate: function () + { + return this.propertyValue; + }, + + /** + * An `onEmit` callback that returns a random value from the current value array. + * + * @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit + * @since 3.0.0 + * + * @return {number} The new value of the property. + */ + randomStaticValueEmit: function () + { + var randomIndex = Math.floor(Math.random() * this.propertyValue.length); + + return this.propertyValue[randomIndex]; + }, + + /** + * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The key of the property. + * + * @return {number} The new value of the property. + */ + randomRangedValueEmit: function (particle, key) + { + var value = FloatBetween(this.start, this.end); + + if (particle && particle.data[key]) + { + particle.data[key].min = value; + } + + return value; + }, + + /** + * An `onEmit` callback that returns a stepped value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit + * @since 3.0.0 + * + * @return {number} The new value of the property. + */ + steppedEmit: function () + { + var current = this.counter; + + var next = this.counter + (this.end - this.start) / this.steps; + + this.counter = Wrap(next, this.start, this.end); + + return current; + }, + + /** + * An `onEmit` callback for an eased property. + * + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. + * + * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * + * @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property. + */ + easedValueEmit: function (particle, key) + { + if (particle && particle.data[key]) + { + var data = particle.data[key]; + + data.min = this.start; + data.max = this.end; + } + + return this.start; + }, + + /** + * An `onUpdate` callback that returns an eased value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The T value (between 0 and 1) + * + * @return {number} The new value of the property. + */ + easeValueUpdate: function (particle, key, t) + { + var data = particle.data[key]; + + return (data.max - data.min) * this.ease(t) + data.min; + } +}); + +module.exports = EmitterOp; + + +/***/ }), +/* 444 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * The GravityWell action applies a force on the particle to draw it towards, or repel it from, a single point. + * + * The force applied is inversely proportional to the square of the distance from the particle to the point, in accordance with Newton's law of gravity. + * + * This simulates the effect of gravity over large distances (as between planets, for example). + * + * @class GravityWell + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {(number|Phaser.Types.GameObjects.Particles.GravityWellConfig)} [x=0] - The x coordinate of the Gravity Well, in world space. + * @param {number} [y=0] - The y coordinate of the Gravity Well, in world space. + * @param {number} [power=0] - The strength of the gravity force - larger numbers produce a stronger force. + * @param {number} [epsilon=100] - The minimum distance for which the gravity force is calculated. + * @param {number} [gravity=50] - The gravitational force of this Gravity Well. + */ +var GravityWell = new Class({ + + initialize: + + function GravityWell (x, y, power, epsilon, gravity) + { + if (typeof x === 'object') + { + var config = x; + + x = GetFastValue(config, 'x', 0); + y = GetFastValue(config, 'y', 0); + power = GetFastValue(config, 'power', 0); + epsilon = GetFastValue(config, 'epsilon', 100); + gravity = GetFastValue(config, 'gravity', 50); + } + else + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (power === undefined) { power = 0; } + if (epsilon === undefined) { epsilon = 100; } + if (gravity === undefined) { gravity = 50; } + } + + /** + * The x coordinate of the Gravity Well, in world space. + * + * @name Phaser.GameObjects.Particles.GravityWell#x + * @type {number} + * @since 3.0.0 + */ + this.x = x; + + /** + * The y coordinate of the Gravity Well, in world space. + * + * @name Phaser.GameObjects.Particles.GravityWell#y + * @type {number} + * @since 3.0.0 + */ + this.y = y; + + /** + * The active state of the Gravity Well. An inactive Gravity Well will not influence any particles. + * + * @name Phaser.GameObjects.Particles.GravityWell#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Internal gravity value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_gravity + * @type {number} + * @private + * @since 3.0.0 + */ + this._gravity = gravity; + + /** + * Internal power value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_power + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._power = 0; + + /** + * Internal epsilon value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_epsilon + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._epsilon = 0; + + /** + * The strength of the gravity force - larger numbers produce a stronger force. + * + * @name Phaser.GameObjects.Particles.GravityWell#power + * @type {number} + * @since 3.0.0 + */ + this.power = power; + + /** + * The minimum distance for which the gravity force is calculated. + * + * @name Phaser.GameObjects.Particles.GravityWell#epsilon + * @type {number} + * @since 3.0.0 + */ + this.epsilon = epsilon; + }, + + /** + * Takes a Particle and updates it based on the properties of this Gravity Well. + * + * @method Phaser.GameObjects.Particles.GravityWell#update + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update. + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + */ + update: function (particle, delta) + { + var x = this.x - particle.x; + var y = this.y - particle.y; + var dSq = x * x + y * y; + + if (dSq === 0) + { + return; + } + + var d = Math.sqrt(dSq); + + if (dSq < this._epsilon) + { + dSq = this._epsilon; + } + + var factor = ((this._power * delta) / (dSq * d)) * 100; + + particle.velocityX += x * factor; + particle.velocityY += y * factor; + }, + + epsilon: { + + get: function () + { + return Math.sqrt(this._epsilon); + }, + + set: function (value) + { + this._epsilon = value * value; + } + + }, + + power: { + + get: function () + { + return this._power / this._gravity; + }, + + set: function (value) + { + this._power = value * this._gravity; + } + + }, + + gravity: { + + get: function () + { + return this._gravity; + }, + + set: function (value) + { + var pwr = this.power; + this._gravity = value; + this.power = pwr; + } + + } + +}); + +module.exports = GravityWell; + + +/***/ }), +/* 445 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var DistanceBetween = __webpack_require__(48); + +/** + * @classdesc + * A Particle is a simple Game Object controlled by a Particle Emitter and Manager, and rendered by the Manager. + * It uses its own lightweight physics system, and can interact only with its Emitter's bounds and zones. + * + * @class Particle + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. + */ +var Particle = new Class({ + + initialize: + + function Particle (emitter) + { + /** + * The Emitter to which this Particle belongs. + * + * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. + * + * @name Phaser.GameObjects.Particles.Particle#emitter + * @type {Phaser.GameObjects.Particles.ParticleEmitter} + * @since 3.0.0 + */ + this.emitter = emitter; + + /** + * The texture frame used to render this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#frame + * @type {Phaser.Textures.Frame} + * @default null + * @since 3.0.0 + */ + this.frame = null; + + /** + * The x coordinate of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; + + /** + * The y coordinate of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; + + /** + * The x velocity of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#velocityX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.velocityX = 0; + + /** + * The y velocity of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#velocityY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.velocityY = 0; + + /** + * The x acceleration of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#accelerationX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.accelerationX = 0; + + /** + * The y acceleration of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#accelerationY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.accelerationY = 0; + + /** + * The maximum horizontal velocity this Particle can travel at. + * + * @name Phaser.GameObjects.Particles.Particle#maxVelocityX + * @type {number} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityX = 10000; + + /** + * The maximum vertical velocity this Particle can travel at. + * + * @name Phaser.GameObjects.Particles.Particle#maxVelocityY + * @type {number} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityY = 10000; + + /** + * The bounciness, or restitution, of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#bounce + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.bounce = 0; + + /** + * The horizontal scale of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#scaleX + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.scaleX = 1; + + /** + * The vertical scale of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#scaleY + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.scaleY = 1; + + /** + * The alpha value of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#alpha + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.alpha = 1; + + /** + * The angle of this Particle in degrees. + * + * @name Phaser.GameObjects.Particles.Particle#angle + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angle = 0; + + /** + * The angle of this Particle in radians. + * + * @name Phaser.GameObjects.Particles.Particle#rotation + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.rotation = 0; + + /** + * The tint applied to this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#tint + * @type {number} + * @webglOnly + * @since 3.0.0 + */ + this.tint = 0xffffff; + + /** + * The lifespan of this Particle in ms. + * + * @name Phaser.GameObjects.Particles.Particle#life + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.life = 1000; + + /** + * The current life of this Particle in ms. + * + * @name Phaser.GameObjects.Particles.Particle#lifeCurrent + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.lifeCurrent = 1000; + + /** + * The delay applied to this Particle upon emission, in ms. + * + * @name Phaser.GameObjects.Particles.Particle#delayCurrent + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.delayCurrent = 0; + + /** + * The normalized lifespan T value, where 0 is the start and 1 is the end. + * + * @name Phaser.GameObjects.Particles.Particle#lifeT + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lifeT = 0; + + /** + * The data used by the ease equation. + * + * @name Phaser.GameObjects.Particles.Particle#data + * @type {object} + * @since 3.0.0 + */ + this.data = { + tint: { min: 0xffffff, max: 0xffffff, current: 0xffffff }, + alpha: { min: 1, max: 1 }, + rotate: { min: 0, max: 0 }, + scaleX: { min: 1, max: 1 }, + scaleY: { min: 1, max: 1 } + }; + }, + + /** + * Checks to see if this Particle is alive and updating. + * + * @method Phaser.GameObjects.Particles.Particle#isAlive + * @since 3.0.0 + * + * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. + */ + isAlive: function () + { + return (this.lifeCurrent > 0); + }, + + /** + * Resets the position of this particle back to zero. + * + * @method Phaser.GameObjects.Particles.Particle#resetPosition + * @since 3.16.0 + */ + resetPosition: function () + { + this.x = 0; + this.y = 0; + }, + + /** + * Starts this Particle from the given coordinates. + * + * @method Phaser.GameObjects.Particles.Particle#fire + * @since 3.0.0 + * + * @param {number} x - The x coordinate to launch this Particle from. + * @param {number} y - The y coordinate to launch this Particle from. + */ + fire: function (x, y) + { + var emitter = this.emitter; + + this.frame = emitter.getFrame(); + + if (emitter.emitZone) + { + // Updates particle.x and particle.y during this call + emitter.emitZone.getPoint(this); + } + + if (x === undefined) + { + this.x += emitter.x.onEmit(this, 'x'); + } + else + { + this.x += x; + } + + if (y === undefined) + { + this.y += emitter.y.onEmit(this, 'y'); + } + else + { + this.y += y; + } + + this.life = emitter.lifespan.onEmit(this, 'lifespan'); + this.lifeCurrent = this.life; + this.lifeT = 0; + + var sx = emitter.speedX.onEmit(this, 'speedX'); + var sy = (emitter.speedY) ? emitter.speedY.onEmit(this, 'speedY') : sx; + + if (emitter.radial) + { + var rad = DegToRad(emitter.angle.onEmit(this, 'angle')); + + this.velocityX = Math.cos(rad) * Math.abs(sx); + this.velocityY = Math.sin(rad) * Math.abs(sy); + } + else if (emitter.moveTo) + { + var mx = emitter.moveToX.onEmit(this, 'moveToX'); + var my = (emitter.moveToY) ? emitter.moveToY.onEmit(this, 'moveToY') : mx; + + var angle = Math.atan2(my - this.y, mx - this.x); + + var speed = DistanceBetween(this.x, this.y, mx, my) / (this.life / 1000); + + // We know how many pixels we need to move, but how fast? + // var speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000); + + this.velocityX = Math.cos(angle) * speed; + this.velocityY = Math.sin(angle) * speed; + } + else + { + this.velocityX = sx; + this.velocityY = sy; + } + + if (emitter.acceleration) + { + this.accelerationX = emitter.accelerationX.onEmit(this, 'accelerationX'); + this.accelerationY = emitter.accelerationY.onEmit(this, 'accelerationY'); + } + + this.maxVelocityX = emitter.maxVelocityX.onEmit(this, 'maxVelocityX'); + this.maxVelocityY = emitter.maxVelocityY.onEmit(this, 'maxVelocityY'); + + this.delayCurrent = emitter.delay.onEmit(this, 'delay'); + + this.scaleX = emitter.scaleX.onEmit(this, 'scaleX'); + this.scaleY = (emitter.scaleY) ? emitter.scaleY.onEmit(this, 'scaleY') : this.scaleX; + + this.angle = emitter.rotate.onEmit(this, 'rotate'); + this.rotation = DegToRad(this.angle); + + this.bounce = emitter.bounce.onEmit(this, 'bounce'); + + this.alpha = emitter.alpha.onEmit(this, 'alpha'); + + this.tint = emitter.tint.onEmit(this, 'tint'); + }, + + /** + * An internal method that calculates the velocity of the Particle. + * + * @method Phaser.GameObjects.Particles.Particle#computeVelocity + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle. + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + * @param {array} processors - Particle processors (gravity wells). + */ + computeVelocity: function (emitter, delta, step, processors) + { + var vx = this.velocityX; + var vy = this.velocityY; + + var ax = this.accelerationX; + var ay = this.accelerationY; + + var mx = this.maxVelocityX; + var my = this.maxVelocityY; + + vx += (emitter.gravityX * step); + vy += (emitter.gravityY * step); + + if (ax) + { + vx += (ax * step); + } + + if (ay) + { + vy += (ay * step); + } + + if (vx > mx) + { + vx = mx; + } + else if (vx < -mx) + { + vx = -mx; + } + + if (vy > my) + { + vy = my; + } + else if (vy < -my) + { + vy = -my; + } + + this.velocityX = vx; + this.velocityY = vy; + + // Apply any additional processors + for (var i = 0; i < processors.length; i++) + { + processors[i].update(this, delta, step); + } + }, + + /** + * Checks if this Particle is still within the bounds defined by the given Emitter. + * + * If not, and depending on the Emitter collision flags, the Particle may either stop or rebound. + * + * @method Phaser.GameObjects.Particles.Particle#checkBounds + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against. + */ + checkBounds: function (emitter) + { + var bounds = emitter.bounds; + var bounce = -this.bounce; + + if (this.x < bounds.x && emitter.collideLeft) + { + this.x = bounds.x; + this.velocityX *= bounce; + } + else if (this.x > bounds.right && emitter.collideRight) + { + this.x = bounds.right; + this.velocityX *= bounce; + } + + if (this.y < bounds.y && emitter.collideTop) + { + this.y = bounds.y; + this.velocityY *= bounce; + } + else if (this.y > bounds.bottom && emitter.collideBottom) + { + this.y = bounds.bottom; + this.velocityY *= bounce; + } + }, + + /** + * The main update method for this Particle. + * + * Updates its life values, computes the velocity and repositions the Particle. + * + * @method Phaser.GameObjects.Particles.Particle#update + * @since 3.0.0 + * + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + * @param {array} processors - An optional array of update processors. + * + * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. + */ + update: function (delta, step, processors) + { + if (this.delayCurrent > 0) + { + this.delayCurrent -= delta; + + return false; + } + + var emitter = this.emitter; + + // How far along in life is this particle? (t = 0 to 1) + var t = 1 - (this.lifeCurrent / this.life); + + this.lifeT = t; + + this.computeVelocity(emitter, delta, step, processors); + + this.x += this.velocityX * step; + this.y += this.velocityY * step; + + if (emitter.bounds) + { + this.checkBounds(emitter); + } + + if (emitter.deathZone && emitter.deathZone.willKill(this)) + { + this.lifeCurrent = 0; + + // No need to go any further, particle has been killed + return true; + } + + this.scaleX = emitter.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); + + if (emitter.scaleY) + { + this.scaleY = emitter.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); + } + else + { + this.scaleY = this.scaleX; + } + + this.angle = emitter.rotate.onUpdate(this, 'rotate', t, this.angle); + this.rotation = DegToRad(this.angle); + + this.alpha = emitter.alpha.onUpdate(this, 'alpha', t, this.alpha); + + this.tint = emitter.tint.onUpdate(this, 'tint', t, this.tint); + + this.lifeCurrent -= delta; + + return (this.lifeCurrent <= 0); + } + +}); + +module.exports = Particle; + + +/***/ }), +/* 446 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BlendModes = __webpack_require__(33); +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var DeathZone = __webpack_require__(447); +var EdgeZone = __webpack_require__(448); +var EmitterOp = __webpack_require__(443); +var GetFastValue = __webpack_require__(2); +var GetRandom = __webpack_require__(207); +var HasAny = __webpack_require__(449); +var HasValue = __webpack_require__(125); +var Particle = __webpack_require__(445); +var RandomZone = __webpack_require__(450); +var Rectangle = __webpack_require__(10); +var StableSort = __webpack_require__(79); +var Vector2 = __webpack_require__(3); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * A particle emitter represents a single particle stream. + * It controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles} and is controlled by a {@link Phaser.GameObjects.Particles.ParticleEmitterManager Particle Emitter Manager}. + * + * @class ParticleEmitter + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} manager - The Emitter Manager this Emitter belongs to. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + */ +var ParticleEmitter = new Class({ + + Mixins: [ + Components.BlendMode, + Components.Mask, + Components.ScrollFactor, + Components.Visible + ], + + initialize: + + function ParticleEmitter (manager, config) + { + /** + * The Emitter Manager this Emitter belongs to. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#manager + * @type {Phaser.GameObjects.Particles.ParticleEmitterManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * The texture assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#texture + * @type {Phaser.Textures.Texture} + * @since 3.0.0 + */ + this.texture = manager.texture; + + /** + * The texture frames assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frames + * @type {Phaser.Textures.Frame[]} + * @since 3.0.0 + */ + this.frames = [ manager.defaultFrame ]; + + /** + * The default texture frame assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#defaultFrame + * @type {Phaser.Textures.Frame} + * @since 3.0.0 + */ + this.defaultFrame = manager.defaultFrame; + + /** + * Names of simple configuration properties. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#configFastMap + * @type {object} + * @since 3.0.0 + */ + this.configFastMap = [ + 'active', + 'blendMode', + 'collideBottom', + 'collideLeft', + 'collideRight', + 'collideTop', + 'deathCallback', + 'deathCallbackScope', + 'emitCallback', + 'emitCallbackScope', + 'follow', + 'frequency', + 'gravityX', + 'gravityY', + 'maxParticles', + 'name', + 'on', + 'particleBringToTop', + 'particleClass', + 'radial', + 'timeScale', + 'trackVisible', + 'visible' + ]; + + /** + * Names of complex configuration properties. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#configOpMap + * @type {object} + * @since 3.0.0 + */ + this.configOpMap = [ + 'accelerationX', + 'accelerationY', + 'angle', + 'alpha', + 'bounce', + 'delay', + 'lifespan', + 'maxVelocityX', + 'maxVelocityY', + 'moveToX', + 'moveToY', + 'quantity', + 'rotate', + 'scaleX', + 'scaleY', + 'speedX', + 'speedY', + 'tint', + 'x', + 'y' + ]; + + /** + * The name of this Particle Emitter. + * + * Empty by default and never populated by Phaser, this is left for developers to use. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#name + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.name = ''; + + /** + * The Particle Class which will be emitted by this Emitter. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass + * @type {Phaser.GameObjects.Particles.Particle} + * @default Phaser.GameObjects.Particles.Particle + * @since 3.0.0 + */ + this.particleClass = Particle; + + /** + * The x-coordinate of the particle origin (where particles will be emitted). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#x + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + */ + this.x = new EmitterOp(config, 'x', 0, true); + + /** + * The y-coordinate of the particle origin (where particles will be emitted). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#y + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + */ + this.y = new EmitterOp(config, 'y', 0, true); + + /** + * A radial emitter will emit particles in all directions between angle min and max, + * using {@link Phaser.GameObjects.Particles.ParticleEmitter#speed} as the value. If set to false then this acts as a point Emitter. + * A point emitter will emit particles only in the direction derived from the speedX and speedY values. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#radial + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial + */ + this.radial = true; + + /** + * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + */ + this.gravityX = 0; + + /** + * Vertical acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + */ + this.gravityY = 0; + + /** + * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#acceleration + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.acceleration = false; + + /** + * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.accelerationX = new EmitterOp(config, 'accelerationX', 0, true); + + /** + * Vertical acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.accelerationY = new EmitterOp(config, 'accelerationY', 0, true); + + /** + * The maximum horizontal velocity of emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityX = new EmitterOp(config, 'maxVelocityX', 10000, true); + + /** + * The maximum vertical velocity of emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityY = new EmitterOp(config, 'maxVelocityY', 10000, true); + + /** + * The initial horizontal speed of emitted particles, in pixels per second. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX + */ + this.speedX = new EmitterOp(config, 'speedX', 0, true); + + /** + * The initial vertical speed of emitted particles, in pixels per second. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY + */ + this.speedY = new EmitterOp(config, 'speedY', 0, true); + + /** + * Whether moveToX and moveToY are nonzero. Set automatically during configuration. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveTo + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.moveTo = false; + + /** + * The x-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.moveToX = new EmitterOp(config, 'moveToX', 0, true); + + /** + * The y-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.moveToY = new EmitterOp(config, 'moveToY', 0, true); + + /** + * Whether particles will rebound when they meet the emitter bounds. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#bounce + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.bounce = new EmitterOp(config, 'bounce', 0, true); + + /** + * The horizontal scale of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleX + */ + this.scaleX = new EmitterOp(config, 'scaleX', 1); + + /** + * The vertical scale of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleY + */ + this.scaleY = new EmitterOp(config, 'scaleY', 1); + + /** + * Color tint applied to emitted particles. Value must not include the alpha channel. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#tint + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0xffffff + * @since 3.0.0 + */ + this.tint = new EmitterOp(config, 'tint', 0xffffff); + + /** + * The alpha (transparency) of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#alpha + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAlpha + */ + this.alpha = new EmitterOp(config, 'alpha', 1); + + /** + * The lifespan of emitted particles, in ms. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1000 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setLifespan + */ + this.lifespan = new EmitterOp(config, 'lifespan', 1000, true); + + /** + * The angle of the initial velocity of emitted particles, in degrees. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#angle + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default { min: 0, max: 360 } + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAngle + */ + this.angle = new EmitterOp(config, 'angle', { min: 0, max: 360 }, true); + + /** + * The rotation of emitted particles, in degrees. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#rotate + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.rotate = new EmitterOp(config, 'rotate', 0); + + /** + * A function to call when a particle is emitted. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} + * @default null + * @since 3.0.0 + */ + this.emitCallback = null; + + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 + */ + this.emitCallbackScope = null; + + /** + * A function to call when a particle dies. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleDeathCallback} + * @default null + * @since 3.0.0 + */ + this.deathCallback = null; + + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 + */ + this.deathCallbackScope = null; + + /** + * Set to hard limit the amount of particle objects this emitter is allowed to create. + * 0 means unlimited. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxParticles + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxParticles = 0; + + /** + * How many particles are emitted each time particles are emitted (one explosion or one flow cycle). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#quantity + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + */ + this.quantity = new EmitterOp(config, 'quantity', 1, true); + + /** + * How many ms to wait after emission before the particles start updating. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#delay + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.delay = new EmitterOp(config, 'delay', 0, true); + + /** + * For a flow emitter, the time interval (>= 0) between particle flow cycles in ms. + * A value of 0 means there is one particle flow cycle for each logic update (the maximum flow frequency). This is the default setting. + * For an exploding emitter, this value will be -1. + * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} also puts the emitter in flow mode (frequency >= 0). + * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} also puts the emitter in explode mode (frequency = -1). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frequency + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + */ + this.frequency = 0; + + /** + * Controls if the emitter is currently emitting a particle flow (when frequency >= 0). + * Already alive particles will continue to update until they expire. + * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#start} and {@link Phaser.GameObjects.Particles.ParticleEmitter#stop}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#on + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.on = true; + + /** + * Newly emitted particles are added to the top of the particle list, i.e. rendered above those already alive. + * Set to false to send them to the back. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.particleBringToTop = true; + + /** + * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * An object describing a shape to emit particles from. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitZone + * @type {?Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone + */ + this.emitZone = null; + + /** + * An object describing a shape that deactivates particles when they interact with it. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathZone + * @type {?Phaser.GameObjects.Particles.Zones.DeathZone} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone + */ + this.deathZone = null; + + /** + * A rectangular boundary constraining particle movement. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#bounds + * @type {?Phaser.Geom.Rectangle} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setBounds + */ + this.bounds = null; + + /** + * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideLeft + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideLeft = true; + + /** + * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideRight + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideRight = true; + + /** + * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideTop + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideTop = true; + + /** + * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideBottom + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideBottom = true; + + /** + * Whether this emitter updates itself and its particles. + * + * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#pause} + * and {@link Phaser.GameObjects.Particles.ParticleEmitter#resume}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Set this to false to hide any active particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#visible + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setVisible + */ + this.visible = true; + + /** + * The blend mode of this emitter's particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#blendMode + * @type {number} + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setBlendMode + */ + this.blendMode = BlendModes.NORMAL; + + /** + * A Game Object whose position is used as the particle origin. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#follow + * @type {?Phaser.GameObjects.GameObject} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + * @see Phaser.GameObjects.Particles.ParticleEmitter#stopFollow + */ + this.follow = null; + + /** + * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#followOffset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + */ + this.followOffset = new Vector2(); + + /** + * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track + * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#trackVisible + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + */ + this.trackVisible = false; + + /** + * The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.currentFrame = 0; + + /** + * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#randomFrame + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.randomFrame = true; + + /** + * The number of consecutive particles that receive a single texture frame (per frame cycle). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity + * @type {number} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.frameQuantity = 1; + + /** + * Inactive particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#dead + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.dead = []; + + /** + * Active particles + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#alive + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.alive = []; + + /** + * The time until the next flow cycle. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#_counter + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._counter = 0; + + /** + * Counts up to {@link Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#_frameCounter + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._frameCounter = 0; + + if (config) + { + this.fromJSON(config); + } + }, + + /** + * Merges configuration settings into the emitter's current settings. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + * + * @return {this} This Particle Emitter. + */ + fromJSON: function (config) + { + if (!config) + { + return this; + } + + // Only update properties from their current state if they exist in the given config + + var i = 0; + var key = ''; + + for (i = 0; i < this.configFastMap.length; i++) + { + key = this.configFastMap[i]; + + if (HasValue(config, key)) + { + this[key] = GetFastValue(config, key); + } + } + + for (i = 0; i < this.configOpMap.length; i++) + { + key = this.configOpMap[i]; + + if (HasValue(config, key)) + { + this[key].loadConfig(config); + } + } + + this.acceleration = (this.accelerationX.propertyValue !== 0 || this.accelerationY.propertyValue !== 0); + + this.moveTo = (this.moveToX.propertyValue !== 0 || this.moveToY.propertyValue !== 0); + + // Special 'speed' override + + if (HasValue(config, 'speed')) + { + this.speedX.loadConfig(config, 'speed'); + this.speedY = null; + } + + // If you specify speedX, speedY or moveTo then it changes the emitter from radial to a point emitter + if (HasAny(config, [ 'speedX', 'speedY' ]) || this.moveTo) + { + this.radial = false; + } + + // Special 'scale' override + + if (HasValue(config, 'scale')) + { + this.scaleX.loadConfig(config, 'scale'); + this.scaleY = null; + } + + if (HasValue(config, 'callbackScope')) + { + var callbackScope = GetFastValue(config, 'callbackScope', null); + + this.emitCallbackScope = callbackScope; + this.deathCallbackScope = callbackScope; + } + + if (HasValue(config, 'emitZone')) + { + this.setEmitZone(config.emitZone); + } + + if (HasValue(config, 'deathZone')) + { + this.setDeathZone(config.deathZone); + } + + if (HasValue(config, 'bounds')) + { + this.setBounds(config.bounds); + } + + if (HasValue(config, 'followOffset')) + { + this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); + } + + if (HasValue(config, 'frame')) + { + this.setFrame(config.frame); + } + + if (HasValue(config, 'reserve')) + { + this.reserve(config.reserve); + } + + return this; + }, + + /** + * Creates a description of this emitter suitable for JSON serialization. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON + * @since 3.0.0 + * + * @param {object} [output] - An object to copy output into. + * + * @return {object} - The output object. + */ + toJSON: function (output) + { + if (output === undefined) { output = {}; } + + var i = 0; + var key = ''; + + for (i = 0; i < this.configFastMap.length; i++) + { + key = this.configFastMap[i]; + + output[key] = this[key]; + } + + for (i = 0; i < this.configOpMap.length; i++) + { + key = this.configOpMap[i]; + + if (this[key]) + { + output[key] = this[key].toJSON(); + } + } + + // special handlers + if (!this.speedY) + { + delete output.speedX; + output.speed = this.speedX.toJSON(); + } + + if (!this.scaleY) + { + delete output.scaleX; + output.scale = this.scaleX.toJSON(); + } + + return output; + }, + + /** + * Continuously moves the particle origin to follow a Game Object's position. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} target - The Game Object to follow. + * @param {number} [offsetX=0] - Horizontal offset of the particle origin from the Game Object. + * @param {number} [offsetY=0] - Vertical offset of the particle origin from the Game Object. + * @param {boolean} [trackVisible=false] - Whether the emitter's visible state will track the target's visible state. + * + * @return {this} This Particle Emitter. + */ + startFollow: function (target, offsetX, offsetY, trackVisible) + { + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } + if (trackVisible === undefined) { trackVisible = false; } + + this.follow = target; + this.followOffset.set(offsetX, offsetY); + this.trackVisible = trackVisible; + + return this; + }, + + /** + * Stops following a Game Object. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + stopFollow: function () + { + this.follow = null; + this.followOffset.set(0, 0); + this.trackVisible = false; + + return this; + }, + + /** + * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame + * @since 3.0.0 + * + * @return {Phaser.Textures.Frame} The texture frame. + */ + getFrame: function () + { + if (this.frames.length === 1) + { + return this.defaultFrame; + } + else if (this.randomFrame) + { + return GetRandom(this.frames); + } + else + { + var frame = this.frames[this.currentFrame]; + + this._frameCounter++; + + if (this._frameCounter === this.frameQuantity) + { + this._frameCounter = 0; + this.currentFrame = Wrap(this.currentFrame + 1, 0, this._frameLength); + } + + return frame; + } + }, + + // frame: 0 + // frame: 'red' + // frame: [ 0, 1, 2, 3 ] + // frame: [ 'red', 'green', 'blue', 'pink', 'white' ] + // frame: { frames: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } + + /** + * Sets a pattern for assigning texture frames to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrame + * @since 3.0.0 + * + * @param {(array|string|number|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} frames - One or more texture frames, or a configuration object. + * @param {boolean} [pickRandom=true] - Whether frames should be assigned at random from `frames`. + * @param {number} [quantity=1] - The number of consecutive particles that will receive each frame. + * + * @return {this} This Particle Emitter. + */ + setFrame: function (frames, pickRandom, quantity) + { + if (pickRandom === undefined) { pickRandom = true; } + if (quantity === undefined) { quantity = 1; } + + this.randomFrame = pickRandom; + this.frameQuantity = quantity; + this.currentFrame = 0; + this._frameCounter = 0; + + var t = typeof (frames); + + if (Array.isArray(frames) || t === 'string' || t === 'number') + { + this.manager.setEmitterFrames(frames, this); + } + else if (t === 'object') + { + var frameConfig = frames; + + frames = GetFastValue(frameConfig, 'frames', null); + + if (frames) + { + this.manager.setEmitterFrames(frames, this); + } + + var isCycle = GetFastValue(frameConfig, 'cycle', false); + + this.randomFrame = (isCycle) ? false : true; + + this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); + } + + this._frameLength = this.frames.length; + + if (this._frameLength === 1) + { + this.frameQuantity = 1; + this.randomFrame = false; + } + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial + * @since 3.0.0 + * + * @param {boolean} [value=true] - Radial mode (true) or point mode (true). + * + * @return {this} This Particle Emitter. + */ + setRadial: function (value) + { + if (value === undefined) { value = true; } + + this.radial = value; + + return this; + }, + + /** + * Sets the position of the emitter's particle origin. + * New particles will be emitted here. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setPosition + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} x - The x-coordinate of the particle origin. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} y - The y-coordinate of the particle origin. + * + * @return {this} This Particle Emitter. + */ + setPosition: function (x, y) + { + this.x.onChange(x); + this.y.onChange(y); + + return this; + }, + + /** + * Sets or modifies a rectangular boundary constraining the particles. + * + * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setBounds + * @since 3.0.0 + * + * @param {(number|Phaser.Types.GameObjects.Particles.ParticleEmitterBounds|Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt)} x - The x-coordinate of the left edge of the boundary, or an object representing a rectangle. + * @param {number} y - The y-coordinate of the top edge of the boundary. + * @param {number} width - The width of the boundary. + * @param {number} height - The height of the boundary. + * + * @return {this} This Particle Emitter. + */ + setBounds: function (x, y, width, height) + { + if (typeof x === 'object') + { + var obj = x; + + x = obj.x; + y = obj.y; + width = (HasValue(obj, 'w')) ? obj.w : obj.width; + height = (HasValue(obj, 'h')) ? obj.h : obj.height; + } + + if (this.bounds) + { + this.bounds.setTo(x, y, width, height); + } + else + { + this.bounds = new Rectangle(x, y, width, height); + } + + return this; + }, + + /** + * Sets the initial horizontal speed of emitted particles. + * Changes the emitter to point mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeedX: function (value) + { + this.speedX.onChange(value); + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = false; + + return this; + }, + + /** + * Sets the initial vertical speed of emitted particles. + * Changes the emitter to point mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeedY: function (value) + { + if (this.speedY) + { + this.speedY.onChange(value); + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = false; + } + + return this; + }, + + /** + * Sets the initial radial speed of emitted particles. + * Changes the emitter to radial mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeed + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeed: function (value) + { + this.speedX.onChange(value); + this.speedY = null; + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = true; + + return this; + }, + + /** + * Sets the horizontal scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleX + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScaleX: function (value) + { + this.scaleX.onChange(value); + + return this; + }, + + /** + * Sets the vertical scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleY + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScaleY: function (value) + { + this.scaleY.onChange(value); + + return this; + }, + + /** + * Sets the scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScale: function (value) + { + this.scaleX.onChange(value); + this.scaleY = null; + + return this; + }, + + /** + * Sets the horizontal gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityX + * @since 3.0.0 + * + * @param {number} value - Acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravityX: function (value) + { + this.gravityX = value; + + return this; + }, + + /** + * Sets the vertical gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityY + * @since 3.0.0 + * + * @param {number} value - Acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravityY: function (value) + { + this.gravityY = value; + + return this; + }, + + /** + * Sets the gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravity + * @since 3.0.0 + * + * @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. + * @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravity: function (x, y) + { + this.gravityX = x; + this.gravityY = y; + + return this; + }, + + /** + * Sets the opacity of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setAlpha + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 (transparent) and 1 (opaque). + * + * @return {this} This Particle Emitter. + */ + setAlpha: function (value) + { + this.alpha.onChange(value); + + return this; + }, + + /** + * Sets the color tint of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setTint + * @since 3.22.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff. + * + * @return {this} This Particle Emitter. + */ + setTint: function (value) + { + this.tint.onChange(value); + + return this; + }, + + /** + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. + * + * @return {this} This Particle Emitter. + */ + setEmitterAngle: function (value) + { + this.angle.onChange(value); + + return this; + }, + + /** + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setAngle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. + * + * @return {this} This Particle Emitter. + */ + setAngle: function (value) + { + this.angle.onChange(value); + + return this; + }, + + /** + * Sets the lifespan of newly emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setLifespan + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The particle lifespan, in ms. + * + * @return {this} This Particle Emitter. + */ + setLifespan: function (value) + { + this.lifespan.onChange(value); + + return this; + }, + + /** + * Sets the number of particles released at each flow cycle or explosion. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} quantity - The number of particles to release at each flow cycle or explosion. + * + * @return {this} This Particle Emitter. + */ + setQuantity: function (quantity) + { + this.quantity.onChange(quantity); + + return this; + }, + + /** + * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} + * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @since 3.0.0 + * + * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [quantity] - The number of particles to release at each flow cycle or explosion. + * + * @return {this} This Particle Emitter. + */ + setFrequency: function (frequency, quantity) + { + this.frequency = frequency; + + this._counter = 0; + + if (quantity) + { + this.quantity.onChange(quantity); + } + + return this; + }, + + /** + * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#emitZone}. + * + * An {@link Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig EdgeZone} places particles on its edges. Its {@link Phaser.Types.GameObjects.Particles.EdgeZoneSource source} can be a Curve, Path, Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback getPoints} method. + * + * A {@link Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig RandomZone} places randomly within its interior. Its {@link RandomZoneSource source} can be a Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.RandomZoneSourceCallback getRandomPoint} method. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current emit zone. + * + * @return {this} This Particle Emitter. + */ + setEmitZone: function (zoneConfig) + { + if (zoneConfig === undefined) + { + this.emitZone = null; + } + else + { + // Where source = Geom like Circle, or a Path or Curve + // emitZone: { type: 'random', source: X } + // emitZone: { type: 'edge', source: X, quantity: 32, [stepRate=0], [yoyo=false], [seamless=true] } + + var type = GetFastValue(zoneConfig, 'type', 'random'); + var source = GetFastValue(zoneConfig, 'source', null); + + switch (type) + { + case 'random': + + this.emitZone = new RandomZone(source); + + break; + + case 'edge': + + var quantity = GetFastValue(zoneConfig, 'quantity', 1); + var stepRate = GetFastValue(zoneConfig, 'stepRate', 0); + var yoyo = GetFastValue(zoneConfig, 'yoyo', false); + var seamless = GetFastValue(zoneConfig, 'seamless', true); + + this.emitZone = new EdgeZone(source, quantity, stepRate, yoyo, seamless); + + break; + } + } + + return this; + }, + + /** + * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current death zone. + * + * @return {this} This Particle Emitter. + */ + setDeathZone: function (zoneConfig) + { + if (zoneConfig === undefined) + { + this.deathZone = null; + } + else + { + // Where source = Geom like Circle or Rect that supports a 'contains' function + // deathZone: { type: 'onEnter', source: X } + // deathZone: { type: 'onLeave', source: X } + + var type = GetFastValue(zoneConfig, 'type', 'onEnter'); + var source = GetFastValue(zoneConfig, 'source', null); + + if (source && typeof source.contains === 'function') + { + var killOnEnter = (type === 'onEnter') ? true : false; + + this.deathZone = new DeathZone(source, killOnEnter); + } + } + + return this; + }, + + /** + * Creates inactive particles and adds them to this emitter's pool. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve + * @since 3.0.0 + * + * @param {number} particleCount - The number of particles to create. + * + * @return {this} This Particle Emitter. + */ + reserve: function (particleCount) + { + var dead = this.dead; + + for (var i = 0; i < particleCount; i++) + { + dead.push(new this.particleClass(this)); + } + + return this; + }, + + /** + * Gets the number of active (in-use) particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles with `active=true`. + */ + getAliveParticleCount: function () + { + return this.alive.length; + }, + + /** + * Gets the number of inactive (available) particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles with `active=false`. + */ + getDeadParticleCount: function () + { + return this.dead.length; + }, + + /** + * Gets the total number of particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles, including both alive and dead. + */ + getParticleCount: function () + { + return this.getAliveParticleCount() + this.getDeadParticleCount(); + }, + + /** + * Whether this emitter is at its limit (if set). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit + * @since 3.0.0 + * + * @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level. + */ + atLimit: function () + { + return (this.maxParticles > 0 && this.getParticleCount() === this.maxParticles); + }, + + /** + * Sets a function to call for each newly emitted particle. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} [context] - The calling context. + * + * @return {this} This Particle Emitter. + */ + onParticleEmit: function (callback, context) + { + if (callback === undefined) + { + // Clear any previously set callback + this.emitCallback = null; + this.emitCallbackScope = null; + } + else if (typeof callback === 'function') + { + this.emitCallback = callback; + + if (context) + { + this.emitCallbackScope = context; + } + } + + return this; + }, + + /** + * Sets a function to call for each particle death. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleDeathCallback} callback - The function. + * @param {*} [context] - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + onParticleDeath: function (callback, context) + { + if (callback === undefined) + { + // Clear any previously set callback + this.deathCallback = null; + this.deathCallbackScope = null; + } + else if (typeof callback === 'function') + { + this.deathCallback = callback; + + if (context) + { + this.deathCallbackScope = context; + } + } + + return this; + }, + + /** + * Deactivates every particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + killAll: function () + { + var dead = this.dead; + var alive = this.alive; + + while (alive.length > 0) + { + dead.push(alive.pop()); + } + + return this; + }, + + /** + * Calls a function for each active particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + forEachAlive: function (callback, context) + { + var alive = this.alive; + var length = alive.length; + + for (var index = 0; index < length; ++index) + { + // Sends the Particle and the Emitter + callback.call(context, alive[index], this); + } + + return this; + }, + + /** + * Calls a function for each inactive particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + forEachDead: function (callback, context) + { + var dead = this.dead; + var length = dead.length; + + for (var index = 0; index < length; ++index) + { + // Sends the Particle and the Emitter + callback.call(context, dead[index], this); + } + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on} the emitter and resets the flow counter. + * + * If this emitter is in flow mode (frequency >= 0; the default), the particle flow will start (or restart). + * + * If this emitter is in explode mode (frequency = -1), nothing will happen. + * Use {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} or {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} instead. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#start + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + start: function () + { + this.on = true; + + this._counter = 0; + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#stop + * @since 3.11.0 + * + * @return {this} This Particle Emitter. + */ + stop: function () + { + this.on = false; + + return this; + }, + + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#pause + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + pause: function () + { + this.active = false; + + return this; + }, + + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#resume + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + resume: function () + { + this.active = true; + + return this; + }, + + /** + * Removes the emitter from its manager and the scene. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#remove + * @since 3.22.0 + * + * @return {this} This Particle Emitter. + */ + remove: function () + { + this.manager.removeEmitter(this); + + return this; + }, + + /** + * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + depthSort: function () + { + StableSort(this.alive, this.depthSortCallback); + + return this; + }, + + /** + * Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow. + * + * To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#flow + * @since 3.0.0 + * + * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [count=1] - The number of particles to emit at each flow cycle. + * + * @return {this} This Particle Emitter. + */ + flow: function (frequency, count) + { + if (count === undefined) { count = 1; } + + this.frequency = frequency; + + this.quantity.onChange(count); + + return this.start(); + }, + + /** + * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#explode + * @since 3.0.0 + * + * @param {number} count - The amount of Particles to emit. + * @param {number} x - The x coordinate to emit the Particles from. + * @param {number} y - The y coordinate to emit the Particles from. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + */ + explode: function (count, x, y) + { + this.frequency = -1; + + return this.emitParticle(count, x, y); + }, + + /** + * Emits particles at a given position (or the emitter's current position). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt + * @since 3.0.0 + * + * @param {number} [x=this.x] - The x coordinate to emit the Particles from. + * @param {number} [y=this.x] - The y coordinate to emit the Particles from. + * @param {number} [count=this.quantity] - The number of Particles to emit. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + */ + emitParticleAt: function (x, y, count) + { + return this.emitParticle(count, x, y); + }, + + /** + * Emits particles at a given position (or the emitter's current position). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle + * @since 3.0.0 + * + * @param {number} [count=this.quantity] - The number of Particles to emit. + * @param {number} [x=this.x] - The x coordinate to emit the Particles from. + * @param {number} [y=this.x] - The y coordinate to emit the Particles from. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + * + * @see Phaser.GameObjects.Particles.Particle#fire + */ + emitParticle: function (count, x, y) + { + if (this.atLimit()) + { + return; + } + + if (count === undefined) + { + count = this.quantity.onEmit(); + } + + var dead = this.dead; + + var followX = (this.follow) ? this.follow.x + this.followOffset.x : x; + var followY = (this.follow) ? this.follow.y + this.followOffset.y : y; + + for (var i = 0; i < count; i++) + { + var particle = dead.pop(); + + if (!particle) + { + particle = new this.particleClass(this); + } + + particle.fire(followX, followY); + + if (this.particleBringToTop) + { + this.alive.push(particle); + } + else + { + this.alive.unshift(particle); + } + + if (this.emitCallback) + { + this.emitCallback.call(this.emitCallbackScope, particle, this); + } + + if (this.atLimit()) + { + break; + } + } + + return particle; + }, + + /** + * Updates this emitter and its particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) + { + // Scale the delta + delta *= this.timeScale; + + var step = (delta / 1000); + + if (this.trackVisible) + { + this.visible = this.follow.visible; + } + + // Any particle processors? + var processors = this.manager.getProcessors(); + + var particles = this.alive; + var dead = this.dead; + + var i = 0; + var rip = []; + var length = particles.length; + + for (i = 0; i < length; i++) + { + var particle = particles[i]; + + // update returns `true` if the particle is now dead (lifeCurrent <= 0) + if (particle.update(delta, step, processors)) + { + rip.push({ index: i, particle: particle }); + } + } + + // Move dead particles to the dead array + length = rip.length; + + if (length > 0) + { + var deathCallback = this.deathCallback; + var deathCallbackScope = this.deathCallbackScope; + + for (i = length - 1; i >= 0; i--) + { + var entry = rip[i]; + + // Remove from particles array + particles.splice(entry.index, 1); + + // Add to dead array + dead.push(entry.particle); + + // Callback + if (deathCallback) + { + deathCallback.call(deathCallbackScope, entry.particle); + } + + entry.particle.resetPosition(); + } + } + + if (!this.on) + { + return; + } + + if (this.frequency === 0) + { + this.emitParticle(); + } + else if (this.frequency > 0) + { + this._counter -= delta; + + if (this._counter <= 0) + { + this.emitParticle(); + + // counter = frequency - remained from previous delta + this._counter = (this.frequency - Math.abs(this._counter)); + } + } + }, + + /** + * Calculates the difference of two particles, for sorting them by depth. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback + * @since 3.0.0 + * + * @param {object} a - The first particle. + * @param {object} b - The second particle. + * + * @return {number} The difference of a and b's y coordinates. + */ + depthSortCallback: function (a, b) + { + return a.y - b.y; + } + +}); + +module.exports = ParticleEmitter; + + +/***/ }), +/* 447 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A Death Zone. + * + * A Death Zone is a special type of zone that will kill a Particle as soon as it either enters, or leaves, the zone. + * + * The zone consists of a `source` which could be a Geometric shape, such as a Rectangle or Ellipse, or your own + * object as long as it includes a `contains` method for which the Particles can be tested against. + * + * @class DeathZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.DeathZoneSource} source - An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. + * @param {boolean} killOnEnter - Should the Particle be killed when it enters the zone? `true` or leaves it? `false` + */ +var DeathZone = new Class({ + + initialize: + + function DeathZone (source, killOnEnter) + { + /** + * An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. + * This could be a Geometry shape, such as `Phaser.Geom.Circle`, or your own custom object. + * + * @name Phaser.GameObjects.Particles.Zones.DeathZone#source + * @type {Phaser.Types.GameObjects.Particles.DeathZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * Set to `true` if the Particle should be killed if it enters this zone. + * Set to `false` to kill the Particle if it leaves this zone. + * + * @name Phaser.GameObjects.Particles.Zones.DeathZone#killOnEnter + * @type {boolean} + * @since 3.0.0 + */ + this.killOnEnter = killOnEnter; + }, + + /** + * Checks if the given Particle will be killed or not by this zone. + * + * @method Phaser.GameObjects.Particles.Zones.DeathZone#willKill + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to be checked against this zone. + * + * @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`. + */ + willKill: function (particle) + { + var withinZone = this.source.contains(particle.x, particle.y); + + return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); + } + +}); + +module.exports = DeathZone; + + +/***/ }), +/* 448 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A zone that places particles on a shape's edges. + * + * @class EdgeZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * @param {number} quantity - The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * @param {number} stepRate - The distance between each particle. When set, `quantity` is implied and should be set to 0. + * @param {boolean} [yoyo=false] - Whether particles are placed from start to end and then end to start. + * @param {boolean} [seamless=true] - Whether one endpoint will be removed if it's identical to the other. + */ +var EdgeZone = new Class({ + + initialize: + + function EdgeZone (source, quantity, stepRate, yoyo, seamless) + { + if (yoyo === undefined) { yoyo = false; } + if (seamless === undefined) { seamless = true; } + + /** + * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source + * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * The points placed on the source edge. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points + * @type {Phaser.Geom.Point[]} + * @default [] + * @since 3.0.0 + */ + this.points = []; + + /** + * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#quantity + * @type {number} + * @since 3.0.0 + */ + this.quantity = quantity; + + /** + * The distance between each particle. When set, `quantity` is implied and should be set to 0. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#stepRate + * @type {number} + * @since 3.0.0 + */ + this.stepRate = stepRate; + + /** + * Whether particles are placed from start to end and then end to start. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#yoyo + * @type {boolean} + * @since 3.0.0 + */ + this.yoyo = yoyo; + + /** + * The counter used for iterating the EdgeZone's points. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.counter = -1; + + /** + * Whether one endpoint will be removed if it's identical to the other. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless + * @type {boolean} + * @since 3.0.0 + */ + this.seamless = seamless; + + /** + * An internal count of the points belonging to this EdgeZone. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_length + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._length = 0; + + /** + * An internal value used to keep track of the current iteration direction for the EdgeZone's points. + * + * 0 = forwards, 1 = backwards + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_direction + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._direction = 0; + + this.updateSource(); + }, + + /** + * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's + * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. + * + * Also updates internal properties. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource + * @since 3.0.0 + * + * @return {this} This Edge Zone. + */ + updateSource: function () + { + this.points = this.source.getPoints(this.quantity, this.stepRate); + + // Remove ends? + if (this.seamless) + { + var a = this.points[0]; + var b = this.points[this.points.length - 1]; + + if (a.x === b.x && a.y === b.y) + { + this.points.pop(); + } + } + + var oldLength = this._length; + + this._length = this.points.length; + + // Adjust counter if we now have less points than before + if (this._length < oldLength && this.counter > this._length) + { + this.counter = this._length - 1; + } + + return this; + }, + + /** + * Change the source of the EdgeZone. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * + * @return {this} This Edge Zone. + */ + changeSource: function (source) + { + this.source = source; + + return this.updateSource(); + }, + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. + */ + getPoint: function (particle) + { + if (this._direction === 0) + { + this.counter++; + + if (this.counter >= this._length) + { + if (this.yoyo) + { + this._direction = 1; + this.counter = this._length - 1; + } + else + { + this.counter = 0; + } + } + } + else + { + this.counter--; + + if (this.counter === -1) + { + if (this.yoyo) + { + this._direction = 0; + this.counter = 0; + } + else + { + this.counter = this._length - 1; + } + } + } + + var point = this.points[this.counter]; + + if (point) + { + particle.x = point.x; + particle.y = point.y; + } + } + +}); + +module.exports = EdgeZone; + + +/***/ }), +/* 449 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Verifies that an object contains at least one of the requested keys + * + * @function Phaser.Utils.Objects.HasAny + * @since 3.0.0 + * + * @param {object} source - an object on which to check for key existence + * @param {string[]} keys - an array of keys to search the object for + * + * @return {boolean} true if the source object contains at least one of the keys, false otherwise + */ +var HasAny = function (source, keys) +{ + for (var i = 0; i < keys.length; i++) + { + if (source.hasOwnProperty(keys[i])) + { + return true; + } + } + + return false; +}; + +module.exports = HasAny; + + +/***/ }), +/* 450 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A zone that places particles randomly within a shapes area. + * + * @class RandomZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.RandomZoneSource} source - An object instance with a `getRandomPoint(point)` method. + */ +var RandomZone = new Class({ + + initialize: + + function RandomZone (source) + { + /** + * An object instance with a `getRandomPoint(point)` method. + * + * @name Phaser.GameObjects.Particles.Zones.RandomZone#source + * @type {Phaser.Types.GameObjects.Particles.RandomZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * Internal calculation vector. + * + * @name Phaser.GameObjects.Particles.Zones.RandomZone#_tempVec + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tempVec = new Vector2(); + }, + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * + * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. + */ + getPoint: function (particle) + { + var vec = this._tempVec; + + this.source.getRandomPoint(vec); + + particle.x = vec.x; + particle.y = vec.y; + } + +}); + +module.exports = RandomZone; + + +/***/ }), +/* 451 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var Sprite = __webpack_require__(73); + +/** + * @classdesc + * A PathFollower Game Object. + * + * A PathFollower is a Sprite Game Object with some extra helpers to allow it to follow a Path automatically. + * + * Anything you can do with a standard Sprite can be done with this PathFollower, such as animate it, tint it, + * scale it and so on. + * + * PathFollowers are bound to a single Path at any one time and can traverse the length of the Path, from start + * to finish, forwards or backwards, or from any given point on the Path to its end. They can optionally rotate + * to face the direction of the path, be offset from the path coordinates or rotate independently of the Path. + * + * @class PathFollower + * @extends Phaser.GameObjects.Sprite + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.PathFollower + * + * @param {Phaser.Scene} scene - The Scene to which this PathFollower belongs. + * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. + * @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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + */ +var PathFollower = new Class({ + + Extends: Sprite, + + Mixins: [ + Components.PathFollower + ], + + initialize: + + function PathFollower (scene, path, x, y, texture, frame) + { + Sprite.call(this, scene, x, y, texture, frame); + + this.path = path; + }, + + /** + * 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.PathFollower#preUpdate + * @protected + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) + { + this.anims.update(time, delta); + this.pathUpdate(time); + } + +}); + +module.exports = PathFollower; + + +/***/ }), +/* 452 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns an object containing dimensions of the Text object. + * + * @function Phaser.GameObjects.GetTextSize + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Text} text - The Text object to calculate the size from. + * @param {Phaser.Types.GameObjects.Text.TextMetrics} size - The Text metrics to use when calculating the size. + * @param {string[]} lines - The lines of text to calculate the size from. + * + * @return {Phaser.Types.GameObjects.Text.GetTextSizeObject} An object containing dimensions of the Text object. + */ +var GetTextSize = function (text, size, lines) +{ + var canvas = text.canvas; + var context = text.context; + var style = text.style; + + var lineWidths = []; + var maxLineWidth = 0; + var drawnLines = lines.length; + + if (style.maxLines > 0 && style.maxLines < lines.length) + { + drawnLines = style.maxLines; + } + + style.syncFont(canvas, context); + + // Text Width + + for (var i = 0; i < drawnLines; i++) + { + var lineWidth = style.strokeThickness; + + lineWidth += context.measureText(lines[i]).width; + + // Adjust for wrapped text + if (style.wordWrap) + { + lineWidth -= context.measureText(' ').width; + } + + lineWidths[i] = Math.ceil(lineWidth); + maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); + } + + // Text Height + + var lineHeight = size.fontSize + style.strokeThickness; + var height = lineHeight * drawnLines; + var lineSpacing = text.lineSpacing; + + // Adjust for line spacing + if (drawnLines > 1) + { + height += lineSpacing * (drawnLines - 1); + } + + return { + width: maxLineWidth, + height: height, + lines: drawnLines, + lineWidths: lineWidths, + lineSpacing: lineSpacing, + lineHeight: lineHeight + }; +}; + +module.exports = GetTextSize; + + +/***/ }), +/* 453 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetAdvancedValue = __webpack_require__(13); +var GetValue = __webpack_require__(6); +var MeasureText = __webpack_require__(454); + +// Key: [ Object Key, Default Value ] + +var propertyMap = { + fontFamily: [ 'fontFamily', 'Courier' ], + fontSize: [ 'fontSize', '16px' ], + fontStyle: [ 'fontStyle', '' ], + backgroundColor: [ 'backgroundColor', null ], + color: [ 'color', '#fff' ], + stroke: [ 'stroke', '#fff' ], + strokeThickness: [ 'strokeThickness', 0 ], + shadowOffsetX: [ 'shadow.offsetX', 0 ], + shadowOffsetY: [ 'shadow.offsetY', 0 ], + shadowColor: [ 'shadow.color', '#000' ], + shadowBlur: [ 'shadow.blur', 0 ], + shadowStroke: [ 'shadow.stroke', false ], + shadowFill: [ 'shadow.fill', false ], + align: [ 'align', 'left' ], + maxLines: [ 'maxLines', 0 ], + fixedWidth: [ 'fixedWidth', 0 ], + fixedHeight: [ 'fixedHeight', 0 ], + resolution: [ 'resolution', 0 ], + rtl: [ 'rtl', false ], + testString: [ 'testString', '|MÉqgy' ], + baselineX: [ 'baselineX', 1.2 ], + baselineY: [ 'baselineY', 1.4 ], + wordWrapWidth: [ 'wordWrap.width', null ], + wordWrapCallback: [ 'wordWrap.callback', null ], + wordWrapCallbackScope: [ 'wordWrap.callbackScope', null ], + wordWrapUseAdvanced: [ 'wordWrap.useAdvancedWrap', false ] +}; + +/** + * @classdesc + * A TextStyle class manages all of the style settings for a Text object. + * + * Text Game Objects create a TextStyle instance automatically, which is + * accessed via the `Text.style` property. You do not normally need to + * instantiate one yourself. + * + * @class TextStyle + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Text} text - The Text object that this TextStyle is styling. + * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. + */ +var TextStyle = new Class({ + + initialize: + + function TextStyle (text, style) + { + /** + * The Text object that this TextStyle is styling. + * + * @name Phaser.GameObjects.TextStyle#parent + * @type {Phaser.GameObjects.Text} + * @since 3.0.0 + */ + this.parent = text; + + /** + * The font family. + * + * @name Phaser.GameObjects.TextStyle#fontFamily + * @type {string} + * @default 'Courier' + * @since 3.0.0 + */ + this.fontFamily; + + /** + * The font size. + * + * @name Phaser.GameObjects.TextStyle#fontSize + * @type {string} + * @default '16px' + * @since 3.0.0 + */ + this.fontSize; + + /** + * The font style. + * + * @name Phaser.GameObjects.TextStyle#fontStyle + * @type {string} + * @since 3.0.0 + */ + this.fontStyle; + + /** + * The background color. + * + * @name Phaser.GameObjects.TextStyle#backgroundColor + * @type {string} + * @since 3.0.0 + */ + this.backgroundColor; + + /** + * The text fill color. + * + * @name Phaser.GameObjects.TextStyle#color + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.color; + + /** + * The text stroke color. + * + * @name Phaser.GameObjects.TextStyle#stroke + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.stroke; + + /** + * The text stroke thickness. + * + * @name Phaser.GameObjects.TextStyle#strokeThickness + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.strokeThickness; + + /** + * The horizontal shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetX; + + /** + * The vertical shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetY; + + /** + * The shadow color. + * + * @name Phaser.GameObjects.TextStyle#shadowColor + * @type {string} + * @default '#000' + * @since 3.0.0 + */ + this.shadowColor; + + /** + * The shadow blur radius. + * + * @name Phaser.GameObjects.TextStyle#shadowBlur + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowBlur; + + /** + * Whether shadow stroke is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowStroke + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowStroke; + + /** + * Whether shadow fill is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowFill + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowFill; + + /** + * The text alignment. + * + * @name Phaser.GameObjects.TextStyle#align + * @type {string} + * @default 'left' + * @since 3.0.0 + */ + this.align; + + /** + * The maximum number of lines to draw. + * + * @name Phaser.GameObjects.TextStyle#maxLines + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxLines; + + /** + * The fixed width of the text. + * + * `0` means no fixed with. + * + * @name Phaser.GameObjects.TextStyle#fixedWidth + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.fixedWidth; + + /** + * The fixed height of the text. + * + * `0` means no fixed height. + * + * @name Phaser.GameObjects.TextStyle#fixedHeight + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.fixedHeight; + + /** + * The resolution the text is rendered to its internal canvas at. + * The default is 0, which means it will use the resolution set in the Game Config. + * + * @name Phaser.GameObjects.TextStyle#resolution + * @type {number} + * @default 0 + * @since 3.12.0 + */ + this.resolution; + + /** + * Whether the text should render right to left. + * + * @name Phaser.GameObjects.TextStyle#rtl + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.rtl; + + /** + * The test string to use when measuring the font. + * + * @name Phaser.GameObjects.TextStyle#testString + * @type {string} + * @default '|MÉqgy' + * @since 3.0.0 + */ + this.testString; + + /** + * The amount of horizontal padding added to the width of the text when calculating the font metrics. + * + * @name Phaser.GameObjects.TextStyle#baselineX + * @type {number} + * @default 1.2 + * @since 3.3.0 + */ + this.baselineX; + + /** + * The amount of vertical padding added to the height of the text when calculating the font metrics. + * + * @name Phaser.GameObjects.TextStyle#baselineY + * @type {number} + * @default 1.4 + * @since 3.3.0 + */ + this.baselineY; + + /** + * The maximum width of a line of text in pixels. Null means no line wrapping. Setting this + * property directly will not re-run the word wrapping algorithm. To change the width and + * re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapWidth + * @type {number | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapWidth; + + /** + * A custom function that will be responsible for wrapping the text. It will receive two + * arguments: text (the string to wrap), textObject (this Text instance). It should return + * the wrapped lines either as an array of lines or as a string with newline characters in + * place to indicate where breaks should happen. Setting this directly will not re-run the + * word wrapping algorithm. To change the callback and re-wrap, use + * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapCallback + * @type {TextStyleWordWrapCallback | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapCallback; + + /** + * The scope that will be applied when the wordWrapCallback is invoked. Setting this directly will not re-run the + * word wrapping algorithm. To change the callback and re-wrap, use + * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapCallbackScope + * @type {object | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapCallbackScope; + + /** + * Whether or not to use the advanced wrapping algorithm. If true, spaces are collapsed and + * whitespace is trimmed from lines. If false, spaces and whitespace are left as is. Setting + * this property directly will not re-run the word wrapping algorithm. To change the + * advanced setting and re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapUseAdvanced + * @type {boolean} + * @default false + * @since 3.24.0 + */ + this.wordWrapUseAdvanced; + + /** + * The font style, size and family. + * + * @name Phaser.GameObjects.TextStyle#_font + * @type {string} + * @private + * @since 3.0.0 + */ + this._font; + + // Set to defaults + user style + this.setStyle(style, false, true); + + var metrics = GetValue(style, 'metrics', false); + + // Provide optional TextMetrics in the style object to avoid the canvas look-up / scanning + // Doing this is reset if you then change the font of this TextStyle after creation + if (metrics) + { + this.metrics = { + ascent: GetValue(metrics, 'ascent', 0), + descent: GetValue(metrics, 'descent', 0), + fontSize: GetValue(metrics, 'fontSize', 0) + }; + } + else + { + this.metrics = MeasureText(this); + } + }, + + /** + * Set the text style. + * + * @example + * text.setStyle({ + * fontSize: '64px', + * fontFamily: 'Arial', + * color: '#ffffff', + * align: 'center', + * backgroundColor: '#ff00ff' + * }); + * + * @method Phaser.GameObjects.TextStyle#setStyle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. + * @param {boolean} [updateText=true] - Whether to update the text immediately. + * @param {boolean} [setDefaults=false] - Use the default values is not set, or the local values. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setStyle: function (style, updateText, setDefaults) + { + if (updateText === undefined) { updateText = true; } + if (setDefaults === undefined) { setDefaults = false; } + + // Avoid type mutation + // eslint-disable-next-line no-prototype-builtins + if (style && style.hasOwnProperty('fontSize') && typeof style.fontSize === 'number') + { + style.fontSize = style.fontSize.toString() + 'px'; + } + + for (var key in propertyMap) + { + var value = (setDefaults) ? propertyMap[key][1] : this[key]; + + if (key === 'wordWrapCallback' || key === 'wordWrapCallbackScope') + { + // Callback & scope should be set without processing the values + this[key] = GetValue(style, propertyMap[key][0], value); + } + else + { + this[key] = GetAdvancedValue(style, propertyMap[key][0], value); + } + } + + // Allow for 'font' override + var font = GetValue(style, 'font', null); + + if (font !== null) + { + this.setFont(font, false); + } + + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); + + // Allow for 'fill' to be used in place of 'color' + var fill = GetValue(style, 'fill', null); + + if (fill !== null) + { + this.color = fill; + } + + if (updateText) + { + return this.update(true); + } + else + { + return this.parent; + } + }, + + /** + * Synchronize the font settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncFont + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + */ + syncFont: function (canvas, context) + { + context.font = this._font; + }, + + /** + * Synchronize the text style settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncStyle + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + */ + syncStyle: function (canvas, context) + { + context.textBaseline = 'alphabetic'; + + context.fillStyle = this.color; + context.strokeStyle = this.stroke; + + context.lineWidth = this.strokeThickness; + context.lineCap = 'round'; + context.lineJoin = 'round'; + }, + + /** + * Synchronize the shadow settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncShadow + * @since 3.0.0 + * + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @param {boolean} enabled - Whether shadows are enabled or not. + */ + syncShadow: function (context, enabled) + { + if (enabled) + { + context.shadowOffsetX = this.shadowOffsetX; + context.shadowOffsetY = this.shadowOffsetY; + context.shadowColor = this.shadowColor; + context.shadowBlur = this.shadowBlur; + } + else + { + context.shadowOffsetX = 0; + context.shadowOffsetY = 0; + context.shadowColor = 0; + context.shadowBlur = 0; + } + }, + + /** + * Update the style settings for the parent Text object. + * + * @method Phaser.GameObjects.TextStyle#update + * @since 3.0.0 + * + * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + update: function (recalculateMetrics) + { + if (recalculateMetrics) + { + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); + + this.metrics = MeasureText(this); + } + + return this.parent.updateText(); + }, + + /** + * Set the font. + * + * If a string is given, the font family is set. + * + * If an object is given, the `fontFamily`, `fontSize` and `fontStyle` + * properties of that object are set. + * + * @method Phaser.GameObjects.TextStyle#setFont + * @since 3.0.0 + * + * @param {(string|object)} font - The font family or font settings to set. + * @param {boolean} [updateText=true] - Whether to update the text immediately. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFont: function (font, updateText) + { + if (updateText === undefined) { updateText = true; } + + var fontFamily = font; + var fontSize = ''; + var fontStyle = ''; + + if (typeof font !== 'string') + { + fontFamily = GetValue(font, 'fontFamily', 'Courier'); + fontSize = GetValue(font, 'fontSize', '16px'); + fontStyle = GetValue(font, 'fontStyle', ''); + } + else + { + var fontSplit = font.split(' '); + + var i = 0; + + fontStyle = (fontSplit.length > 2) ? fontSplit[i++] : ''; + fontSize = fontSplit[i++] || '16px'; + fontFamily = fontSplit[i++] || 'Courier'; + } + + if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) + { + this.fontFamily = fontFamily; + this.fontSize = fontSize; + this.fontStyle = fontStyle; + + if (updateText) + { + this.update(true); + } + } + + return this.parent; + }, + + /** + * Set the font family. + * + * @method Phaser.GameObjects.TextStyle#setFontFamily + * @since 3.0.0 + * + * @param {string} family - The font family. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontFamily: function (family) + { + if (this.fontFamily !== family) + { + this.fontFamily = family; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the font style. + * + * @method Phaser.GameObjects.TextStyle#setFontStyle + * @since 3.0.0 + * + * @param {string} style - The font style. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontStyle: function (style) + { + if (this.fontStyle !== style) + { + this.fontStyle = style; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the font size. + * + * @method Phaser.GameObjects.TextStyle#setFontSize + * @since 3.0.0 + * + * @param {(number|string)} size - The font size. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontSize: function (size) + { + if (typeof size === 'number') + { + size = size.toString() + 'px'; + } + + if (this.fontSize !== size) + { + this.fontSize = size; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the test string to use when measuring the font. + * + * @method Phaser.GameObjects.TextStyle#setTestString + * @since 3.0.0 + * + * @param {string} string - The test string to use when measuring the font. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setTestString: function (string) + { + this.testString = string; + + return this.update(true); + }, + + /** + * Set a fixed width and height for the text. + * + * Pass in `0` for either of these parameters to disable fixed width or height respectively. + * + * @method Phaser.GameObjects.TextStyle#setFixedSize + * @since 3.0.0 + * + * @param {number} width - The fixed width to set. + * @param {number} height - The fixed height to set. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFixedSize: function (width, height) + { + this.fixedWidth = width; + this.fixedHeight = height; + + if (width) + { + this.parent.width = width; + } + + if (height) + { + this.parent.height = height; + } + + return this.update(false); + }, + + /** + * Set the background color. + * + * @method Phaser.GameObjects.TextStyle#setBackgroundColor + * @since 3.0.0 + * + * @param {string} color - The background color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setBackgroundColor: function (color) + { + this.backgroundColor = color; + + return this.update(false); + }, + + /** + * Set the text fill color. + * + * @method Phaser.GameObjects.TextStyle#setFill + * @since 3.0.0 + * + * @param {string} color - The text fill color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFill: function (color) + { + this.color = color; + + return this.update(false); + }, + + /** + * Set the text fill color. + * + * @method Phaser.GameObjects.TextStyle#setColor + * @since 3.0.0 + * + * @param {string} color - The text fill color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setColor: function (color) + { + this.color = color; + + return this.update(false); + }, + + /** + * Set the resolution used by the Text object. + * + * By default it will be set to match the resolution set in the Game Config, + * but you can override it via this method. It allows for much clearer text on High DPI devices, + * at the cost of memory because it uses larger internal Canvas textures for the Text. + * + * Please use with caution, as the more high res Text you have, the more memory it uses up. + * + * @method Phaser.GameObjects.TextStyle#setResolution + * @since 3.12.0 + * + * @param {number} value - The resolution for this Text object to use. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setResolution: function (value) + { + this.resolution = value; + + return this.update(false); + }, + + /** + * Set the stroke settings. + * + * @method Phaser.GameObjects.TextStyle#setStroke + * @since 3.0.0 + * + * @param {string} color - The stroke color. + * @param {number} thickness - The stroke thickness. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setStroke: function (color, thickness) + { + if (thickness === undefined) { thickness = this.strokeThickness; } + + if (color === undefined && this.strokeThickness !== 0) + { + // Reset the stroke to zero (disabling it) + this.strokeThickness = 0; + + this.update(true); + } + else if (this.stroke !== color || this.strokeThickness !== thickness) + { + this.stroke = color; + this.strokeThickness = thickness; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the shadow settings. + * + * Calling this method always re-measures the parent Text object, + * so only call it when you actually change the shadow settings. + * + * @method Phaser.GameObjects.TextStyle#setShadow + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal shadow offset. + * @param {number} [y=0] - The vertical shadow offset. + * @param {string} [color='#000'] - The shadow color. + * @param {number} [blur=0] - The shadow blur radius. + * @param {boolean} [shadowStroke=false] - Whether to stroke the shadow. + * @param {boolean} [shadowFill=true] - Whether to fill the shadow. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadow: function (x, y, color, blur, shadowStroke, shadowFill) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (color === undefined) { color = '#000'; } + if (blur === undefined) { blur = 0; } + if (shadowStroke === undefined) { shadowStroke = false; } + if (shadowFill === undefined) { shadowFill = true; } + + this.shadowOffsetX = x; + this.shadowOffsetY = y; + this.shadowColor = color; + this.shadowBlur = blur; + this.shadowStroke = shadowStroke; + this.shadowFill = shadowFill; + + return this.update(false); + }, + + /** + * Set the shadow offset. + * + * @method Phaser.GameObjects.TextStyle#setShadowOffset + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal shadow offset. + * @param {number} [y=0] - The vertical shadow offset. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowOffset: function (x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this.shadowOffsetX = x; + this.shadowOffsetY = y; + + return this.update(false); + }, + + /** + * Set the shadow color. + * + * @method Phaser.GameObjects.TextStyle#setShadowColor + * @since 3.0.0 + * + * @param {string} [color='#000'] - The shadow color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowColor: function (color) + { + if (color === undefined) { color = '#000'; } + + this.shadowColor = color; + + return this.update(false); + }, + + /** + * Set the shadow blur radius. + * + * @method Phaser.GameObjects.TextStyle#setShadowBlur + * @since 3.0.0 + * + * @param {number} [blur=0] - The shadow blur radius. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowBlur: function (blur) + { + if (blur === undefined) { blur = 0; } + + this.shadowBlur = blur; + + return this.update(false); + }, + + /** + * Enable or disable shadow stroke. + * + * @method Phaser.GameObjects.TextStyle#setShadowStroke + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow stroke is enabled or not. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowStroke: function (enabled) + { + this.shadowStroke = enabled; + + return this.update(false); + }, + + /** + * Enable or disable shadow fill. + * + * @method Phaser.GameObjects.TextStyle#setShadowFill + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow fill is enabled or not. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowFill: function (enabled) + { + this.shadowFill = enabled; + + return this.update(false); + }, + + /** + * Set the width (in pixels) to use for wrapping lines. + * + * Pass in null to remove wrapping by width. + * + * @method Phaser.GameObjects.TextStyle#setWordWrapWidth + * @since 3.0.0 + * + * @param {number} width - The maximum width of a line in pixels. Set to null to remove wrapping. + * @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping + * algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false, + * spaces and whitespace are left as is. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setWordWrapWidth: function (width, useAdvancedWrap) + { + if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } + + this.wordWrapWidth = width; + this.wordWrapUseAdvanced = useAdvancedWrap; + + return this.update(false); + }, + + /** + * Set a custom callback for wrapping lines. + * + * Pass in null to remove wrapping by callback. + * + * @method Phaser.GameObjects.TextStyle#setWordWrapCallback + * @since 3.0.0 + * + * @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the + * text. It will receive two arguments: text (the string to wrap), textObject (this Text + * instance). It should return the wrapped lines either as an array of lines or as a string with + * newline characters in place to indicate where breaks should happen. + * @param {object} [scope=null] - The scope that will be applied when the callback is invoked. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setWordWrapCallback: function (callback, scope) + { + if (scope === undefined) { scope = null; } + + this.wordWrapCallback = callback; + this.wordWrapCallbackScope = scope; + + return this.update(false); + }, + + /** + * Set the alignment of the text in this Text object. + * + * The argument can be one of: `left`, `right`, `center` or `justify`. + * + * Alignment only works if the Text object has more than one line of text. + * + * @method Phaser.GameObjects.TextStyle#setAlign + * @since 3.0.0 + * + * @param {string} [align='left'] - The text alignment for multi-line text. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setAlign: function (align) + { + if (align === undefined) { align = 'left'; } + + this.align = align; + + return this.update(false); + }, + + /** + * Set the maximum number of lines to draw. + * + * @method Phaser.GameObjects.TextStyle#setMaxLines + * @since 3.0.0 + * + * @param {number} [max=0] - The maximum number of lines to draw. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setMaxLines: function (max) + { + if (max === undefined) { max = 0; } + + this.maxLines = max; + + return this.update(false); + }, + + /** + * Get the current text metrics. + * + * @method Phaser.GameObjects.TextStyle#getTextMetrics + * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. + */ + getTextMetrics: function () + { + var metrics = this.metrics; + + return { + ascent: metrics.ascent, + descent: metrics.descent, + fontSize: metrics.fontSize + }; + }, + + /** + * Build a JSON representation of this Text Style. + * + * @method Phaser.GameObjects.TextStyle#toJSON + * @since 3.0.0 + * + * @return {object} A JSON representation of this Text Style. + */ + toJSON: function () + { + var output = {}; + + for (var key in propertyMap) + { + output[key] = this[key]; + } + + output.metrics = this.getTextMetrics(); + + return output; + }, + + /** + * Destroy this Text Style. + * + * @method Phaser.GameObjects.TextStyle#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.parent = undefined; + } + +}); + +module.exports = TextStyle; + + +/***/ }), +/* 454 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); + +/** + * Calculates the ascent, descent and fontSize of a given font style. + * + * @function Phaser.GameObjects.MeasureText + * @since 3.0.0 + * + * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. + * + * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. + */ +var MeasureText = function (textStyle) +{ + var canvas = CanvasPool.create(this); + var context = canvas.getContext('2d'); + + textStyle.syncFont(canvas, context); + + var metrics = context.measureText(textStyle.testString); + + if (metrics.hasOwnProperty('actualBoundingBoxAscent')) + { + var ascent = metrics.actualBoundingBoxAscent; + var descent = metrics.actualBoundingBoxDescent; + + CanvasPool.remove(canvas); + + return { + ascent: ascent, + descent: descent, + fontSize: ascent + descent + }; + } + + var width = Math.ceil(metrics.width * textStyle.baselineX); + var baseline = width; + var height = 2 * baseline; + + baseline = baseline * textStyle.baselineY | 0; + + canvas.width = width; + canvas.height = height; + + context.fillStyle = '#f00'; + context.fillRect(0, 0, width, height); + + context.font = textStyle._font; + + context.textBaseline = 'alphabetic'; + context.fillStyle = '#000'; + context.fillText(textStyle.testString, 0, baseline); + + var output = { + ascent: 0, + descent: 0, + fontSize: 0 + }; + + if (!context.getImageData(0, 0, width, height)) + { + output.ascent = baseline; + output.descent = baseline + 6; + output.fontSize = output.ascent + output.descent; + + CanvasPool.remove(canvas); + + return output; + } + + var imagedata = context.getImageData(0, 0, width, height).data; + var pixels = imagedata.length; + var line = width * 4; + var i; + var j; + var idx = 0; + var stop = false; + + // ascent. scan from top to bottom until we find a non red pixel + for (i = 0; i < baseline; i++) + { + for (j = 0; j < line; j += 4) + { + if (imagedata[idx + j] !== 255) + { + stop = true; + break; + } + } + + if (!stop) + { + idx += line; + } + else + { + break; + } + } + + output.ascent = baseline - i; + + idx = pixels - line; + stop = false; + + // descent. scan from bottom to top until we find a non red pixel + for (i = height; i > baseline; i--) + { + for (j = 0; j < line; j += 4) + { + if (imagedata[idx + j] !== 255) + { + stop = true; + break; + } + } + + if (!stop) + { + idx -= line; + } + else + { + break; + } + } + + output.descent = (i - baseline); + output.fontSize = output.ascent + output.descent; + + CanvasPool.remove(canvas); + + return output; +}; + +module.exports = MeasureText; + + +/***/ }), +/* 455 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcRender = __webpack_require__(1091); +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var Earcut = __webpack_require__(68); +var GeomCircle = __webpack_require__(62); +var MATH_CONST = __webpack_require__(14); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Arc Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * When it renders it displays an arc shape. You can control the start and end angles of the arc, + * as well as if the angles are winding clockwise or anti-clockwise. With the default settings + * it renders as a complete circle. By changing the angles you can create other arc shapes, + * such as half-circles. + * + * Arcs also have an `iterations` property and corresponding `setIterations` method. This allows + * you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. + * + * @class Arc + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [radius=128] - The radius of the arc. + * @param {number} [startAngle=0] - The start angle of the arc, in degrees. + * @param {number} [endAngle=360] - The end angle of the arc, in degrees. + * @param {boolean} [anticlockwise=false] - The winding order of the start and end angles. + * @param {number} [fillColor] - The color the arc will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Arc = new Class({ + + Extends: Shape, + + Mixins: [ + ArcRender + ], + + initialize: + + function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 128; } + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 360; } + if (anticlockwise === undefined) { anticlockwise = false; } + + Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius)); + + /** + * Private internal value. Holds the start angle in degrees. + * + * @name Phaser.GameObjects.Arc#_startAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._startAngle = startAngle; + + /** + * Private internal value. Holds the end angle in degrees. + * + * @name Phaser.GameObjects.Arc#_endAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._endAngle = endAngle; + + /** + * Private internal value. Holds the winding order of the start and end angles. + * + * @name Phaser.GameObjects.Arc#_anticlockwise + * @type {boolean} + * @private + * @since 3.13.0 + */ + this._anticlockwise = anticlockwise; + + /** + * Private internal value. Holds the number of iterations used when drawing the arc. + * + * @name Phaser.GameObjects.Arc#_iterations + * @type {number} + * @default 0.01 + * @private + * @since 3.13.0 + */ + this._iterations = 0.01; + + this.setPosition(x, y); + + var diameter = this.geom.radius * 2; + this.setSize(diameter, diameter); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * The number of iterations used when drawing the arc. + * Increase this value for smoother arcs, at the cost of more polygons being rendered. + * Modify this value by small amounts, such as 0.01. + * + * @name Phaser.GameObjects.Arc#iterations + * @type {number} + * @default 0.01 + * @since 3.13.0 + */ + iterations: { + + get: function () + { + return this._iterations; + }, + + set: function (value) + { + this._iterations = value; + + this.updateData(); + } + + }, + + /** + * The radius of the arc. + * + * @name Phaser.GameObjects.Arc#radius + * @type {number} + * @since 3.13.0 + */ + radius: { + + get: function () + { + return this.geom.radius; + }, + + set: function (value) + { + this.geom.radius = value; + + var diameter = value * 2; + this.setSize(diameter, diameter); + this.updateDisplayOrigin(); + this.updateData(); + } + + }, + + /** + * The start angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#startAngle + * @type {number} + * @since 3.13.0 + */ + startAngle: { + + get: function () + { + return this._startAngle; + }, + + set: function (value) + { + this._startAngle = value; + + this.updateData(); + } + + }, + + /** + * The end angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#endAngle + * @type {number} + * @since 3.13.0 + */ + endAngle: { + + get: function () + { + return this._endAngle; + }, + + set: function (value) + { + this._endAngle = value; + + this.updateData(); + } + + }, + + /** + * The winding order of the start and end angles. + * + * @name Phaser.GameObjects.Arc#anticlockwise + * @type {boolean} + * @since 3.13.0 + */ + anticlockwise: { + + get: function () + { + return this._anticlockwise; + }, + + set: function (value) + { + this._anticlockwise = value; + + this.updateData(); + } + + }, + + /** + * Sets the radius of the arc. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setRadius + * @since 3.13.0 + * + * @param {number} value - The value to set the radius to. + * + * @return {this} This Game Object instance. + */ + setRadius: function (value) + { + this.radius = value; + + return this; + }, + + /** + * Sets the number of iterations used when drawing the arc. + * Increase this value for smoother arcs, at the cost of more polygons being rendered. + * Modify this value by small amounts, such as 0.01. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setIterations + * @since 3.13.0 + * + * @param {number} value - The value to set the iterations to. + * + * @return {this} This Game Object instance. + */ + setIterations: function (value) + { + if (value === undefined) { value = 0.01; } + + this.iterations = value; + + return this; + }, + + /** + * Sets the starting angle of the arc, in degrees. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setStartAngle + * @since 3.13.0 + * + * @param {number} value - The value to set the starting angle to. + * + * @return {this} This Game Object instance. + */ + setStartAngle: function (angle, anticlockwise) + { + this._startAngle = angle; + + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } + + return this.updateData(); + }, + + /** + * Sets the ending angle of the arc, in degrees. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setEndAngle + * @since 3.13.0 + * + * @param {number} value - The value to set the ending angle to. + * + * @return {this} This Game Object instance. + */ + setEndAngle: function (angle, anticlockwise) + { + this._endAngle = angle; + + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Arc#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var step = this._iterations; + var iteration = step; + + var radius = this.geom.radius; + var startAngle = DegToRad(this._startAngle); + var endAngle = DegToRad(this._endAngle); + var anticlockwise = this._anticlockwise; + + var x = radius; + var y = radius; + + endAngle -= startAngle; + + if (anticlockwise) + { + if (endAngle < -MATH_CONST.PI2) + { + endAngle = -MATH_CONST.PI2; + } + else if (endAngle > 0) + { + endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; + } + } + else if (endAngle > MATH_CONST.PI2) + { + endAngle = MATH_CONST.PI2; + } + else if (endAngle < 0) + { + endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; + } + + var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; + + var ta; + + while (iteration < 1) + { + ta = endAngle * iteration + startAngle; + + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + + iteration += step; + } + + ta = endAngle + startAngle; + + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + + path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Arc; + + +/***/ }), +/* 456 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CurveRender = __webpack_require__(1094); +var Earcut = __webpack_require__(68); +var Rectangle = __webpack_require__(10); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Curve Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to + * the Curve Shape in the constructor. + * + * The Curve shape also has a `smoothness` property and corresponding `setSmoothness` method. + * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. Increase and decrease the default value for smoother, or more + * jagged, shapes. + * + * @class Curve + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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.Curves.Curve} [curve] - The Curve object to use to create the Shape. + * @param {number} [fillColor] - The color the curve will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Curve = new Class({ + + Extends: Shape, + + Mixins: [ + CurveRender + ], + + initialize: + + function Curve (scene, x, y, curve, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + Shape.call(this, scene, 'Curve', curve); + + /** + * Private internal value. + * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. + * + * @name Phaser.GameObjects.Curve#_smoothness + * @type {number} + * @private + * @since 3.13.0 + */ + this._smoothness = 32; + + /** + * Private internal value. + * The Curve bounds rectangle. + * + * @name Phaser.GameObjects.Curve#_curveBounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.13.0 + */ + this._curveBounds = new Rectangle(); + + this.closePath = false; + + this.setPosition(x, y); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateData(); + }, + + /** + * The smoothness of the curve. The number of points used when rendering it. + * Increase this value for smoother curves, at the cost of more polygons being rendered. + * + * @name Phaser.GameObjects.Curve#smoothness + * @type {number} + * @default 32 + * @since 3.13.0 + */ + smoothness: { + + get: function () + { + return this._smoothness; + }, + + set: function (value) + { + this._smoothness = value; + + this.updateData(); + } + + }, + + /** + * Sets the smoothness of the curve. The number of points used when rendering it. + * Increase this value for smoother curves, at the cost of more polygons being rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.Curve#setSmoothness + * @since 3.13.0 + * + * @param {number} value - The value to set the smoothness to. + * + * @return {this} This Game Object instance. + */ + setSmoothness: function (value) + { + this._smoothness = value; + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Curve#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var bounds = this._curveBounds; + var smoothness = this._smoothness; + + // Update the bounds in case the underlying data has changed + this.geom.getBounds(bounds, smoothness); + + this.setSize(bounds.width, bounds.height); + this.updateDisplayOrigin(); + + var path = []; + var points = this.geom.getPoints(smoothness); + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Curve; + + +/***/ }), +/* 457 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var EllipseRender = __webpack_require__(1097); +var GeomEllipse = __webpack_require__(108); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * When it renders it displays an ellipse shape. You can control the width and height of the ellipse. + * If the width and height match it will render as a circle. If the width is less than the height, + * it will look more like an egg shape. + * + * The Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method. + * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. Increase and decrease the default value for smoother, or more + * jagged, shapes. + * + * @class Ellipse + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [width=128] - The width of the ellipse. An ellipse with equal width and height renders as a circle. + * @param {number} [height=128] - The height of the ellipse. An ellipse with equal width and height renders as a circle. + * @param {number} [fillColor] - The color the ellipse will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Ellipse = new Class({ + + Extends: Shape, + + Mixins: [ + EllipseRender + ], + + initialize: + + function Ellipse (scene, x, y, width, height, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + + Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); + + /** + * Private internal value. + * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. + * + * @name Phaser.GameObjects.Ellipse#_smoothness + * @type {number} + * @private + * @since 3.13.0 + */ + this._smoothness = 64; + + this.setPosition(x, y); + + this.width = width; + this.height = height; + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * The smoothness of the ellipse. The number of points used when rendering it. + * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. + * + * @name Phaser.GameObjects.Ellipse#smoothness + * @type {number} + * @default 64 + * @since 3.13.0 + */ + smoothness: { + + get: function () + { + return this._smoothness; + }, + + set: function (value) + { + this._smoothness = value; + + this.updateData(); + } + + }, + + /** + * Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object. + * This call can be chained. + * + * @method Phaser.GameObjects.Ellipse#setSize + * @since 3.13.0 + * + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. + * + * @return {this} This Game Object instance. + */ + setSize: function (width, height) + { + this.width = width; + this.height = height; + this.geom.setPosition(width / 2, height / 2); + this.geom.setSize(width, height); + + return this.updateData(); + }, + + /** + * Sets the smoothness of the ellipse. The number of points used when rendering it. + * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.Ellipse#setSmoothness + * @since 3.13.0 + * + * @param {number} value - The value to set the smoothness to. + * + * @return {this} This Game Object instance. + */ + setSmoothness: function (value) + { + this._smoothness = value; + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Ellipse#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var points = this.geom.getPoints(this._smoothness); + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Ellipse; + + +/***/ }), +/* 458 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GridRender = __webpack_require__(1100); + +/** + * @classdesc + * The Grid Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * A Grid Shape allows you to display a grid in your game, where you can control the size of the + * grid as well as the width and height of the grid cells. You can set a fill color for each grid + * cell as well as an alternate fill color. When the alternate fill color is set then the grid + * cells will alternate the fill colors as they render, creating a chess-board effect. You can + * also optionally have an outline fill color. If set, this draws lines between the grid cells + * in the given color. If you specify an outline color with an alpha of zero, then it will draw + * the cells spaced out, but without the lines between them. + * + * @class Grid + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [width=128] - The width of the grid. + * @param {number} [height=128] - The height of the grid. + * @param {number} [cellWidth=32] - The width of one cell in the grid. + * @param {number} [cellHeight=32] - The height of one cell in the grid. + * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * @param {number} [outlineFillColor] - The color of the lines between the grid cells. See the `setOutline` method. + * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. + */ +var Grid = new Class({ + + Extends: Shape, + + Mixins: [ + GridRender + ], + + initialize: + + function Grid (scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + if (cellWidth === undefined) { cellWidth = 32; } + if (cellHeight === undefined) { cellHeight = 32; } + + Shape.call(this, scene, 'Grid', null); + + /** + * The width of each grid cell. + * Must be a positive value. + * + * @name Phaser.GameObjects.Grid#cellWidth + * @type {number} + * @since 3.13.0 + */ + this.cellWidth = cellWidth; + + /** + * The height of each grid cell. + * Must be a positive value. + * + * @name Phaser.GameObjects.Grid#cellHeight + * @type {number} + * @since 3.13.0 + */ + this.cellHeight = cellHeight; + + /** + * Will the grid render its cells in the `fillColor`? + * + * @name Phaser.GameObjects.Grid#showCells + * @type {boolean} + * @since 3.13.0 + */ + this.showCells = true; + + /** + * The color of the lines between each grid cell. + * + * @name Phaser.GameObjects.Grid#outlineFillColor + * @type {number} + * @since 3.13.0 + */ + this.outlineFillColor = 0; + + /** + * The alpha value for the color of the lines between each grid cell. + * + * @name Phaser.GameObjects.Grid#outlineFillAlpha + * @type {number} + * @since 3.13.0 + */ + this.outlineFillAlpha = 0; + + /** + * Will the grid display the lines between each cell when it renders? + * + * @name Phaser.GameObjects.Grid#showOutline + * @type {boolean} + * @since 3.13.0 + */ + this.showOutline = true; + + /** + * Will the grid render the alternating cells in the `altFillColor`? + * + * @name Phaser.GameObjects.Grid#showAltCells + * @type {boolean} + * @since 3.13.0 + */ + this.showAltCells = false; + + /** + * The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. + * + * @name Phaser.GameObjects.Grid#altFillColor + * @type {number} + * @since 3.13.0 + */ + this.altFillColor; + + /** + * The alpha the alternating grid cells will be filled with. + * You can also set the alpha of the overall Shape using its `alpha` property. + * + * @name Phaser.GameObjects.Grid#altFillAlpha + * @type {number} + * @since 3.13.0 + */ + this.altFillAlpha; + + this.setPosition(x, y); + this.setSize(width, height); + + this.setFillStyle(fillColor, fillAlpha); + + if (outlineFillColor !== undefined) + { + this.setOutlineStyle(outlineFillColor, outlineFillAlpha); + } + + this.updateDisplayOrigin(); + }, + + /** + * Sets the fill color and alpha level the grid cells will use when rendering. + * + * If this method is called with no values then the grid cells will not be rendered, + * however the grid lines and alternating cells may still be. + * + * Also see the `setOutlineStyle` and `setAltFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showCells = false; + } + else + { + this.fillColor = fillColor; + this.fillAlpha = fillAlpha; + this.showCells = true; + } + + return this; + }, + + /** + * Sets the fill color and alpha level that the alternating grid cells will use. + * + * If this method is called with no values then alternating grid cells will not be rendered in a different color. + * + * Also see the `setOutlineStyle` and `setFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setAltFillStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the alternating grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setAltFillStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showAltCells = false; + } + else + { + this.altFillColor = fillColor; + this.altFillAlpha = fillAlpha; + this.showAltCells = true; + } + + return this; + }, + + /** + * Sets the fill color and alpha level that the lines between each grid cell will use. + * + * If this method is called with no values then the grid lines will not be rendered at all, however + * the cells themselves may still be if they have colors set. + * + * Also see the `setFillStyle` and `setAltFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setOutlineStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the lines between the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the lines between the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setOutlineStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showOutline = false; + } + else + { + this.outlineFillColor = fillColor; + this.outlineFillAlpha = fillAlpha; + this.showOutline = true; + } + + return this; + } + +}); + +module.exports = Grid; + + +/***/ }), +/* 459 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var IsoBoxRender = __webpack_require__(1103); +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The IsoBox Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * An IsoBox is an 'isometric' rectangle. Each face of it has a different fill color. You can set + * the color of the top, left and right faces of the rectangle respectively. You can also choose + * which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. + * + * You cannot view an IsoBox from under-neath, however you can change the 'angle' by setting + * the `projection` property. + * + * @class IsoBox + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [size=48] - The width of the iso box in pixels. The left and right faces will be exactly half this value. + * @param {number} [height=32] - The height of the iso box. The left and right faces will be this tall. The overall height of the isobox will be this value plus half the `size` value. + * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso box. + * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso box. + * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso box. + */ +var IsoBox = new Class({ + + Extends: Shape, + + Mixins: [ + IsoBoxRender + ], + + initialize: + + function IsoBox (scene, x, y, size, height, fillTop, fillLeft, fillRight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (size === undefined) { size = 48; } + if (height === undefined) { height = 32; } + if (fillTop === undefined) { fillTop = 0xeeeeee; } + if (fillLeft === undefined) { fillLeft = 0x999999; } + if (fillRight === undefined) { fillRight = 0xcccccc; } + + Shape.call(this, scene, 'IsoBox', null); + + /** + * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * + * @name Phaser.GameObjects.IsoBox#projection + * @type {number} + * @default 4 + * @since 3.13.0 + */ + this.projection = 4; + + /** + * The color used to fill in the top of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillTop + * @type {number} + * @since 3.13.0 + */ + this.fillTop = fillTop; + + /** + * The color used to fill in the left-facing side of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillLeft + * @type {number} + * @since 3.13.0 + */ + this.fillLeft = fillLeft; + + /** + * The color used to fill in the right-facing side of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillRight + * @type {number} + * @since 3.13.0 + */ + this.fillRight = fillRight; + + /** + * Controls if the top-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showTop + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showTop = true; + + /** + * Controls if the left-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showLeft + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showLeft = true; + + /** + * Controls if the right-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showRight + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showRight = true; + + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); + }, + + /** + * Sets the projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setProjection + * @since 3.13.0 + * + * @param {number} value - The value to set the projection to. + * + * @return {this} This Game Object instance. + */ + setProjection: function (value) + { + this.projection = value; + + return this; + }, + + /** + * Sets which faces of the iso box will be rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setFaces + * @since 3.13.0 + * + * @param {boolean} [showTop=true] - Show the top-face of the iso box. + * @param {boolean} [showLeft=true] - Show the left-face of the iso box. + * @param {boolean} [showRight=true] - Show the right-face of the iso box. + * + * @return {this} This Game Object instance. + */ + setFaces: function (showTop, showLeft, showRight) + { + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } + + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; + + return this; + }, + + /** + * Sets the fill colors for each face of the iso box. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillTop] - The color used to fill the top of the iso box. + * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso box. + * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso box. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillTop, fillLeft, fillRight) + { + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.isFilled = true; + + return this; + } + +}); + +module.exports = IsoBox; + + +/***/ }), +/* 460 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var IsoTriangleRender = __webpack_require__(1106); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The IsoTriangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * An IsoTriangle is an 'isometric' triangle. Think of it like a pyramid. Each face has a different + * fill color. You can set the color of the top, left and right faces of the triangle respectively + * You can also choose which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. + * + * You cannot view an IsoTriangle from under-neath, however you can change the 'angle' by setting + * the `projection` property. The `reversed` property controls if the IsoTriangle is rendered upside + * down or not. + * + * @class IsoTriangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [size=48] - The width of the iso triangle in pixels. The left and right faces will be exactly half this value. + * @param {number} [height=32] - The height of the iso triangle. The left and right faces will be this tall. The overall height of the iso triangle will be this value plus half the `size` value. + * @param {boolean} [reversed=false] - Is the iso triangle upside down? + * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso triangle. + * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso triangle. + * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso triangle. + */ +var IsoTriangle = new Class({ + + Extends: Shape, + + Mixins: [ + IsoTriangleRender + ], + + initialize: + + function IsoTriangle (scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (size === undefined) { size = 48; } + if (height === undefined) { height = 32; } + if (reversed === undefined) { reversed = false; } + if (fillTop === undefined) { fillTop = 0xeeeeee; } + if (fillLeft === undefined) { fillLeft = 0x999999; } + if (fillRight === undefined) { fillRight = 0xcccccc; } + + Shape.call(this, scene, 'IsoTriangle', null); + + /** + * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * + * @name Phaser.GameObjects.IsoTriangle#projection + * @type {number} + * @default 4 + * @since 3.13.0 + */ + this.projection = 4; + + /** + * The color used to fill in the top of the iso triangle. This is only used if the triangle is reversed. + * + * @name Phaser.GameObjects.IsoTriangle#fillTop + * @type {number} + * @since 3.13.0 + */ + this.fillTop = fillTop; + + /** + * The color used to fill in the left-facing side of the iso triangle. + * + * @name Phaser.GameObjects.IsoTriangle#fillLeft + * @type {number} + * @since 3.13.0 + */ + this.fillLeft = fillLeft; + + /** + * The color used to fill in the right-facing side of the iso triangle. + * + * @name Phaser.GameObjects.IsoTriangle#fillRight + * @type {number} + * @since 3.13.0 + */ + this.fillRight = fillRight; + + /** + * Controls if the top-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showTop + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showTop = true; + + /** + * Controls if the left-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showLeft + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showLeft = true; + + /** + * Controls if the right-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showRight + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showRight = true; + + /** + * Sets if the iso triangle will be rendered upside down or not. + * + * @name Phaser.GameObjects.IsoTriangle#isReversed + * @type {boolean} + * @default false + * @since 3.13.0 + */ + this.isReversed = reversed; + + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); + }, + + /** + * Sets the projection level of the iso triangle. Change this to change the 'angle' at which you are looking at the pyramid. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setProjection + * @since 3.13.0 + * + * @param {number} value - The value to set the projection to. + * + * @return {this} This Game Object instance. + */ + setProjection: function (value) + { + this.projection = value; + + return this; + }, + + /** + * Sets if the iso triangle will be rendered upside down or not. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setReversed + * @since 3.13.0 + * + * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. + * + * @return {this} This Game Object instance. + */ + setReversed: function (reversed) + { + this.isReversed = reversed; + + return this; + }, + + /** + * Sets which faces of the iso triangle will be rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setFaces + * @since 3.13.0 + * + * @param {boolean} [showTop=true] - Show the top-face of the iso triangle (only if `reversed` is true) + * @param {boolean} [showLeft=true] - Show the left-face of the iso triangle. + * @param {boolean} [showRight=true] - Show the right-face of the iso triangle. + * + * @return {this} This Game Object instance. + */ + setFaces: function (showTop, showLeft, showRight) + { + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } + + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; + + return this; + }, + + /** + * Sets the fill colors for each face of the iso triangle. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillTop] - The color used to fill the top of the iso triangle. + * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso triangle. + * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso triangle. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillTop, fillLeft, fillRight) + { + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.isFilled = true; + + return this; + } + +}); + +module.exports = IsoTriangle; + + +/***/ }), +/* 461 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GeomLine = __webpack_require__(45); +var LineRender = __webpack_require__(1109); + +/** + * @classdesc + * The Line Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only stroke colors and cannot be filled. + * + * A Line Shape allows you to draw a line between two points in your game. You can control the + * stroke color and thickness of the line. In WebGL only you can also specify a different + * thickness for the start and end of the line, allowing you to render lines that taper-off. + * + * If you need to draw multiple lines in a sequence you may wish to use the Polygon Shape instead. + * + * Be aware that as with all Game Objects the default origin is 0.5. If you need to draw a Line + * between two points and want the x1/y1 values to match the x/y values, then set the origin to 0. + * + * @class Line + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [x1=0] - The horizontal position of the start of the line. + * @param {number} [y1=0] - The vertical position of the start of the line. + * @param {number} [x2=128] - The horizontal position of the end of the line. + * @param {number} [y2=0] - The vertical position of the end of the line. + * @param {number} [strokeColor] - The color the line will be drawn in, i.e. 0xff0000 for red. + * @param {number} [strokeAlpha] - The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Line = new Class({ + + Extends: Shape, + + Mixins: [ + LineRender + ], + + initialize: + + function Line (scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 128; } + if (y2 === undefined) { y2 = 0; } + + Shape.call(this, scene, 'Line', new GeomLine(x1, y1, x2, y2)); + + var width = Math.max(1, this.geom.right - this.geom.left); + var height = Math.max(1, this.geom.bottom - this.geom.top); + + /** + * The width (or thickness) of the line. + * See the setLineWidth method for extra details on changing this on WebGL. + * + * @name Phaser.GameObjects.Line#lineWidth + * @type {number} + * @since 3.13.0 + */ + this.lineWidth = 1; + + /** + * Private internal value. Holds the start width of the line. + * + * @name Phaser.GameObjects.Line#_startWidth + * @type {number} + * @private + * @since 3.13.0 + */ + this._startWidth = 1; + + /** + * Private internal value. Holds the end width of the line. + * + * @name Phaser.GameObjects.Line#_endWidth + * @type {number} + * @private + * @since 3.13.0 + */ + this._endWidth = 1; + + this.setPosition(x, y); + this.setSize(width, height); + + if (strokeColor !== undefined) + { + this.setStrokeStyle(1, strokeColor, strokeAlpha); + } + + this.updateDisplayOrigin(); + }, + + /** + * Sets the width of the line. + * + * When using the WebGL renderer you can have different start and end widths. + * When using the Canvas renderer only the `startWidth` value is used. The `endWidth` is ignored. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Line#setLineWidth + * @since 3.13.0 + * + * @param {number} startWidth - The start width of the line. + * @param {number} [endWidth] - The end width of the line. Only used in WebGL. + * + * @return {this} This Game Object instance. + */ + setLineWidth: function (startWidth, endWidth) + { + if (endWidth === undefined) { endWidth = startWidth; } + + this._startWidth = startWidth; + this._endWidth = endWidth; + + this.lineWidth = startWidth; + + return this; + }, + + /** + * Sets the start and end coordinates of this Line. + * + * @method Phaser.GameObjects.Line#setTo + * @since 3.13.0 + * + * @param {number} [x1=0] - The horizontal position of the start of the line. + * @param {number} [y1=0] - The vertical position of the start of the line. + * @param {number} [x2=0] - The horizontal position of the end of the line. + * @param {number} [y2=0] - The vertical position of the end of the line. + * + * @return {this} This Line object. + */ + setTo: function (x1, y1, x2, y2) + { + this.geom.setTo(x1, y1, x2, y2); + + return this; + } + +}); + +module.exports = Line; + + +/***/ }), +/* 462 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var PolygonRender = __webpack_require__(1112); +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var GetAABB = __webpack_require__(463); +var GeomPolygon = __webpack_require__(224); +var Shape = __webpack_require__(32); +var Smooth = __webpack_require__(466); + +/** + * @classdesc + * The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * The Polygon Shape is created by providing a list of points, which are then used to create an + * internal Polygon geometry object. The points can be set from a variety of formats: + * + * - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` + * - An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]` + * - An array of objects with public x/y properties: `[obj1, obj2, ...]` + * - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]` + * - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]` + * + * By default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending + * on the coordinates of the points provided, the final shape may be rendered offset from its origin. + * + * @class Polygon + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {any} [points] - The points that make up the polygon. + * @param {number} [fillColor] - The color the polygon will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Polygon = new Class({ + + Extends: Shape, + + Mixins: [ + PolygonRender + ], + + initialize: + + function Polygon (scene, x, y, points, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + Shape.call(this, scene, 'Polygon', new GeomPolygon(points)); + + var bounds = GetAABB(this.geom); + + this.setPosition(x, y); + this.setSize(bounds.width, bounds.height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Smooths the polygon over the number of iterations specified. + * The base polygon data will be updated and replaced with the smoothed values. + * This call can be chained. + * + * @method Phaser.GameObjects.Polygon#smooth + * @since 3.13.0 + * + * @param {number} [iterations=1] - The number of times to apply the polygon smoothing. + * + * @return {this} This Game Object instance. + */ + smooth: function (iterations) + { + if (iterations === undefined) { iterations = 1; } + + for (var i = 0; i < iterations; i++) + { + Smooth(this.geom); + } + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Polygon#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var points = this.geom.points; + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Polygon; + + +/***/ }), +/* 463 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +/** + * Calculates the bounding AABB rectangle of a polygon. + * + * @function Phaser.Geom.Polygon.GetAABB + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The polygon that should be calculated. + * @param {(Phaser.Geom.Rectangle|object)} [out] - The rectangle or object that has x, y, width, and height properties to store the result. Optional. + * + * @return {(Phaser.Geom.Rectangle|object)} The resulting rectangle or object that is passed in with position and dimensions of the polygon's AABB. + */ +var GetAABB = function (polygon, out) +{ + if (out === undefined) { out = new Rectangle(); } + + var minX = Infinity; + var minY = Infinity; + var maxX = -minX; + var maxY = -minY; + var p; + + for (var i = 0; i < polygon.points.length; i++) + { + p = polygon.points[i]; + + minX = Math.min(minX, p.x); + minY = Math.min(minY, p.y); + maxX = Math.max(maxX, p.x); + maxY = Math.max(maxY, p.y); + } + + out.x = minX; + out.y = minY; + out.width = maxX - minX; + out.height = maxY - minY; + + return out; +}; + +module.exports = GetAABB; + + +/***/ }), +/* 464 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Line = __webpack_require__(45); +var Perimeter = __webpack_require__(465); + +/** + * Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon, + * based on the given quantity or stepRate values. + * + * @function Phaser.Geom.Polygon.GetPoints + * @since 3.12.0 + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the points from. + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate. + * @param {array} [output] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {Phaser.Geom.Point[]} An array of Point objects pertaining to the points around the perimeter of the Polygon. + */ +var GetPoints = function (polygon, quantity, stepRate, out) +{ + if (out === undefined) { out = []; } + + var points = polygon.points; + var perimeter = Perimeter(polygon); + + // 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 / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var position = perimeter * (i / quantity); + var accumulatedPerimeter = 0; + + for (var j = 0; j < points.length; j++) + { + var pointA = points[j]; + var pointB = points[(j + 1) % points.length]; + var line = new Line( + pointA.x, + pointA.y, + pointB.x, + pointB.y + ); + var length = Length(line); + + if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) + { + accumulatedPerimeter += length; + continue; + } + + var point = line.getPoint((position - accumulatedPerimeter) / length); + out.push(point); + + break; + } + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 465 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Line = __webpack_require__(45); + +/** + * Returns the perimeter of the given Polygon. + * + * @function Phaser.Geom.Polygon.Perimeter + * @since 3.12.0 + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the perimeter of. + * + * @return {number} The perimeter of the Polygon. + */ +var Perimeter = function (polygon) +{ + var points = polygon.points; + var perimeter = 0; + + for (var i = 0; i < points.length; i++) + { + var pointA = points[i]; + var pointB = points[(i + 1) % points.length]; + var line = new Line( + pointA.x, + pointA.y, + pointB.x, + pointB.y + ); + + perimeter += Length(line); + } + + return perimeter; +}; + +module.exports = Perimeter; + + +/***/ }), +/* 466 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @author Igor Ognichenko + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @ignore + */ +var copy = function (out, a) +{ + out[0] = a[0]; + out[1] = a[1]; + + return out; +}; + +/** + * Takes a Polygon object and applies Chaikin's smoothing algorithm on its points. + * + * @function Phaser.Geom.Polygon.Smooth + * @since 3.13.0 + * + * @generic {Phaser.Geom.Polygon} O - [polygon,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The polygon to be smoothed. The polygon will be modified in-place and returned. + * + * @return {Phaser.Geom.Polygon} The input polygon. + */ +var Smooth = function (polygon) +{ + var i; + var points = []; + var data = polygon.points; + + for (i = 0; i < data.length; i++) + { + points.push([ data[i].x, data[i].y ]); + } + + var output = []; + + if (points.length > 0) + { + output.push(copy([ 0, 0 ], points[0])); + } + + for (i = 0; i < points.length - 1; i++) + { + var p0 = points[i]; + var p1 = points[i + 1]; + var p0x = p0[0]; + var p0y = p0[1]; + var p1x = p1[0]; + var p1y = p1[1]; + + output.push([ 0.85 * p0x + 0.15 * p1x, 0.85 * p0y + 0.15 * p1y ]); + output.push([ 0.15 * p0x + 0.85 * p1x, 0.15 * p0y + 0.85 * p1y ]); + } + + if (points.length > 1) + { + output.push(copy([ 0, 0 ], points[points.length - 1])); + } + + return polygon.setTo(output); +}; + +module.exports = Smooth; + + +/***/ }), +/* 467 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GeomRectangle = __webpack_require__(10); +var Shape = __webpack_require__(32); +var RectangleRender = __webpack_require__(1115); + +/** + * @classdesc + * The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * You can change the size of the rectangle by changing the `width` and `height` properties. + * + * @class Rectangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 - The horizontal position of this Game Object in the world. + * @param {number} y - The vertical position of this Game Object in the world. + * @param {number} [width=128] - The width of the rectangle. + * @param {number} [height=128] - The height of the rectangle. + * @param {number} [fillColor] - The color the rectangle will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Rectangle = new Class({ + + Extends: Shape, + + Mixins: [ + RectangleRender + ], + + initialize: + + function Rectangle (scene, x, y, width, height, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + + Shape.call(this, scene, 'Rectangle', new GeomRectangle(0, 0, width, height)); + + this.setPosition(x, y); + this.setSize(width, height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * 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.Rectangle#setSize + * @since 3.13.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; + + this.geom.setSize(width, height); + + this.updateData(); + + return this; + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Rectangle#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var rect = this.geom; + var line = this._tempLine; + + rect.getLineA(line); + + path.push(line.x1, line.y1, line.x2, line.y2); + + rect.getLineB(line); + + path.push(line.x2, line.y2); + + rect.getLineC(line); + + path.push(line.x2, line.y2); + + rect.getLineD(line); + + path.push(line.x2, line.y2); + + this.pathData = path; + + return this; + } + +}); + +module.exports = Rectangle; + + +/***/ }), +/* 468 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var StarRender = __webpack_require__(1118); +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Star Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * As the name implies, the Star shape will display a star in your game. You can control several + * aspects of it including the number of points that constitute the star. The default is 5. If + * you change it to 4 it will render as a diamond. If you increase them, you'll get a more spiky + * star shape. + * + * You can also control the inner and outer radius, which is how 'long' each point of the star is. + * Modify these values to create more interesting shapes. + * + * @class Star + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [points=5] - The number of points on the star. + * @param {number} [innerRadius=32] - The inner radius of the star. + * @param {number} [outerRadius=64] - The outer radius of the star. + * @param {number} [fillColor] - The color the star will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Star = new Class({ + + Extends: Shape, + + Mixins: [ + StarRender + ], + + initialize: + + function Star (scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (points === undefined) { points = 5; } + if (innerRadius === undefined) { innerRadius = 32; } + if (outerRadius === undefined) { outerRadius = 64; } + + Shape.call(this, scene, 'Star', null); + + /** + * Private internal value. + * The number of points in the star. + * + * @name Phaser.GameObjects.Star#_points + * @type {number} + * @private + * @since 3.13.0 + */ + this._points = points; + + /** + * Private internal value. + * The inner radius of the star. + * + * @name Phaser.GameObjects.Star#_innerRadius + * @type {number} + * @private + * @since 3.13.0 + */ + this._innerRadius = innerRadius; + + /** + * Private internal value. + * The outer radius of the star. + * + * @name Phaser.GameObjects.Star#_outerRadius + * @type {number} + * @private + * @since 3.13.0 + */ + this._outerRadius = outerRadius; + + this.setPosition(x, y); + this.setSize(outerRadius * 2, outerRadius * 2); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Sets the number of points that make up the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setPoints + * @since 3.13.0 + * + * @param {number} value - The amount of points the Star will have. + * + * @return {this} This Game Object instance. + */ + setPoints: function (value) + { + this._points = value; + + return this.updateData(); + }, + + /** + * Sets the inner radius of the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setInnerRadius + * @since 3.13.0 + * + * @param {number} value - The amount to set the inner radius to. + * + * @return {this} This Game Object instance. + */ + setInnerRadius: function (value) + { + this._innerRadius = value; + + return this.updateData(); + }, + + /** + * Sets the outer radius of the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setOuterRadius + * @since 3.13.0 + * + * @param {number} value - The amount to set the outer radius to. + * + * @return {this} This Game Object instance. + */ + setOuterRadius: function (value) + { + this._outerRadius = value; + + return this.updateData(); + }, + + /** + * The number of points that make up the Star shape. + * + * @name Phaser.GameObjects.Star#points + * @type {number} + * @default 5 + * @since 3.13.0 + */ + points: { + + get: function () + { + return this._points; + }, + + set: function (value) + { + this._points = value; + + this.updateData(); + } + + }, + + /** + * The inner radius of the Star shape. + * + * @name Phaser.GameObjects.Star#innerRadius + * @type {number} + * @default 32 + * @since 3.13.0 + */ + innerRadius: { + + get: function () + { + return this._innerRadius; + }, + + set: function (value) + { + this._innerRadius = value; + + this.updateData(); + } + + }, + + /** + * The outer radius of the Star shape. + * + * @name Phaser.GameObjects.Star#outerRadius + * @type {number} + * @default 64 + * @since 3.13.0 + */ + outerRadius: { + + get: function () + { + return this._outerRadius; + }, + + set: function (value) + { + this._outerRadius = value; + + this.updateData(); + } + + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Star#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + + var points = this._points; + var innerRadius = this._innerRadius; + var outerRadius = this._outerRadius; + + var rot = Math.PI / 2 * 3; + var step = Math.PI / points; + + // So origin 0.5 = the center of the star + var x = outerRadius; + var y = outerRadius; + + path.push(x, y + -outerRadius); + + for (var i = 0; i < points; i++) + { + path.push(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius); + + rot += step; + + path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius); + + rot += step; + } + + path.push(x, y + -outerRadius); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Star; + + +/***/ }), +/* 469 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GeomTriangle = __webpack_require__(82); +var TriangleRender = __webpack_require__(1121); + +/** + * @classdesc + * The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * The Triangle consists of 3 lines, joining up to form a triangular shape. You can control the + * position of each point of these lines. The triangle is always closed and cannot have an open + * face. If you require that, consider using a Polygon instead. + * + * @class Triangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [x1=0] - The horizontal position of the first point in the triangle. + * @param {number} [y1=128] - The vertical position of the first point in the triangle. + * @param {number} [x2=64] - The horizontal position of the second point in the triangle. + * @param {number} [y2=0] - The vertical position of the second point in the triangle. + * @param {number} [x3=128] - The horizontal position of the third point in the triangle. + * @param {number} [y3=128] - The vertical position of the third point in the triangle. + * @param {number} [fillColor] - The color the triangle will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Triangle = new Class({ + + Extends: Shape, + + Mixins: [ + TriangleRender + ], + + initialize: + + function Triangle (scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 128; } + if (x2 === undefined) { x2 = 64; } + if (y2 === undefined) { y2 = 0; } + if (x3 === undefined) { x3 = 128; } + if (y3 === undefined) { y3 = 128; } + + Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); + + var width = this.geom.right - this.geom.left; + var height = this.geom.bottom - this.geom.top; + + this.setPosition(x, y); + this.setSize(width, height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Sets the data for the lines that make up this Triangle shape. + * + * @method Phaser.GameObjects.Triangle#setTo + * @since 3.13.0 + * + * @param {number} [x1=0] - The horizontal position of the first point in the triangle. + * @param {number} [y1=0] - The vertical position of the first point in the triangle. + * @param {number} [x2=0] - The horizontal position of the second point in the triangle. + * @param {number} [y2=0] - The vertical position of the second point in the triangle. + * @param {number} [x3=0] - The horizontal position of the third point in the triangle. + * @param {number} [y3=0] - The vertical position of the third point in the triangle. + * + * @return {this} This Game Object instance. + */ + setTo: function (x1, y1, x2, y2, x3, y3) + { + this.geom.setTo(x1, y1, x2, y2, x3, y3); + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Triangle#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var tri = this.geom; + var line = this._tempLine; + + tri.getLineA(line); + + path.push(line.x1, line.y1, line.x2, line.y2); + + tri.getLineB(line); + + path.push(line.x2, line.y2); + + tri.getLineC(line); + + path.push(line.x2, line.y2); + + this.pathData = path; + + return this; + } + +}); + +module.exports = Triangle; + + +/***/ }), +/* 470 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); +var Length = __webpack_require__(64); + +/** + * Returns a Point from around the perimeter of a Triangle. + * + * @function Phaser.Geom.Triangle.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the point on its perimeter from. + * @param {number} position - The position along the perimeter of the triangle. A value between 0 and 1. + * @param {(Phaser.Geom.Point|object)} [out] - An option Point, or Point-like object to store the value in. If not given a new Point will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point object containing the given position from the perimeter of the triangle. + */ +var GetPoint = function (triangle, position, out) +{ + if (out === undefined) { out = new Point(); } + + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); + + if (position <= 0 || position >= 1) + { + out.x = line1.x1; + out.y = line1.y1; + + return out; + } + + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); + + var perimeter = length1 + length2 + length3; + + var p = perimeter * position; + var localPosition = 0; + + // Which line is it on? + + if (p < length1) + { + // Line 1 + localPosition = p / length1; + + out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; + } + else if (p > length1 + length2) + { + // Line 3 + p -= length1 + length2; + localPosition = p / length3; + + out.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; + out.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; + } + else + { + // Line 2 + p -= length1; + localPosition = p / length2; + + out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } + + return out; +}; + +module.exports = GetPoint; + + +/***/ }), +/* 471 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Point = __webpack_require__(4); + +/** + * Returns an array of evenly spaced points on the perimeter of a Triangle. + * + * @function Phaser.Geom.Triangle.GetPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the points from. + * @param {number} quantity - The number of evenly spaced points to return. Set to 0 to return an arbitrary number of points based on the `stepRate`. + * @param {number} stepRate - If `quantity` is 0, the distance between each returned point. + * @param {(array|Phaser.Geom.Point[])} [out] - An array to which the points should be appended. + * + * @return {(array|Phaser.Geom.Point[])} The modified `out` array, or a new array if none was provided. + */ +var GetPoints = function (triangle, quantity, stepRate, out) +{ + if (out === undefined) { out = []; } + + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); + + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); + + var perimeter = length1 + length2 + length3; + + // 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 / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var p = perimeter * (i / quantity); + var localPosition = 0; + + var point = new Point(); + + // Which line is it on? + + if (p < length1) + { + // Line 1 + localPosition = p / length1; + + point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; + } + else if (p > length1 + length2) + { + // Line 3 + p -= length1 + length2; + localPosition = p / length3; + + point.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; + point.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; + } + else + { + // Line 2 + p -= length1; + localPosition = p / length2; + + point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } + + out.push(point); + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 472 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets a value in an object, allowing for dot notation to control the depth of the property. + * + * For example: + * + * ```javascript + * var data = { + * world: { + * position: { + * x: 200, + * y: 100 + * } + * } + * }; + * + * SetValue(data, 'world.position.y', 300); + * + * console.log(data.world.position.y); // 300 + * ``` + * + * @function Phaser.Utils.Objects.SetValue + * @since 3.17.0 + * + * @param {object} source - The object to set the value in. + * @param {string} key - The name of the property in the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) + * @param {any} value - The value to set into the property, if found in the source object. + * + * @return {boolean} `true` if the property key was valid and the value was set, otherwise `false`. + */ +var SetValue = function (source, key, value) +{ + if (!source || typeof source === 'number') + { + return false; + } + else if (source.hasOwnProperty(key)) + { + source[key] = value; + + return true; + } + else if (key.indexOf('.') !== -1) + { + var keys = key.split('.'); + var parent = source; + var prev = source; + + // 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 + prev = parent; + parent = parent[keys[i]]; + } + else + { + return false; + } + } + + prev[keys[keys.length - 1]] = value; + + return true; + } + + return false; +}; + +module.exports = SetValue; + + +/***/ }), +/* 473 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Face = __webpack_require__(113); +var Vertex = __webpack_require__(115); + +/** + * Generates a set of Face and Vertex objects by parsing the given data. + * + * This method will take vertex data in one of two formats, based on the `containsZ` parameter. + * + * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default) + * + * If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true. + * + * The `uvs` parameter is a numeric array consisting of `u` and `v` pairs. + * + * The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well. + * + * The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added. + * + * The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created. + * + * The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created. + * + * When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices. + * + * The following example will create a 256 x 256 sized quad using an index array: + * + * ```javascript + * const vertices = [ + * -128, 128, + * 128, 128, + * -128, -128, + * 128, -128 + * ]; + * + * const uvs = [ + * 0, 1, + * 1, 1, + * 0, 0, + * 1, 0 + * ]; + * + * const indices = [ 0, 2, 1, 2, 3, 1 ]; + * + * GenerateVerts(vertices, uvs, indicies); + * ``` + * + * If the data is not indexed, it's assumed that the arrays all contain sequential data. + * + * @function Phaser.Geom.Mesh.GenerateVerts + * @since 3.50.0 + * + * @param {number[]} vertices - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. + * @param {number[]} uvs - The UVs pairs array. + * @param {number[]} [indicies] - Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + * @param {boolean} [containsZ=false] - Does the vertices data include a `z` component? + * @param {number[]} [normals] - Optional vertex normals array. If you don't have one, pass `null` or an empty array. + * @param {number|number[]} [colors=0xffffff] - An array of colors, one per vertex, or a single color value applied to all vertices. + * @param {number|number[]} [alphas=1] - An array of alpha values, one per vertex, or a single alpha value applied to all vertices. + * + * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. + */ +var GenerateVerts = function (vertices, uvs, indicies, containsZ, normals, colors, alphas) +{ + if (containsZ === undefined) { containsZ = false; } + if (colors === undefined) { colors = 0xffffff; } + if (alphas === undefined) { alphas = 1; } + + if (vertices.length !== uvs.length) + { + console.warn('GenerateVerts: vertices and uvs count not equal'); + return; + } + + var result = { + faces: [], + verts: [] + }; + + var i; + + var x; + var y; + var z; + + var u; + var v; + + var color; + var alpha; + + var normalX; + var normalY; + var normalZ; + + var iInc = (containsZ) ? 3 : 2; + + var isColorArray = Array.isArray(colors); + var isAlphaArray = Array.isArray(alphas); + + if (Array.isArray(indicies) && indicies.length > 0) + { + for (i = 0; i < indicies.length; i++) + { + var index1 = indicies[i]; + var index2 = indicies[i] * 2; + var index3 = indicies[i] * iInc; + + x = vertices[index3]; + y = vertices[index3 + 1]; + z = (containsZ) ? vertices[index3 + 2] : 0; + + u = uvs[index2]; + v = uvs[index2 + 1]; + + color = (isColorArray) ? colors[index1] : colors; + alpha = (isAlphaArray) ? alphas[index1] : alphas; + + normalX = 0; + normalY = 0; + normalZ = 0; + + if (normals) + { + normalX = normals[index3]; + normalY = normals[index3 + 1]; + normalZ = (containsZ) ? normals[index3 + 2] : 0; + } + + result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + } + } + else + { + var uvIndex = 0; + var colorIndex = 0; + + for (i = 0; i < vertices.length; i += iInc) + { + x = vertices[i]; + y = vertices[i + 1]; + z = (containsZ) ? vertices[i + 2] : 0; + + u = uvs[uvIndex]; + v = uvs[uvIndex + 1]; + + color = (isColorArray) ? colors[colorIndex] : colors; + alpha = (isAlphaArray) ? alphas[colorIndex] : alphas; + + normalX = 0; + normalY = 0; + normalZ = 0; + + if (normals) + { + normalX = normals[i]; + normalY = normals[i + 1]; + normalZ = (containsZ) ? normals[i + 2] : 0; + } + + result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + + uvIndex += 2; + colorIndex++; + } + } + + for (i = 0; i < result.verts.length; i += 3) + { + var vert1 = result.verts[i]; + var vert2 = result.verts[i + 1]; + var vert3 = result.verts[i + 2]; + + result.faces.push(new Face(vert1, vert2, vert3)); + } + + return result; +}; + +module.exports = GenerateVerts; + + +/***/ }), +/* 474 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Face = __webpack_require__(113); +var Matrix4 = __webpack_require__(67); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); + +var tempPosition = new Vector3(); +var tempRotation = new Vector3(); +var tempMatrix = new Matrix4(); + +/** + * This method will return an object containing Face and Vertex instances, generated + * from the parsed triangulated OBJ Model data given to this function. + * + * The obj data should have been parsed in advance via the ParseObj function: + * + * ```javascript + * var data = Phaser.Geom.Mesh.ParseObj(rawData, flipUV); + * + * var results = GenerateObjVerts(data); + * ``` + * + * Alternatively, you can parse obj files loaded via the OBJFile loader: + * + * ```javascript + * preload () + * { + * this.load.obj('alien', 'assets/3d/alien.obj); + * } + * + * var results = GenerateObjVerts(this.cache.obj.get('alien)); + * ``` + * + * Make sure your 3D package has triangulated the model data prior to exporting it. + * + * You can use the data returned by this function to populate the vertices of a Mesh Game Object. + * + * You may add multiple models to a single Mesh, although they will act as one when + * moved or rotated. You can scale the model data, should it be too small (or large) to visualize. + * You can also offset the model via the `x`, `y` and `z` parameters. + * + * @function Phaser.Geom.Mesh.GenerateObjVerts + * @since 3.50.0 + * + * @param {Phaser.Types.Geom.Mesh.OBJData} data - The parsed OBJ model data. + * @param {Phaser.GameObjects.Mesh} [mesh] - An optional Mesh Game Object. If given, the generated Faces will be automatically added to this Mesh. Set to `null` to skip. + * @param {number} [scale=1] - An amount to scale the model data by. Use this if the model has exported too small, or large, to see. + * @param {number} [x=0] - Translate the model x position by this amount. + * @param {number} [y=0] - Translate the model y position by this amount. + * @param {number} [z=0] - Translate the model z position by this amount. + * @param {number} [rotateX=0] - Rotate the model on the x axis by this amount, in radians. + * @param {number} [rotateY=0] - Rotate the model on the y axis by this amount, in radians. + * @param {number} [rotateZ=0] - Rotate the model on the z axis by this amount, in radians. + * @param {boolean} [zIsUp=true] - Is the z axis up (true), or is y axis up (false)? + * + * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. + */ +var GenerateObjVerts = function (data, mesh, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) +{ + if (scale === undefined) { scale = 1; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (z === undefined) { z = 0; } + if (rotateX === undefined) { rotateX = 0; } + if (rotateY === undefined) { rotateY = 0; } + if (rotateZ === undefined) { rotateZ = 0; } + if (zIsUp === undefined) { zIsUp = true; } + + var result = { + faces: [], + verts: [] + }; + + var materials = data.materials; + + tempPosition.set(x, y, z); + tempRotation.set(rotateX, rotateY, rotateZ); + tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); + + for (var m = 0; m < data.models.length; m++) + { + var model = data.models[m]; + + var vertices = model.vertices; + var textureCoords = model.textureCoords; + var faces = model.faces; + + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; + + var v1 = face.vertices[0]; + var v2 = face.vertices[1]; + var v3 = face.vertices[2]; + + var m1 = vertices[v1.vertexIndex]; + var m2 = vertices[v2.vertexIndex]; + var m3 = vertices[v3.vertexIndex]; + + var t1 = v1.textureCoordsIndex; + var t2 = v2.textureCoordsIndex; + var t3 = v3.textureCoordsIndex; + + var uv1 = (t1 === -1) ? { u: 0, v: 1 } : textureCoords[t1]; + var uv2 = (t2 === -1) ? { u: 0, v: 0 } : textureCoords[t2]; + var uv3 = (t3 === -1) ? { u: 1, v: 1 } : textureCoords[t3]; + + var color = 0xffffff; + + if (face.material !== '' && materials[face.material]) + { + color = materials[face.material]; + } + + var vert1 = new Vertex(m1.x * scale, m1.y * scale, m1.z * scale, uv1.u, uv1.v, color).transformMat4(tempMatrix); + var vert2 = new Vertex(m2.x * scale, m2.y * scale, m2.z * scale, uv2.u, uv2.v, color).transformMat4(tempMatrix); + var vert3 = new Vertex(m3.x * scale, m3.y * scale, m3.z * scale, uv3.u, uv3.v, color).transformMat4(tempMatrix); + + result.verts.push(vert1, vert2, vert3); + result.faces.push(new Face(vert1, vert2, vert3)); + } + } + + if (mesh) + { + mesh.faces = mesh.faces.concat(result.faces); + mesh.vertices = mesh.vertices.concat(result.verts); + } + + return result; +}; + +module.exports = GenerateObjVerts; + + +/***/ }), +/* 475 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circle = __webpack_require__(62); +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var RGB = __webpack_require__(197); +var Utils = __webpack_require__(12); + +/** + * @classdesc + * A 2D point light. + * + * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. + * + * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. + * + * They can also simply be used to represent a point light for your own purposes. + * + * @class Light + * @extends Phaser.Geom.Circle + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Visible + * + * @param {number} x - The horizontal position of the light. + * @param {number} y - The vertical position of the light. + * @param {number} radius - The radius of the light. + * @param {number} r - The red color of the light. A value between 0 and 1. + * @param {number} g - The green color of the light. A value between 0 and 1. + * @param {number} b - The blue color of the light. A value between 0 and 1. + * @param {number} intensity - The intensity of the light. + */ +var Light = new Class({ + + Extends: Circle, + + Mixins: [ + Components.ScrollFactor, + Components.Visible + ], + + initialize: + + function Light (x, y, radius, r, g, b, intensity) + { + Circle.call(this, x, y, radius); + + /** + * The color of the light. + * + * @name Phaser.GameObjects.Light#color + * @type {Phaser.Display.RGB} + * @since 3.50.0 + */ + this.color = new RGB(r, g, b); + + /** + * The intensity of the light. + * + * @name Phaser.GameObjects.Light#intensity + * @type {number} + * @since 3.50.0 + */ + this.intensity = intensity; + + /** + * 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 {number} + * @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; + + this.setScrollFactor(1, 1); + }, + + /** + * 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.Light#willRender + * @since 3.50.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 !(Light.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + }, + + /** + * Set the color of the light from a single integer RGB value. + * + * @method Phaser.GameObjects.Light#setColor + * @since 3.0.0 + * + * @param {number} rgb - The integer RGB color of the light. + * + * @return {this} This Light object. + */ + setColor: function (rgb) + { + var color = Utils.getFloatsFromUintRGB(rgb); + + this.color.set(color[0], color[1], color[2]); + + return this; + }, + + /** + * Set the intensity of the light. + * + * @method Phaser.GameObjects.Light#setIntensity + * @since 3.0.0 + * + * @param {number} intensity - The intensity of the light. + * + * @return {this} This Light object. + */ + setIntensity: function (intensity) + { + this.intensity = intensity; + + return this; + }, + + /** + * Set the radius of the light. + * + * @method Phaser.GameObjects.Light#setRadius + * @since 3.0.0 + * + * @param {number} radius - The radius of the light. + * + * @return {this} This Light object. + */ + setRadius: function (radius) + { + this.radius = radius; + + return this; + } + +}); + +/** + * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + * + * @constant {number} RENDER_MASK + * @memberof Phaser.GameObjects.Light + * @default + */ +Light.RENDER_MASK = 15; + +module.exports = Light; + + +/***/ }), +/* 476 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircleToRectangle = __webpack_require__(150); +var Class = __webpack_require__(0); +var DistanceBetween = __webpack_require__(48); +var Light = __webpack_require__(475); +var PointLight = __webpack_require__(149); +var RGB = __webpack_require__(197); +var SpliceOne = __webpack_require__(74); +var StableSort = __webpack_require__(79); +var Utils = __webpack_require__(12); + +/** + * @callback LightForEach + * + * @param {Phaser.GameObjects.Light} light - The Light. + */ + +/** + * @classdesc + * Manages Lights for a Scene. + * + * Affects the rendering of Game Objects using the `Light2D` pipeline. + * + * @class LightsManager + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + */ +var LightsManager = new Class({ + + initialize: + + function LightsManager () + { + /** + * The Lights in the Scene. + * + * @name Phaser.GameObjects.LightsManager#lights + * @type {Phaser.GameObjects.Light[]} + * @default [] + * @since 3.0.0 + */ + this.lights = []; + + /** + * The ambient color. + * + * @name Phaser.GameObjects.LightsManager#ambientColor + * @type {Phaser.Display.RGB} + * @since 3.50.0 + */ + this.ambientColor = new RGB(0.1, 0.1, 0.1); + + /** + * Whether the Lights Manager is enabled. + * + * @name Phaser.GameObjects.LightsManager#active + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.active = false; + + /** + * The maximum number of lights that a single Camera and the lights shader can process. + * Change this via the `maxLights` property in your game config, as it cannot be changed at runtime. + * + * @name Phaser.GameObjects.LightsManager#maxLights + * @type {number} + * @readonly + * @since 3.15.0 + */ + this.maxLights = -1; + + /** + * The number of lights that the LightPipeline processed in the _previous_ frame. + * + * @name Phaser.GameObjects.LightsManager#visibleLights + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.visibleLights = 0; + }, + + addPointLight: function (x, y, color, radius, intensity) + { + return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity)); + }, + + /** + * Enable the Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#enable + * @since 3.0.0 + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + enable: function () + { + if (this.maxLights === -1) + { + this.maxLights = this.scene.sys.renderer.config.maxLights; + } + + this.active = true; + + return this; + }, + + /** + * Disable the Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#disable + * @since 3.0.0 + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + disable: function () + { + this.active = false; + + return this; + }, + + /** + * Get all lights that can be seen by the given Camera. + * + * It will automatically cull lights that are outside the world view of the Camera. + * + * If more lights are returned than supported by the pipeline, the lights are then culled + * based on the distance from the center of the camera. Only those closest are rendered. + * + * @method Phaser.GameObjects.LightsManager#getLights + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. + * + * @return {Phaser.GameObjects.Light[]} The culled Lights. + */ + getLights: function (camera) + { + var lights = this.lights; + var worldView = camera.worldView; + + var visibleLights = []; + + for (var i = 0; i < lights.length; i++) + { + var light = lights[i]; + + if (light.willRender(camera) && CircleToRectangle(light, worldView)) + { + visibleLights.push({ + light: light, + distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY) + }); + } + } + + if (visibleLights.length > this.maxLights) + { + // We've got too many lights, so sort by distance from camera and cull those far away + // This isn't ideal because it doesn't factor in the radius of the lights, but it'll do for now + // and is significantly better than we had before! + + StableSort(visibleLights, this.sortByDistance); + + visibleLights = visibleLights.slice(0, this.maxLights); + } + + this.visibleLights = visibleLights.length; + + return visibleLights; + }, + + sortByDistance: function (a, b) + { + return (a.distance >= b.distance); + }, + + /** + * Set the ambient light color. + * + * @method Phaser.GameObjects.LightsManager#setAmbientColor + * @since 3.0.0 + * + * @param {number} rgb - The integer RGB color of the ambient light. + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + setAmbientColor: function (rgb) + { + var color = Utils.getFloatsFromUintRGB(rgb); + + this.ambientColor.set(color[0], color[1], color[2]); + + return this; + }, + + /** + * Returns the maximum number of Lights allowed to appear at once. + * + * @method Phaser.GameObjects.LightsManager#getMaxVisibleLights + * @since 3.0.0 + * + * @return {number} The maximum number of Lights allowed to appear at once. + */ + getMaxVisibleLights: function () + { + return this.maxLights; + }, + + /** + * Get the number of Lights managed by this Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#getLightCount + * @since 3.0.0 + * + * @return {number} The number of Lights managed by this Lights Manager. + */ + getLightCount: function () + { + return this.lights.length; + }, + + /** + * Add a Light. + * + * @method Phaser.GameObjects.LightsManager#addLight + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal position of the Light. + * @param {number} [y=0] - The vertical position of the Light. + * @param {number} [radius=100] - The radius of the Light. + * @param {number} [rgb=0xffffff] - The integer RGB color of the light. + * @param {number} [intensity=1] - The intensity of the Light. + * + * @return {Phaser.GameObjects.Light} The Light that was added. + */ + addLight: function (x, y, radius, rgb, intensity) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 128; } + if (rgb === undefined) { rgb = 0xffffff; } + if (intensity === undefined) { intensity = 1; } + + var color = Utils.getFloatsFromUintRGB(rgb); + + var light = new Light(x, y, radius, color[0], color[1], color[2], intensity); + + this.lights.push(light); + + return light; + }, + + /** + * Remove a Light. + * + * @method Phaser.GameObjects.LightsManager#removeLight + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Light} light - The Light to remove. + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + removeLight: function (light) + { + var index = this.lights.indexOf(light); + + if (index >= 0) + { + SpliceOne(this.lights, index); + } + + return this; + }, + + /** + * Shut down the Lights Manager. + * + * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and + * culled Lights. + * + * @method Phaser.GameObjects.LightsManager#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + this.lights.length = 0; + }, + + /** + * Destroy the Lights Manager. + * + * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. + * + * @method Phaser.GameObjects.LightsManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + } + +}); + +module.exports = LightsManager; + + +/***/ }), +/* 477 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(55); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Geom + */ + +var Geom = { + + Circle: __webpack_require__(1185), + Ellipse: __webpack_require__(1195), + Intersects: __webpack_require__(478), + Line: __webpack_require__(1215), + Mesh: __webpack_require__(1237), + Point: __webpack_require__(1240), + Polygon: __webpack_require__(1254), + Rectangle: __webpack_require__(496), + Triangle: __webpack_require__(1287) + +}; + +// Merge in the consts +Geom = Extend(false, Geom, CONST); + +module.exports = Geom; + + +/***/ }), +/* 478 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Geom.Intersects + */ + +module.exports = { + + CircleToCircle: __webpack_require__(228), + CircleToRectangle: __webpack_require__(150), + GetCircleToCircle: __webpack_require__(1205), + GetCircleToRectangle: __webpack_require__(1206), + GetLineToCircle: __webpack_require__(229), + GetLineToLine: __webpack_require__(479), + GetLineToPoints: __webpack_require__(480), + GetLineToPolygon: __webpack_require__(481), + GetLineToRectangle: __webpack_require__(231), + GetRaysFromPointToPolygon: __webpack_require__(1207), + GetRectangleIntersection: __webpack_require__(1208), + GetRectangleToRectangle: __webpack_require__(1209), + GetRectangleToTriangle: __webpack_require__(1210), + GetTriangleToCircle: __webpack_require__(1211), + GetTriangleToLine: __webpack_require__(486), + GetTriangleToTriangle: __webpack_require__(1212), + LineToCircle: __webpack_require__(230), + LineToLine: __webpack_require__(92), + LineToRectangle: __webpack_require__(482), + PointToLine: __webpack_require__(490), + PointToLineSegment: __webpack_require__(1213), + RectangleToRectangle: __webpack_require__(114), + RectangleToTriangle: __webpack_require__(483), + RectangleToValues: __webpack_require__(1214), + TriangleToCircle: __webpack_require__(485), + TriangleToLine: __webpack_require__(487), + TriangleToTriangle: __webpack_require__(488) + +}; + + +/***/ }), +/* 479 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); + +/** + * Checks for intersection between the two line segments and returns the intersection point as a Vector3, + * or `null` if the lines are parallel, or do not intersect. + * + * The `z` property of the Vector3 contains the intersection distance, which can be used to find + * the closest intersecting point from a group of line segments. + * + * @function Phaser.Geom.Intersects.GetLineToLine + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line1 - The first line segment to check. + * @param {Phaser.Geom.Line} line2 - The second line segment to check. + * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. + * + * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. + */ +var GetLineToLine = function (line1, line2, out) +{ + var x1 = line1.x1; + var y1 = line1.y1; + var x2 = line1.x2; + var y2 = line1.y2; + + var x3 = line2.x1; + var y3 = line2.y1; + var x4 = line2.x2; + var y4 = line2.y2; + + var dx1 = x2 - x1; + var dy1 = y2 - y1; + + var dx2 = x4 - x3; + var dy2 = y4 - y3; + + var denom = dy2 * dx1 - dx2 * dy1; + + // Make sure there is not a division by zero - this also indicates that the lines are parallel. + // If numA and numB were both equal to zero the lines would be on top of each other (coincidental). + // This check is not done because it is not necessary for this implementation (the parallel check accounts for this). + + if (dx1 === 0 || denom === 0) + { + return false; + } + + var T2 = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); + var T1 = (x3 + dx2 * T2 - x1) / dx1; + + // Intersects? + if (T1 < 0 || T2 < 0 || T2 > 1) + { + return null; + } + + if (out === undefined) + { + out = new Vector3(); + } + + return out.set( + x1 + dx1 * T1, + y1 + dy1 * T1, + T1 + ); +}; + +module.exports = GetLineToLine; + + +/***/ }), +/* 480 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); +var GetLineToLine = __webpack_require__(479); +var Line = __webpack_require__(45); + +// Temp calculation segment +var segment = new Line(); + +// Temp vec3 +var tempIntersect = new Vector3(); + +/** + * Checks for the closest point of intersection between a line segment and an array of points, where each pair + * of points are converted to line segments for the intersection tests. + * + * If no intersection is found, this function returns `null`. + * + * If intersection was found, a Vector3 is returned with the following properties: + * + * The `x` and `y` components contain the point of the intersection. + * The `z` component contains the closest distance. + * + * @function Phaser.Geom.Intersects.GetLineToPoints + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Math.Vector2[] | Phaser.Geom.Point[]} points - An array of points to check. + * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. + * + * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. + */ +var GetLineToPoints = function (line, points, out) +{ + if (out === undefined) { out = new Vector3(); } + + var closestIntersect = false; + + // Reset our vec3s + out.set(); + tempIntersect.set(); + + var prev = points[0]; + + for (var i = 1; i < points.length; i++) + { + var current = points[i]; + + segment.setTo(prev.x, prev.y, current.x, current.y); + + prev = current; + + if (GetLineToLine(line, segment, tempIntersect)) + { + if (!closestIntersect || tempIntersect.z < out.z) + { + out.copy(tempIntersect); + + closestIntersect = true; + } + } + } + + return (closestIntersect) ? out : null; +}; + +module.exports = GetLineToPoints; + + +/***/ }), +/* 481 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); +var Vector4 = __webpack_require__(138); +var GetLineToPoints = __webpack_require__(480); + +// Temp vec3 +var tempIntersect = new Vector3(); + +/** + * Checks for the closest point of intersection between a line segment and an array of polygons. + * + * If no intersection is found, this function returns `null`. + * + * If intersection was found, a Vector4 is returned with the following properties: + * + * The `x` and `y` components contain the point of the intersection. + * The `z` component contains the closest distance. + * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. + * + * @function Phaser.Geom.Intersects.GetLineToPolygon + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check. + * @param {Phaser.Math.Vector4} [out] - A Vector4 to store the intersection results in. + * + * @return {Phaser.Math.Vector4} A Vector4 containing the intersection results, or `null`. + */ +var GetLineToPolygon = function (line, polygons, out) +{ + if (out === undefined) { out = new Vector4(); } + + if (!Array.isArray(polygons)) + { + polygons = [ polygons ]; + } + + var closestIntersect = false; + + // Reset our vec4s + out.set(); + tempIntersect.set(); + + for (var i = 0; i < polygons.length; i++) + { + if (GetLineToPoints(line, polygons[i].points, tempIntersect)) + { + if (!closestIntersect || tempIntersect.z < out.z) + { + out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); + + closestIntersect = true; + } + } + } + + return (closestIntersect) ? out : null; +}; + +module.exports = GetLineToPolygon; + + +/***/ }), +/* 482 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks for intersection between the Line and a Rectangle shape, or a rectangle-like + * object, with public `x`, `y`, `right` and `bottom` properties, such as a Sprite or Body. + * + * An intersection is considered valid if: + * + * The line starts within, or ends within, the Rectangle. + * The line segment intersects one of the 4 rectangle edges. + * + * The for the purposes of this function rectangles are considered 'solid'. + * + * @function Phaser.Geom.Intersects.LineToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The Line to check for intersection. + * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle to check for intersection. + * + * @return {boolean} `true` if the Line and the Rectangle intersect, `false` otherwise. + */ +var LineToRectangle = function (line, rect) +{ + var x1 = line.x1; + var y1 = line.y1; + + var x2 = line.x2; + var y2 = line.y2; + + var bx1 = rect.x; + var by1 = rect.y; + var bx2 = rect.right; + var by2 = rect.bottom; + + var t = 0; + + // If the start or end of the line is inside the rect then we assume + // collision, as rects are solid for our use-case. + + if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || + (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) + { + return true; + } + + if (x1 < bx1 && x2 >= bx1) + { + // Left edge + t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); + + if (t > by1 && t <= by2) + { + return true; + } + } + else if (x1 > bx2 && x2 <= bx2) + { + // Right edge + t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); + + if (t >= by1 && t <= by2) + { + return true; + } + } + + if (y1 < by1 && y2 >= by1) + { + // Top edge + t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) + { + return true; + } + } + else if (y1 > by2 && y2 <= by2) + { + // Bottom edge + t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) + { + return true; + } + } + + return false; +}; + +module.exports = LineToRectangle; + + +/***/ }), +/* 483 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToLine = __webpack_require__(92); +var Contains = __webpack_require__(56); +var ContainsArray = __webpack_require__(232); +var Decompose = __webpack_require__(484); + +/** + * Checks for intersection between Rectangle shape and Triangle shape. + * + * @function Phaser.Geom.Intersects.RectangleToTriangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. + * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. + * + * @return {boolean} A value of `true` if objects intersect; otherwise `false`. + */ +var RectangleToTriangle = function (rect, triangle) +{ + // First the cheapest ones: + + if ( + triangle.left > rect.right || + triangle.right < rect.left || + triangle.top > rect.bottom || + triangle.bottom < rect.top) + { + return false; + } + + var triA = triangle.getLineA(); + var triB = triangle.getLineB(); + var triC = triangle.getLineC(); + + // Are any of the triangle points within the rectangle? + + if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) + { + return true; + } + + if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) + { + return true; + } + + if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) + { + return true; + } + + // Cheap tests over, now to see if any of the lines intersect ... + + var rectA = rect.getLineA(); + var rectB = rect.getLineB(); + var rectC = rect.getLineC(); + var rectD = rect.getLineD(); + + if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) + { + return true; + } + + if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) + { + return true; + } + + if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) + { + return true; + } + + // None of the lines intersect, so are any rectangle points within the triangle? + + var points = Decompose(rect); + var within = ContainsArray(triangle, points, true); + + return (within.length > 0); +}; + +module.exports = RectangleToTriangle; + + +/***/ }), +/* 484 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Create an array of points for each corner of a Rectangle + * If an array is specified, each point object will be added to the end of the array, otherwise a new array will be created. + * + * @function Phaser.Geom.Rectangle.Decompose + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle object to be decomposed. + * @param {array} [out] - If provided, each point will be added to this array. + * + * @return {array} Will return the array you specified or a new array containing the points of the Rectangle. + */ +var Decompose = function (rect, out) +{ + if (out === undefined) { out = []; } + + out.push({ x: rect.x, y: rect.y }); + out.push({ x: rect.right, y: rect.y }); + out.push({ x: rect.right, y: rect.bottom }); + out.push({ x: rect.x, y: rect.bottom }); + + return out; +}; + +module.exports = Decompose; + + +/***/ }), +/* 485 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToCircle = __webpack_require__(230); +var Contains = __webpack_require__(112); + +/** + * Checks if a Triangle and a Circle intersect. + * + * A Circle intersects a Triangle if its center is located within it or if any of the Triangle's sides intersect the Circle. As such, the Triangle and the Circle are considered "solid" for the intersection. + * + * @function Phaser.Geom.Intersects.TriangleToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check for intersection. + * @param {Phaser.Geom.Circle} circle - The Circle to check for intersection. + * + * @return {boolean} `true` if the Triangle and the `Circle` intersect, otherwise `false`. + */ +var TriangleToCircle = function (triangle, circle) +{ + // First the cheapest ones: + + if ( + triangle.left > circle.right || + triangle.right < circle.left || + triangle.top > circle.bottom || + triangle.bottom < circle.top) + { + return false; + } + + if (Contains(triangle, circle.x, circle.y)) + { + return true; + } + + if (LineToCircle(triangle.getLineA(), circle)) + { + return true; + } + + if (LineToCircle(triangle.getLineB(), circle)) + { + return true; + } + + if (LineToCircle(triangle.getLineC(), circle)) + { + return true; + } + + return false; +}; + +module.exports = TriangleToCircle; + + +/***/ }), +/* 486 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); +var TriangleToLine = __webpack_require__(487); +var LineToLine = __webpack_require__(92); + +/** + * Checks if a Triangle and a Line intersect, and returns the intersection points as a Point object array. + * + * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". + * + * @function Phaser.Geom.Intersects.GetTriangleToLine + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. + * @param {Phaser.Geom.Line} line - The Line to check with. + * @param {array} [out] - An optional array in which to store the points of intersection. + * + * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. + */ +var GetTriangleToLine = function (triangle, line, out) +{ + if (out === undefined) { out = []; } + + if (TriangleToLine(triangle, line)) + { + var lineA = triangle.getLineA(); + var lineB = triangle.getLineB(); + var lineC = triangle.getLineC(); + + var output = [ new Point(), new Point(), new Point() ]; + + var result = [ + LineToLine(lineA, line, output[0]), + LineToLine(lineB, line, output[1]), + LineToLine(lineC, line, output[2]) + ]; + + for (var i = 0; i < 3; i++) + { + if (result[i]) { out.push(output[i]); } + } + } + + return out; +}; + +module.exports = GetTriangleToLine; + + +/***/ }), +/* 487 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToLine = __webpack_require__(92); + +/** + * Checks if a Triangle and a Line intersect. + * + * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". + * + * @function Phaser.Geom.Intersects.TriangleToLine + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. + * @param {Phaser.Geom.Line} line - The Line to check with. + * + * @return {boolean} `true` if the Triangle and the Line intersect, otherwise `false`. + */ +var TriangleToLine = function (triangle, line) +{ + // If the Triangle contains either the start or end point of the line, it intersects + if (triangle.contains(line.x1, line.y1) || triangle.contains(line.x2, line.y2)) + { + return true; + } + + // Now check the line against each line of the Triangle + if (LineToLine(triangle.getLineA(), line)) + { + return true; + } + + if (LineToLine(triangle.getLineB(), line)) + { + return true; + } + + if (LineToLine(triangle.getLineC(), line)) + { + return true; + } + + return false; +}; + +module.exports = TriangleToLine; + + +/***/ }), +/* 488 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ContainsArray = __webpack_require__(232); +var Decompose = __webpack_require__(489); +var LineToLine = __webpack_require__(92); + +/** + * Checks if two Triangles intersect. + * + * A Triangle intersects another Triangle if any pair of their lines intersects or if any point of one Triangle is within the other Triangle. Thus, the Triangles are considered "solid". + * + * @function Phaser.Geom.Intersects.TriangleToTriangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangleA - The first Triangle to check for intersection. + * @param {Phaser.Geom.Triangle} triangleB - The second Triangle to check for intersection. + * + * @return {boolean} `true` if the Triangles intersect, otherwise `false`. + */ +var TriangleToTriangle = function (triangleA, triangleB) +{ + // First the cheapest ones: + + if ( + triangleA.left > triangleB.right || + triangleA.right < triangleB.left || + triangleA.top > triangleB.bottom || + triangleA.bottom < triangleB.top) + { + return false; + } + + var lineAA = triangleA.getLineA(); + var lineAB = triangleA.getLineB(); + var lineAC = triangleA.getLineC(); + + var lineBA = triangleB.getLineA(); + var lineBB = triangleB.getLineB(); + var lineBC = triangleB.getLineC(); + + // Now check the lines against each line of TriangleB + if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) + { + return true; + } + + if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) + { + return true; + } + + if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) + { + return true; + } + + // Nope, so check to see if any of the points of triangleA are within triangleB + + var points = Decompose(triangleA); + var within = ContainsArray(triangleB, points, true); + + if (within.length > 0) + { + return true; + } + + // Finally check to see if any of the points of triangleB are within triangleA + + points = Decompose(triangleB); + within = ContainsArray(triangleA, points, true); + + if (within.length > 0) + { + return true; + } + + return false; +}; + +module.exports = TriangleToTriangle; + + +/***/ }), +/* 489 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Decomposes a Triangle into an array of its points. + * + * @function Phaser.Geom.Triangle.Decompose + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to decompose. + * @param {array} [out] - An array to store the points into. + * + * @return {array} The provided `out` array, or a new array if none was provided, with three objects with `x` and `y` properties representing each point of the Triangle appended to it. + */ +var Decompose = function (triangle, out) +{ + if (out === undefined) { out = []; } + + out.push({ x: triangle.x1, y: triangle.y1 }); + out.push({ x: triangle.x2, y: triangle.y2 }); + out.push({ x: triangle.x3, y: triangle.y3 }); + + return out; +}; + +module.exports = Decompose; + + +/***/ }), +/* 490 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @author Florian Mertens + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if the a Point falls between the two end-points of a Line, based on the given line thickness. + * + * Assumes that the line end points are circular, not square. + * + * @function Phaser.Geom.Intersects.PointToLine + * @since 3.0.0 + * + * @param {(Phaser.Geom.Point|any)} point - The point, or point-like object to check. + * @param {Phaser.Geom.Line} line - The line segment to test for intersection on. + * @param {number} [lineThickness=1] - The line thickness. Assumes that the line end points are circular. + * + * @return {boolean} `true` if the Point falls on the Line, otherwise `false`. + */ +var PointToLine = function (point, line, lineThickness) +{ + if (lineThickness === undefined) { lineThickness = 1; } + + var x1 = line.x1; + var y1 = line.y1; + + var x2 = line.x2; + var y2 = line.y2; + + var px = point.x; + var py = point.y; + + var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); + + if (L2 === 0) + { + return false; + } + + var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; + + // Assume line thickness is circular + if (r < 0) + { + // Outside line1 + return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); + } + else if ((r >= 0) && (r <= 1)) + { + // On the line segment + var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; + + return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); + } + else + { + // Outside line2 + return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); + } +}; + +module.exports = PointToLine; + + +/***/ }), +/* 491 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MATH_CONST = __webpack_require__(14); +var Wrap = __webpack_require__(66); +var Angle = __webpack_require__(93); + +/** + * Get the angle of the normal of the given line in radians. + * + * @function Phaser.Geom.Line.NormalAngle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to calculate the angle of the normal of. + * + * @return {number} The angle of the normal of the line in radians. + */ +var NormalAngle = function (line) +{ + var angle = Angle(line) - MATH_CONST.TAU; + + return Wrap(angle, -Math.PI, Math.PI); +}; + +module.exports = NormalAngle; + + +/***/ }), +/* 492 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var flip = true; + +var defaultModelName = 'untitled'; +var currentGroup = ''; +var currentMaterial = ''; + +/** + * @ignore + */ +function stripComments (line) +{ + var idx = line.indexOf('#'); + + return (idx > -1) ? line.substring(0, idx) : line; +} + +/** + * @ignore + */ +function currentModel (result) +{ + if (result.models.length === 0) + { + result.models.push({ + faces: [], + name: defaultModelName, + textureCoords: [], + vertexNormals: [], + vertices: [] + }); + } + + currentGroup = ''; + + return result.models[result.models.length - 1]; +} + +/** + * @ignore + */ +function parseObject (lineItems, result) +{ + var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName; + + result.models.push({ + faces: [], + name: modelName, + textureCoords: [], + vertexNormals: [], + vertices: [] + }); + + currentGroup = ''; +} + +/** + * @ignore + */ +function parseGroup (lineItems) +{ + if (lineItems.length === 2) + { + currentGroup = lineItems[1]; + } +} + +/** + * @ignore + */ +function parseVertexCoords (lineItems, result) +{ + var len = lineItems.length; + + var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + currentModel(result).vertices.push({ x: x, y: y, z: z }); +} + +/** + * @ignore + */ +function parseTextureCoords (lineItems, result) +{ + var len = lineItems.length; + + var u = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var v = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var w = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + if (isNaN(u)) + { + u = 0; + } + + if (isNaN(v)) + { + v = 0; + } + + if (isNaN(w)) + { + w = 0; + } + + if (flip) + { + v = 1 - v; + } + + currentModel(result).textureCoords.push({ u: u, v: v, w: w }); +} + +/** + * @ignore + */ +function parseVertexNormal (lineItems, result) +{ + var len = lineItems.length; + + var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + currentModel(result).vertexNormals.push({ x: x, y: y, z: z }); +} + +/** + * @ignore + */ +function parsePolygon (lineItems, result) +{ + var totalVertices = lineItems.length - 1; + + if (totalVertices < 3) + { + return; + } + + var face = { + group: currentGroup, + material: currentMaterial, + vertices: [] + }; + + for (var i = 0; i < totalVertices; i++) + { + var vertexString = lineItems[i + 1]; + var vertexValues = vertexString.split('/'); + var vvLen = vertexValues.length; + + if (vvLen < 1 || vvLen > 3) + { + continue; + } + + var vertexIndex = 0; + var textureCoordsIndex = 0; + var vertexNormalIndex = 0; + + vertexIndex = parseInt(vertexValues[0], 10); + + if (vvLen > 1 && vertexValues[1] !== '') + { + textureCoordsIndex = parseInt(vertexValues[1], 10); + } + + if (vvLen > 2) + { + vertexNormalIndex = parseInt(vertexValues[2], 10); + } + + if (vertexIndex !== 0) + { + // Negative vertex indices refer to the nth last defined vertex + // convert these to postive indices for simplicity + if (vertexIndex < 0) + { + vertexIndex = currentModel(result).vertices.length + 1 + vertexIndex; + } + + textureCoordsIndex -= 1; + vertexIndex -= 1; + vertexNormalIndex -= 1; + + face.vertices.push({ + textureCoordsIndex: textureCoordsIndex, + vertexIndex: vertexIndex, + vertexNormalIndex: vertexNormalIndex + }); + } + } + + currentModel(result).faces.push(face); +} + +/** + * @ignore + */ +function parseMtlLib (lineItems, result) +{ + if (lineItems.length >= 2) + { + result.materialLibraries.push(lineItems[1]); + } +} + +/** + * @ignore + */ +function parseUseMtl (lineItems) +{ + if (lineItems.length >= 2) + { + currentMaterial = lineItems[1]; + } +} + +/** + * Parses a Wavefront OBJ File, extracting the models from it and returning them in an array. + * + * The model data *must* be triangulated for a Mesh Game Object to be able to render it. + * + * @function Phaser.Geom.Mesh.ParseObj + * @since 3.50.0 + * + * @param {string} data - The OBJ File data as a raw string. + * @param {boolean} [flipUV=true] - Flip the UV coordinates? + * + * @return {Phaser.Types.Geom.Mesh.OBJData} The parsed model and material data. + */ +var ParseObj = function (data, flipUV) +{ + if (flipUV === undefined) { flipUV = true; } + + flip = flipUV; + + // Store results in here + var result = { + materials: {}, + materialLibraries: [], + models: [] + }; + + currentGroup = ''; + currentMaterial = ''; + + var lines = data.split('\n'); + + for (var i = 0; i < lines.length; i++) + { + var line = stripComments(lines[i]); + + var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); + + switch (lineItems[0].toLowerCase()) + { + case 'o': + // Start A New Model + parseObject(lineItems, result); + break; + + case 'g': + // Start a new polygon group + parseGroup(lineItems); + break; + + case 'v': + // Define a vertex for the current model + parseVertexCoords(lineItems, result); + break; + + case 'vt': + // Texture Coords + parseTextureCoords(lineItems, result); + break; + + case 'vn': + // Define a vertex normal for the current model + parseVertexNormal(lineItems, result); + break; + + case 'f': + // Define a Face/Polygon + parsePolygon(lineItems, result); + break; + + case 'mtllib': + // Reference to a material library file (.mtl) + parseMtlLib(lineItems, result); + break; + + case 'usemtl': + // Sets the current material to be applied to polygons defined from this point forward + parseUseMtl(lineItems); + break; + } + } + + return result; +}; + +module.exports = ParseObj; + + +/***/ }), +/* 493 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetColor = __webpack_require__(100); + +/** + * Takes a Wavefront Material file and extracts the diffuse reflectivity of the named + * materials, converts them to integer color values and returns them. + * + * This is used internally by the `addOBJ` and `addModel` methods, but is exposed for + * public consumption as well. + * + * Note this only works with diffuse values, specified in the `Kd r g b` format, where + * `g` and `b` are optional, but `r` is required. It does not support spectral rfl files, + * or any other material statement (such as `Ka` or `Ks`) + * + * @method Phaser.Geom.Mesh.ParseObjMaterial + * @since 3.50.0 + * + * @param {string} mtl - The OBJ MTL file as a raw string, i.e. loaded via `this.load.text`. + * + * @return {object} The parsed material colors, where each property of the object matches the material name. + */ +var ParseObjMaterial = function (mtl) +{ + var output = {}; + + var lines = mtl.split('\n'); + + var currentMaterial = ''; + + for (var i = 0; i < lines.length; i++) + { + var line = lines[i].trim(); + + if (line.indexOf('#') === 0 || line === '') + { + continue; + } + + var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); + + switch (lineItems[0].toLowerCase()) + { + case 'newmtl': + { + currentMaterial = lineItems[1]; + break; + } + + // The diffuse reflectivity of the current material + // Support r, [g], [b] format, where g and b are optional + case 'kd': + { + var r = Math.floor(lineItems[1] * 255); + var g = (lineItems.length >= 2) ? Math.floor(lineItems[2] * 255) : r; + var b = (lineItems.length >= 3) ? Math.floor(lineItems[3] * 255) : r; + + output[currentMaterial] = GetColor(r, g, b); + + break; + } + } + } + + return output; +}; + +module.exports = ParseObjMaterial; + + +/***/ }), +/* 494 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the magnitude of the point, which equivalent to the length of the line from the origin to this point. + * + * @function Phaser.Geom.Point.GetMagnitude + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - The point to calculate the magnitude for + * + * @return {number} The resulting magnitude + */ +var GetMagnitude = function (point) +{ + return Math.sqrt((point.x * point.x) + (point.y * point.y)); +}; + +module.exports = GetMagnitude; + + +/***/ }), +/* 495 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates the square of magnitude of given point.(Can be used for fast magnitude calculation of point) + * + * @function Phaser.Geom.Point.GetMagnitudeSq + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - Returns square of the magnitude/length of given point. + * + * @return {number} Returns square of the magnitude of given point. + */ +var GetMagnitudeSq = function (point) +{ + return (point.x * point.x) + (point.y * point.y); +}; + +module.exports = GetMagnitudeSq; + + +/***/ }), +/* 496 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +Rectangle.Area = __webpack_require__(1261); +Rectangle.Ceil = __webpack_require__(1262); +Rectangle.CeilAll = __webpack_require__(1263); +Rectangle.CenterOn = __webpack_require__(187); +Rectangle.Clone = __webpack_require__(1264); +Rectangle.Contains = __webpack_require__(56); +Rectangle.ContainsPoint = __webpack_require__(1265); +Rectangle.ContainsRect = __webpack_require__(497); +Rectangle.CopyFrom = __webpack_require__(1266); +Rectangle.Decompose = __webpack_require__(484); +Rectangle.Equals = __webpack_require__(1267); +Rectangle.FitInside = __webpack_require__(1268); +Rectangle.FitOutside = __webpack_require__(1269); +Rectangle.Floor = __webpack_require__(1270); +Rectangle.FloorAll = __webpack_require__(1271); +Rectangle.FromPoints = __webpack_require__(196); +Rectangle.FromXY = __webpack_require__(1272); +Rectangle.GetAspectRatio = __webpack_require__(234); +Rectangle.GetCenter = __webpack_require__(1273); +Rectangle.GetPoint = __webpack_require__(167); +Rectangle.GetPoints = __webpack_require__(300); +Rectangle.GetSize = __webpack_require__(1274); +Rectangle.Inflate = __webpack_require__(1275); +Rectangle.Intersection = __webpack_require__(1276); +Rectangle.MarchingAnts = __webpack_require__(310); +Rectangle.MergePoints = __webpack_require__(1277); +Rectangle.MergeRect = __webpack_require__(1278); +Rectangle.MergeXY = __webpack_require__(1279); +Rectangle.Offset = __webpack_require__(1280); +Rectangle.OffsetPoint = __webpack_require__(1281); +Rectangle.Overlaps = __webpack_require__(1282); +Rectangle.Perimeter = __webpack_require__(128); +Rectangle.PerimeterPoint = __webpack_require__(1283); +Rectangle.Random = __webpack_require__(170); +Rectangle.RandomOutside = __webpack_require__(1284); +Rectangle.SameDimensions = __webpack_require__(1285); +Rectangle.Scale = __webpack_require__(1286); +Rectangle.Union = __webpack_require__(435); + +module.exports = Rectangle; + + +/***/ }), +/* 497 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Tests if one rectangle fully contains another. + * + * @function Phaser.Geom.Rectangle.ContainsRect + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rectA - The first rectangle. + * @param {Phaser.Geom.Rectangle} rectB - The second rectangle. + * + * @return {boolean} True only if rectA fully contains rectB. + */ +var ContainsRect = function (rectA, rectB) +{ + // Volume check (if rectB volume > rectA then rectA cannot contain it) + if ((rectB.width * rectB.height) > (rectA.width * rectA.height)) + { + return false; + } + + return ( + (rectB.x > rectA.x && rectB.x < rectA.right) && + (rectB.right > rectA.x && rectB.right < rectA.right) && + (rectB.y > rectA.y && rectB.y < rectA.bottom) && + (rectB.bottom > rectA.y && rectB.bottom < rectA.bottom) + ); +}; + +module.exports = ContainsRect; + + +/***/ }), +/* 498 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); + +// The three medians (the lines drawn from the vertices to the bisectors of the opposite sides) +// meet in the centroid or center of mass (center of gravity). +// The centroid divides each median in a ratio of 2:1 + +/** + * Calculates the position of a Triangle's centroid, which is also its center of mass (center of gravity). + * + * The centroid is the point in a Triangle at which its three medians (the lines drawn from the vertices to the bisectors of the opposite sides) meet. It divides each one in a 2:1 ratio. + * + * @function Phaser.Geom.Triangle.Centroid + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the coordinates in. + * + * @return {(Phaser.Geom.Point|object)} The `out` object with modified `x` and `y` properties, or a new Point if none was provided. + */ +var Centroid = function (triangle, out) +{ + if (out === undefined) { out = new Point(); } + + out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; + out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; + + return out; +}; + +module.exports = Centroid; + + +/***/ }), +/* 499 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Moves each point (vertex) of a Triangle by a given offset, thus moving the entire Triangle by that offset. + * + * @function Phaser.Geom.Triangle.Offset + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to move. + * @param {number} x - The horizontal offset (distance) by which to move each point. Can be positive or negative. + * @param {number} y - The vertical offset (distance) by which to move each point. Can be positive or negative. + * + * @return {Phaser.Geom.Triangle} The modified Triangle. + */ +var Offset = function (triangle, x, y) +{ + triangle.x1 += x; + triangle.y1 += y; + + triangle.x2 += x; + triangle.y2 += y; + + triangle.x3 += x; + triangle.y3 += y; + + return triangle; +}; + +module.exports = Offset; + + +/***/ }), +/* 500 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); + +// The three angle bisectors of a triangle meet in one point called the incenter. +// It is the center of the incircle, the circle inscribed in the triangle. + +function getLength (x1, y1, x2, y2) +{ + var x = x1 - x2; + var y = y1 - y2; + var magnitude = (x * x) + (y * y); + + return Math.sqrt(magnitude); +} + +/** + * Calculates the position of the incenter of a Triangle object. This is the point where its three angle bisectors meet and it's also the center of the incircle, which is the circle inscribed in the triangle. + * + * @function Phaser.Geom.Triangle.InCenter + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to find the incenter of. + * @param {Phaser.Geom.Point} [out] - An optional Point in which to store the coordinates. + * + * @return {Phaser.Geom.Point} Point (x, y) of the center pixel of the triangle. + */ +var InCenter = function (triangle, out) +{ + if (out === undefined) { out = new Point(); } + + var x1 = triangle.x1; + var y1 = triangle.y1; + + var x2 = triangle.x2; + var y2 = triangle.y2; + + var x3 = triangle.x3; + var y3 = triangle.y3; + + var d1 = getLength(x3, y3, x2, y2); + var d2 = getLength(x1, y1, x3, y3); + var d3 = getLength(x2, y2, x1, y1); + + var p = d1 + d2 + d3; + + out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p; + out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p; + + return out; +}; + +module.exports = InCenter; + + +/***/ }), +/* 501 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Creates a new Pixel Perfect Handler function. + * + * Access via `InputPlugin.makePixelPerfect` rather than calling it directly. + * + * @function Phaser.Input.CreatePixelPerfectHandler + * @since 3.10.0 + * + * @param {Phaser.Textures.TextureManager} textureManager - A reference to the Texture Manager. + * @param {number} alphaTolerance - The alpha level that the pixel should be above to be included as a successful interaction. + * + * @return {function} The new Pixel Perfect Handler function. + */ +var CreatePixelPerfectHandler = function (textureManager, alphaTolerance) +{ + return function (hitArea, x, y, gameObject) + { + var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); + + return (alpha && alpha >= alphaTolerance); + }; +}; + +module.exports = CreatePixelPerfectHandler; + + +/***/ }), +/* 502 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Creates a new Interactive Object. + * + * This is called automatically by the Input Manager when you enable a Game Object for input. + * + * The resulting Interactive Object is mapped to the Game Object's `input` property. + * + * @function Phaser.Input.CreateInteractiveObject + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to which this Interactive Object is bound. + * @param {any} hitArea - The hit area for this Interactive Object. Typically a geometry shape, like a Rectangle or Circle. + * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - The 'contains' check callback that the hit area shape will use for all hit tests. + * + * @return {Phaser.Types.Input.InteractiveObject} The new Interactive Object. + */ +var CreateInteractiveObject = function (gameObject, hitArea, hitAreaCallback) +{ + return { + + gameObject: gameObject, + + enabled: true, + alwaysEnabled: false, + draggable: false, + dropZone: false, + cursor: false, + + target: null, + + camera: null, + + hitArea: hitArea, + hitAreaCallback: hitAreaCallback, + hitAreaDebug: null, + + // Has the dev specified their own shape, or is this bound to the texture size? + customHitArea: false, + + localX: 0, + localY: 0, + + // 0 = Not being dragged + // 1 = Being checked for dragging + // 2 = Being dragged + dragState: 0, + + dragStartX: 0, + dragStartY: 0, + dragStartXGlobal: 0, + dragStartYGlobal: 0, + + dragX: 0, + dragY: 0 + + }; +}; + +module.exports = CreateInteractiveObject; + + +/***/ }), +/* 503 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * Contains information about a specific Gamepad Axis. + * Axis objects are created automatically by the Gamepad as they are needed. + * + * @class Axis + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Axis belongs to. + * @param {number} index - The index of this Axis. + */ +var Axis = new Class({ + + initialize: + + function Axis (pad, index) + { + /** + * A reference to the Gamepad that this Axis belongs to. + * + * @name Phaser.Input.Gamepad.Axis#pad + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.0.0 + */ + this.pad = pad; + + /** + * An event emitter to use to emit the axis events. + * + * @name Phaser.Input.Gamepad.Axis#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = pad.events; + + /** + * The index of this Axis. + * + * @name Phaser.Input.Gamepad.Axis#index + * @type {number} + * @since 3.0.0 + */ + this.index = index; + + /** + * The raw axis value, between -1 and 1 with 0 being dead center. + * Use the method `getValue` to get a normalized value with the threshold applied. + * + * @name Phaser.Input.Gamepad.Axis#value + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.value = 0; + + /** + * Movement tolerance threshold below which axis values are ignored in `getValue`. + * + * @name Phaser.Input.Gamepad.Axis#threshold + * @type {number} + * @default 0.1 + * @since 3.0.0 + */ + this.threshold = 0.1; + }, + + /** + * Internal update handler for this Axis. + * Called automatically by the Gamepad as part of its update. + * + * @method Phaser.Input.Gamepad.Axis#update + * @private + * @since 3.0.0 + * + * @param {number} value - The value of the axis movement. + */ + update: function (value) + { + this.value = value; + }, + + /** + * Applies the `threshold` value to the axis and returns it. + * + * @method Phaser.Input.Gamepad.Axis#getValue + * @since 3.0.0 + * + * @return {number} The axis value, adjusted for the movement threshold. + */ + getValue: function () + { + return (Math.abs(this.value) < this.threshold) ? 0 : this.value; + }, + + /** + * Destroys this Axis instance and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Axis#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.pad = null; + this.events = null; + } + +}); + +module.exports = Axis; + + +/***/ }), +/* 504 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(236); + +/** + * @classdesc + * Contains information about a specific button on a Gamepad. + * Button objects are created automatically by the Gamepad as they are needed. + * + * @class Button + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Button belongs to. + * @param {number} index - The index of this Button. + */ +var Button = new Class({ + + initialize: + + function Button (pad, index) + { + /** + * A reference to the Gamepad that this Button belongs to. + * + * @name Phaser.Input.Gamepad.Button#pad + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.0.0 + */ + this.pad = pad; + + /** + * An event emitter to use to emit the button events. + * + * @name Phaser.Input.Gamepad.Button#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = pad.manager; + + /** + * The index of this Button. + * + * @name Phaser.Input.Gamepad.Button#index + * @type {number} + * @since 3.0.0 + */ + this.index = index; + + /** + * Between 0 and 1. + * + * @name Phaser.Input.Gamepad.Button#value + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.value = 0; + + /** + * Can be set for analogue buttons to enable a 'pressure' threshold, + * before a button is considered as being 'pressed'. + * + * @name Phaser.Input.Gamepad.Button#threshold + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.threshold = 1; + + /** + * Is the Button being pressed down or not? + * + * @name Phaser.Input.Gamepad.Button#pressed + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.pressed = false; + }, + + /** + * Internal update handler for this Button. + * Called automatically by the Gamepad as part of its update. + * + * @method Phaser.Input.Gamepad.Button#update + * @fires Phaser.Input.Gamepad.Events#BUTTON_DOWN + * @fires Phaser.Input.Gamepad.Events#BUTTON_UP + * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN + * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP + * @private + * @since 3.0.0 + * + * @param {number} value - The value of the button. Between 0 and 1. + */ + update: function (value) + { + this.value = value; + + var pad = this.pad; + var index = this.index; + + if (value >= this.threshold) + { + if (!this.pressed) + { + this.pressed = true; + this.events.emit(Events.BUTTON_DOWN, pad, this, value); + this.pad.emit(Events.GAMEPAD_BUTTON_DOWN, index, value, this); + } + } + else if (this.pressed) + { + this.pressed = false; + this.events.emit(Events.BUTTON_UP, pad, this, value); + this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this); + } + }, + + /** + * Destroys this Button instance and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Button#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.pad = null; + this.events = null; + } + +}); + +module.exports = Button; + + +/***/ }), +/* 505 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Axis = __webpack_require__(503); +var Button = __webpack_require__(504); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A single Gamepad. + * + * These are created, updated and managed by the Gamepad Plugin. + * + * @class Gamepad + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.GamepadPlugin} manager - A reference to the Gamepad Plugin. + * @param {Phaser.Types.Input.Gamepad.Pad} pad - The Gamepad object, as extracted from GamepadEvent. + */ +var Gamepad = new Class({ + + Extends: EventEmitter, + + initialize: + + function Gamepad (manager, pad) + { + EventEmitter.call(this); + + /** + * A reference to the Gamepad Plugin. + * + * @name Phaser.Input.Gamepad.Gamepad#manager + * @type {Phaser.Input.Gamepad.GamepadPlugin} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * A reference to the native Gamepad object that is connected to the browser. + * + * @name Phaser.Input.Gamepad.Gamepad#pad + * @type {any} + * @since 3.10.0 + */ + this.pad = pad; + + /** + * A string containing some information about the controller. + * + * This is not strictly specified, but in Firefox it will contain three pieces of information + * separated by dashes (-): two 4-digit hexadecimal strings containing the USB vendor and + * product id of the controller, and the name of the controller as provided by the driver. + * In Chrome it will contain the name of the controller as provided by the driver, + * followed by vendor and product 4-digit hexadecimal strings. + * + * @name Phaser.Input.Gamepad.Gamepad#id + * @type {string} + * @since 3.0.0 + */ + this.id = pad.id; + + /** + * An integer that is unique for each Gamepad currently connected to the system. + * This can be used to distinguish multiple controllers. + * Note that disconnecting a device and then connecting a new device may reuse the previous index. + * + * @name Phaser.Input.Gamepad.Gamepad#index + * @type {number} + * @since 3.0.0 + */ + this.index = pad.index; + + var buttons = []; + + for (var i = 0; i < pad.buttons.length; i++) + { + buttons.push(new Button(this, i)); + } + + /** + * An array of Gamepad Button objects, corresponding to the different buttons available on the Gamepad. + * + * @name Phaser.Input.Gamepad.Gamepad#buttons + * @type {Phaser.Input.Gamepad.Button[]} + * @since 3.0.0 + */ + this.buttons = buttons; + + var axes = []; + + for (i = 0; i < pad.axes.length; i++) + { + axes.push(new Axis(this, i)); + } + + /** + * An array of Gamepad Axis objects, corresponding to the different axes available on the Gamepad, if any. + * + * @name Phaser.Input.Gamepad.Gamepad#axes + * @type {Phaser.Input.Gamepad.Axis[]} + * @since 3.0.0 + */ + this.axes = axes; + + /** + * The Gamepad's Haptic Actuator (Vibration / Rumble support). + * This is highly experimental and only set if both present on the device, + * and exposed by both the hardware and browser. + * + * @name Phaser.Input.Gamepad.Gamepad#vibration + * @type {GamepadHapticActuator} + * @since 3.10.0 + */ + this.vibration = pad.vibrationActuator; + + // https://w3c.github.io/gamepad/#remapping + + var _noButton = { value: 0, pressed: false }; + + /** + * A reference to the Left Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCLeft = (buttons[14]) ? buttons[14] : _noButton; + + /** + * A reference to the Right Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCRight = (buttons[15]) ? buttons[15] : _noButton; + + /** + * A reference to the Top Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCTop = (buttons[12]) ? buttons[12] : _noButton; + + /** + * A reference to the Bottom Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCBottom = (buttons[13]) ? buttons[13] : _noButton; + + /** + * A reference to the Left Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCLeft = (buttons[2]) ? buttons[2] : _noButton; + + /** + * A reference to the Right Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCRight = (buttons[1]) ? buttons[1] : _noButton; + + /** + * A reference to the Top Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCTop = (buttons[3]) ? buttons[3] : _noButton; + + /** + * A reference to the Bottom Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCBottom = (buttons[0]) ? buttons[0] : _noButton; + + /** + * A reference to the Top Left Front Button (L1 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBLeftTop = (buttons[4]) ? buttons[4] : _noButton; + + /** + * A reference to the Bottom Left Front Button (L2 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBLeftBottom = (buttons[6]) ? buttons[6] : _noButton; + + /** + * A reference to the Top Right Front Button (R1 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBRightTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBRightTop = (buttons[5]) ? buttons[5] : _noButton; + + /** + * A reference to the Bottom Right Front Button (R2 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBRightBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBRightBottom = (buttons[7]) ? buttons[7] : _noButton; + + var _noAxis = { value: 0 }; + + /** + * A reference to the Horizontal Axis for the Left Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_HAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._HAxisLeft = (axes[0]) ? axes[0] : _noAxis; + + /** + * A reference to the Vertical Axis for the Left Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_VAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._VAxisLeft = (axes[1]) ? axes[1] : _noAxis; + + /** + * A reference to the Horizontal Axis for the Right Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_HAxisRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._HAxisRight = (axes[2]) ? axes[2] : _noAxis; + + /** + * A reference to the Vertical Axis for the Right Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_VAxisRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._VAxisRight = (axes[3]) ? axes[3] : _noAxis; + + /** + * A Vector2 containing the most recent values from the Gamepad's left axis stick. + * This is updated automatically as part of the Gamepad.update cycle. + * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. + * The values are based on the Axis thresholds. + * If the Gamepad does not have a left axis stick, the values will always be zero. + * + * @name Phaser.Input.Gamepad.Gamepad#leftStick + * @type {Phaser.Math.Vector2} + * @since 3.10.0 + */ + this.leftStick = new Vector2(); + + /** + * A Vector2 containing the most recent values from the Gamepad's right axis stick. + * This is updated automatically as part of the Gamepad.update cycle. + * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. + * The values are based on the Axis thresholds. + * If the Gamepad does not have a right axis stick, the values will always be zero. + * + * @name Phaser.Input.Gamepad.Gamepad#rightStick + * @type {Phaser.Math.Vector2} + * @since 3.10.0 + */ + this.rightStick = new Vector2(); + + /** + * When was this Gamepad created? Used to avoid duplicate event spamming in the update loop. + * + * @name Phaser.Input.Gamepad.Gamepad#_created + * @type {number} + * @private + * @since 3.50.0 + */ + this._created = performance.now(); + }, + + /** + * Gets the total number of axis this Gamepad claims to support. + * + * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal + * @since 3.10.0 + * + * @return {number} The total number of axes this Gamepad claims to support. + */ + getAxisTotal: function () + { + return this.axes.length; + }, + + /** + * Gets the value of an axis based on the given index. + * The index must be valid within the range of axes supported by this Gamepad. + * The return value will be a float between 0 and 1. + * + * @method Phaser.Input.Gamepad.Gamepad#getAxisValue + * @since 3.10.0 + * + * @param {number} index - The index of the axes to get the value for. + * + * @return {number} The value of the axis, between 0 and 1. + */ + getAxisValue: function (index) + { + return this.axes[index].getValue(); + }, + + /** + * Sets the threshold value of all axis on this Gamepad. + * The value is a float between 0 and 1 and is the amount below which the axis is considered as not having been moved. + * + * @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold + * @since 3.10.0 + * + * @param {number} value - A value between 0 and 1. + */ + setAxisThreshold: function (value) + { + for (var i = 0; i < this.axes.length; i++) + { + this.axes[i].threshold = value; + } + }, + + /** + * Gets the total number of buttons this Gamepad claims to have. + * + * @method Phaser.Input.Gamepad.Gamepad#getButtonTotal + * @since 3.10.0 + * + * @return {number} The total number of buttons this Gamepad claims to have. + */ + getButtonTotal: function () + { + return this.buttons.length; + }, + + /** + * Gets the value of a button based on the given index. + * The index must be valid within the range of buttons supported by this Gamepad. + * + * The return value will be either 0 or 1 for an analogue button, or a float between 0 and 1 + * for a pressure-sensitive digital button, such as the shoulder buttons on a Dual Shock. + * + * @method Phaser.Input.Gamepad.Gamepad#getButtonValue + * @since 3.10.0 + * + * @param {number} index - The index of the button to get the value for. + * + * @return {number} The value of the button, between 0 and 1. + */ + getButtonValue: function (index) + { + return this.buttons[index].value; + }, + + /** + * Returns if the button is pressed down or not. + * The index must be valid within the range of buttons supported by this Gamepad. + * + * @method Phaser.Input.Gamepad.Gamepad#isButtonDown + * @since 3.10.0 + * + * @param {number} index - The index of the button to get the value for. + * + * @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`. + */ + isButtonDown: function (index) + { + return this.buttons[index].pressed; + }, + + /** + * Internal update handler for this Gamepad. + * Called automatically by the Gamepad Manager as part of its update. + * + * @method Phaser.Input.Gamepad.Gamepad#update + * @private + * @since 3.0.0 + */ + update: function (pad) + { + if (pad.timestamp < this._created) + { + return; + } + + var i; + + // Sync the button values + + var localButtons = this.buttons; + var gamepadButtons = pad.buttons; + + var len = localButtons.length; + + for (i = 0; i < len; i++) + { + localButtons[i].update(gamepadButtons[i].value); + } + + // Sync the axis values + + var localAxes = this.axes; + var gamepadAxes = pad.axes; + + len = localAxes.length; + + for (i = 0; i < len; i++) + { + localAxes[i].update(gamepadAxes[i]); + } + + if (len >= 2) + { + this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue()); + + if (len >= 4) + { + this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue()); + } + } + }, + + /** + * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Gamepad#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.manager = null; + this.pad = null; + + var i; + + for (i = 0; i < this.buttons.length; i++) + { + this.buttons[i].destroy(); + } + + for (i = 0; i < this.axes.length; i++) + { + this.axes[i].destroy(); + } + + this.buttons = []; + this.axes = []; + }, + + /** + * Is this Gamepad currently connected or not? + * + * @name Phaser.Input.Gamepad.Gamepad#connected + * @type {boolean} + * @default true + * @since 3.0.0 + */ + connected: { + + get: function () + { + return this.pad.connected; + } + + }, + + /** + * A timestamp containing the most recent time this Gamepad was updated. + * + * @name Phaser.Input.Gamepad.Gamepad#timestamp + * @type {number} + * @since 3.0.0 + */ + timestamp: { + + get: function () + { + return this.pad.timestamp; + } + + }, + + /** + * Is the Gamepad's Left button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad left button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#left + * @type {boolean} + * @since 3.10.0 + */ + left: { + + get: function () + { + return this._LCLeft.pressed; + } + + }, + + /** + * Is the Gamepad's Right button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad right button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#right + * @type {boolean} + * @since 3.10.0 + */ + right: { + + get: function () + { + return this._LCRight.pressed; + } + + }, + + /** + * Is the Gamepad's Up button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad up button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#up + * @type {boolean} + * @since 3.10.0 + */ + up: { + + get: function () + { + return this._LCTop.pressed; + } + + }, + + /** + * Is the Gamepad's Down button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad down button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#down + * @type {boolean} + * @since 3.10.0 + */ + down: { + + get: function () + { + return this._LCBottom.pressed; + } + + }, + + /** + * Is the Gamepad's bottom button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the X button. + * On an XBox controller it's the A button. + * + * @name Phaser.Input.Gamepad.Gamepad#A + * @type {boolean} + * @since 3.10.0 + */ + A: { + + get: function () + { + return this._RCBottom.pressed; + } + + }, + + /** + * Is the Gamepad's top button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Triangle button. + * On an XBox controller it's the Y button. + * + * @name Phaser.Input.Gamepad.Gamepad#Y + * @type {boolean} + * @since 3.10.0 + */ + Y: { + + get: function () + { + return this._RCTop.pressed; + } + + }, + + /** + * Is the Gamepad's left button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Square button. + * On an XBox controller it's the X button. + * + * @name Phaser.Input.Gamepad.Gamepad#X + * @type {boolean} + * @since 3.10.0 + */ + X: { + + get: function () + { + return this._RCLeft.pressed; + } + + }, + + /** + * Is the Gamepad's right button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Circle button. + * On an XBox controller it's the B button. + * + * @name Phaser.Input.Gamepad.Gamepad#B + * @type {boolean} + * @since 3.10.0 + */ + B: { + + get: function () + { + return this._RCRight.pressed; + } + + }, + + /** + * Returns the value of the Gamepad's top left shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the L1 button. + * On an XBox controller it's the LB button. + * + * @name Phaser.Input.Gamepad.Gamepad#L1 + * @type {number} + * @since 3.10.0 + */ + L1: { + + get: function () + { + return this._FBLeftTop.value; + } + + }, + + /** + * Returns the value of the Gamepad's bottom left shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the L2 button. + * On an XBox controller it's the LT button. + * + * @name Phaser.Input.Gamepad.Gamepad#L2 + * @type {number} + * @since 3.10.0 + */ + L2: { + + get: function () + { + return this._FBLeftBottom.value; + } + + }, + + /** + * Returns the value of the Gamepad's top right shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the R1 button. + * On an XBox controller it's the RB button. + * + * @name Phaser.Input.Gamepad.Gamepad#R1 + * @type {number} + * @since 3.10.0 + */ + R1: { + + get: function () + { + return this._FBRightTop.value; + } + + }, + + /** + * Returns the value of the Gamepad's bottom right shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the R2 button. + * On an XBox controller it's the RT button. + * + * @name Phaser.Input.Gamepad.Gamepad#R2 + * @type {number} + * @since 3.10.0 + */ + R2: { + + get: function () + { + return this._FBRightBottom.value; + } + + } + +}); + +module.exports = Gamepad; + + +/***/ }), +/* 506 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(152); + +/** + * @classdesc + * A generic Key object which can be passed to the Process functions (and so on) + * keycode must be an integer + * + * @class Key + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Keyboard + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyboardPlugin} plugin - The Keyboard Plugin instance that owns this Key object. + * @param {number} keyCode - The keycode of this key. + */ +var Key = new Class({ + + Extends: EventEmitter, + + initialize: + + function Key (plugin, keyCode) + { + EventEmitter.call(this); + + /** + * The Keyboard Plugin instance that owns this Key object. + * + * @name Phaser.Input.Keyboard.Key#plugin + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.17.0 + */ + this.plugin = plugin; + + /** + * The keycode of this key. + * + * @name Phaser.Input.Keyboard.Key#keyCode + * @type {number} + * @since 3.0.0 + */ + this.keyCode = keyCode; + + /** + * The original DOM event. + * + * @name Phaser.Input.Keyboard.Key#originalEvent + * @type {KeyboardEvent} + * @since 3.0.0 + */ + this.originalEvent = undefined; + + /** + * Can this Key be processed? + * + * @name Phaser.Input.Keyboard.Key#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down. + * + * @name Phaser.Input.Keyboard.Key#isDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isDown = false; + + /** + * The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up. + * + * @name Phaser.Input.Keyboard.Key#isUp + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.isUp = true; + + /** + * The down state of the ALT key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#altKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.altKey = false; + + /** + * The down state of the CTRL key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#ctrlKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.ctrlKey = false; + + /** + * The down state of the SHIFT key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#shiftKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shiftKey = false; + + /** + * The down state of the Meta key, if pressed at the same time as this key. + * On a Mac the Meta Key is the Command key. On Windows keyboards, it's the Windows key. + * + * @name Phaser.Input.Keyboard.Key#metaKey + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.metaKey = false; + + /** + * The location of the modifier key. 0 for standard (or unknown), 1 for left, 2 for right, 3 for numpad. + * + * @name Phaser.Input.Keyboard.Key#location + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.location = 0; + + /** + * The timestamp when the key was last pressed down. + * + * @name Phaser.Input.Keyboard.Key#timeDown + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeDown = 0; + + /** + * The number of milliseconds this key was held down for in the previous down - up sequence. + * This value isn't updated every game step, only when the Key changes state. + * To get the current duration use the `getDuration` method. + * + * @name Phaser.Input.Keyboard.Key#duration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.duration = 0; + + /** + * The timestamp when the key was last released. + * + * @name Phaser.Input.Keyboard.Key#timeUp + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeUp = 0; + + /** + * When a key is held down should it continuously fire the `down` event each time it repeats? + * + * By default it will emit the `down` event just once, but if you wish to receive the event + * for each repeat as well, enable this property. + * + * @name Phaser.Input.Keyboard.Key#emitOnRepeat + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.emitOnRepeat = false; + + /** + * If a key is held down this holds down the number of times the key has 'repeated'. + * + * @name Phaser.Input.Keyboard.Key#repeats + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeats = 0; + + /** + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) + * + * @name Phaser.Input.Keyboard.Key#_justDown + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._justDown = false; + + /** + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) + * + * @name Phaser.Input.Keyboard.Key#_justUp + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._justUp = false; + + /** + * Internal tick counter. + * + * @name Phaser.Input.Keyboard.Key#_tick + * @type {number} + * @private + * @since 3.11.0 + */ + this._tick = -1; + }, + + /** + * Controls if this Key will continuously emit a `down` event while being held down (true), + * or emit the event just once, on first press, and then skip future events (false). + * + * @method Phaser.Input.Keyboard.Key#setEmitOnRepeat + * @since 3.16.0 + * + * @param {boolean} value - Emit `down` events on repeated key down actions, or just once? + * + * @return {this} This Key instance. + */ + setEmitOnRepeat: function (value) + { + this.emitOnRepeat = value; + + return this; + }, + + /** + * Processes the Key Down action for this Key. + * Called automatically by the Keyboard Plugin. + * + * @method Phaser.Input.Keyboard.Key#onDown + * @fires Phaser.Input.Keyboard.Events#DOWN + * @since 3.16.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard event. + */ + onDown: function (event) + { + this.originalEvent = event; + + if (!this.enabled) + { + return; + } + + this.altKey = event.altKey; + this.ctrlKey = event.ctrlKey; + this.shiftKey = event.shiftKey; + this.metaKey = event.metaKey; + this.location = event.location; + + this.repeats++; + + if (!this.isDown) + { + this.isDown = true; + this.isUp = false; + this.timeDown = event.timeStamp; + this.duration = 0; + this._justDown = true; + this._justUp = false; + + this.emit(Events.DOWN, this, event); + } + else if (this.emitOnRepeat) + { + this.emit(Events.DOWN, this, event); + } + }, + + /** + * Processes the Key Up action for this Key. + * Called automatically by the Keyboard Plugin. + * + * @method Phaser.Input.Keyboard.Key#onUp + * @fires Phaser.Input.Keyboard.Events#UP + * @since 3.16.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard event. + */ + onUp: function (event) + { + this.originalEvent = event; + + if (!this.enabled) + { + return; + } + + this.isDown = false; + this.isUp = true; + this.timeUp = event.timeStamp; + this.duration = this.timeUp - this.timeDown; + this.repeats = 0; + + this._justDown = false; + this._justUp = true; + this._tick = -1; + + this.emit(Events.UP, this, event); + }, + + /** + * Resets this Key object back to its default un-pressed state. + * + * @method Phaser.Input.Keyboard.Key#reset + * @since 3.6.0 + * + * @return {this} This Key instance. + */ + reset: function () + { + this.preventDefault = true; + this.enabled = true; + this.isDown = false; + this.isUp = true; + this.altKey = false; + this.ctrlKey = false; + this.shiftKey = false; + this.metaKey = false; + this.timeDown = 0; + this.duration = 0; + this.timeUp = 0; + this.repeats = 0; + this._justDown = false; + this._justUp = false; + this._tick = -1; + + return this; + }, + + /** + * Returns the duration, in ms, that the Key has been held down for. + * + * If the key is not currently down it will return zero. + * + * The get the duration the Key was held down for in the previous up-down cycle, + * use the `Key.duration` property value instead. + * + * @method Phaser.Input.Keyboard.Key#getDuration + * @since 3.17.0 + * + * @return {number} The duration, in ms, that the Key has been held down for if currently down. + */ + getDuration: function () + { + if (this.isDown) + { + return (this.plugin.game.loop.time - this.timeDown); + } + else + { + return 0; + } + }, + + /** + * Removes any bound event handlers and removes local references. + * + * @method Phaser.Input.Keyboard.Key#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.originalEvent = null; + + this.plugin = null; + } + +}); + +module.exports = Key; + + +/***/ }), +/* 507 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(152); +var GetFastValue = __webpack_require__(2); +var ProcessKeyCombo = __webpack_require__(508); +var ResetKeyCombo = __webpack_require__(510); + +/** + * @classdesc + * A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them + * it will emit a `keycombomatch` event from the Keyboard Manager. + * + * The keys to be listened for can be defined as: + * + * A string (i.e. 'ATARI') + * An array of either integers (key codes) or strings, or a mixture of both + * An array of objects (such as Key objects) with a public 'keyCode' property + * + * For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter) + * you could pass the following array of key codes: + * + * ```javascript + * this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true }); + * + * this.input.keyboard.on('keycombomatch', function (event) { + * console.log('Konami Code entered!'); + * }); + * ``` + * + * Or, to listen for the user entering the word PHASER: + * + * ```javascript + * this.input.keyboard.createCombo('PHASER'); + * ``` + * + * @class KeyCombo + * @memberof Phaser.Input.Keyboard + * @constructor + * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyboardPlugin} keyboardPlugin - A reference to the Keyboard Plugin. + * @param {(string|number[]|object[])} keys - The keys that comprise this combo. + * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. + */ +var KeyCombo = new Class({ + + initialize: + + function KeyCombo (keyboardPlugin, keys, config) + { + if (config === undefined) { config = {}; } + + // Can't have a zero or single length combo (string or array based) + if (keys.length < 2) + { + return false; + } + + /** + * A reference to the Keyboard Manager + * + * @name Phaser.Input.Keyboard.KeyCombo#manager + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.0.0 + */ + this.manager = keyboardPlugin; + + /** + * A flag that controls if this Key Combo is actively processing keys or not. + * + * @name Phaser.Input.Keyboard.KeyCombo#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * An array of the keycodes that comprise this combo. + * + * @name Phaser.Input.Keyboard.KeyCombo#keyCodes + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.keyCodes = []; + + // if 'keys' is a string we need to get the keycode of each character in it + + for (var i = 0; i < keys.length; i++) + { + var char = keys[i]; + + if (typeof char === 'string') + { + this.keyCodes.push(char.toUpperCase().charCodeAt(0)); + } + else if (typeof char === 'number') + { + this.keyCodes.push(char); + } + else if (char.hasOwnProperty('keyCode')) + { + this.keyCodes.push(char.keyCode); + } + } + + /** + * The current keyCode the combo is waiting for. + * + * @name Phaser.Input.Keyboard.KeyCombo#current + * @type {number} + * @since 3.0.0 + */ + this.current = this.keyCodes[0]; + + /** + * The current index of the key being waited for in the 'keys' string. + * + * @name Phaser.Input.Keyboard.KeyCombo#index + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.index = 0; + + /** + * The length of this combo (in keycodes) + * + * @name Phaser.Input.Keyboard.KeyCombo#size + * @type {number} + * @since 3.0.0 + */ + this.size = this.keyCodes.length; + + /** + * The time the previous key in the combo was matched. + * + * @name Phaser.Input.Keyboard.KeyCombo#timeLastMatched + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeLastMatched = 0; + + /** + * Has this Key Combo been matched yet? + * + * @name Phaser.Input.Keyboard.KeyCombo#matched + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.matched = false; + + /** + * The time the entire combo was matched. + * + * @name Phaser.Input.Keyboard.KeyCombo#timeMatched + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeMatched = 0; + + /** + * If they press the wrong key do we reset the combo? + * + * @name Phaser.Input.Keyboard.KeyCombo#resetOnWrongKey + * @type {boolean} + * @default 0 + * @since 3.0.0 + */ + this.resetOnWrongKey = GetFastValue(config, 'resetOnWrongKey', true); + + /** + * The max delay in ms between each key press. Above this the combo is reset. 0 means disabled. + * + * @name Phaser.Input.Keyboard.KeyCombo#maxKeyDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxKeyDelay = GetFastValue(config, 'maxKeyDelay', 0); + + /** + * If previously matched and they press the first key of the combo again, will it reset? + * + * @name Phaser.Input.Keyboard.KeyCombo#resetOnMatch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.resetOnMatch = GetFastValue(config, 'resetOnMatch', false); + + /** + * If the combo matches, will it delete itself? + * + * @name Phaser.Input.Keyboard.KeyCombo#deleteOnMatch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.deleteOnMatch = GetFastValue(config, 'deleteOnMatch', false); + + var _this = this; + + var onKeyDownHandler = function (event) + { + if (_this.matched || !_this.enabled) + { + return; + } + + var matched = ProcessKeyCombo(event, _this); + + if (matched) + { + _this.manager.emit(Events.COMBO_MATCH, _this, event); + + if (_this.resetOnMatch) + { + ResetKeyCombo(_this); + } + else if (_this.deleteOnMatch) + { + _this.destroy(); + } + } + }; + + /** + * The internal Key Down handler. + * + * @name Phaser.Input.Keyboard.KeyCombo#onKeyDown + * @private + * @type {KeyboardKeydownCallback} + * @fires Phaser.Input.Keyboard.Events#COMBO_MATCH + * @since 3.0.0 + */ + this.onKeyDown = onKeyDownHandler; + + this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown); + }, + + /** + * How far complete is this combo? A value between 0 and 1. + * + * @name Phaser.Input.Keyboard.KeyCombo#progress + * @type {number} + * @readonly + * @since 3.0.0 + */ + progress: { + + get: function () + { + return this.index / this.size; + } + + }, + + /** + * Destroys this Key Combo and all of its references. + * + * @method Phaser.Input.Keyboard.KeyCombo#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enabled = false; + this.keyCodes = []; + + this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown); + + this.manager = null; + } + +}); + +module.exports = KeyCombo; + + +/***/ }), +/* 508 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AdvanceKeyCombo = __webpack_require__(509); + +/** + * Used internally by the KeyCombo class. + * + * @function Phaser.Input.Keyboard.ProcessKeyCombo + * @private + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native Keyboard Event. + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to be processed. + * + * @return {boolean} `true` if the combo was matched, otherwise `false`. + */ +var ProcessKeyCombo = function (event, combo) +{ + if (combo.matched) + { + return true; + } + + var comboMatched = false; + var keyMatched = false; + + if (event.keyCode === combo.current) + { + // Key was correct + + if (combo.index > 0 && combo.maxKeyDelay > 0) + { + // We have to check to see if the delay between + // the new key and the old one was too long (if enabled) + + var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; + + // Check if they pressed it in time or not + if (event.timeStamp <= timeLimit) + { + keyMatched = true; + comboMatched = AdvanceKeyCombo(event, combo); + } + } + else + { + keyMatched = true; + + // We don't check the time for the first key pressed, so just advance it + comboMatched = AdvanceKeyCombo(event, combo); + } + } + + if (!keyMatched && combo.resetOnWrongKey) + { + // Wrong key was pressed + combo.index = 0; + combo.current = combo.keyCodes[0]; + } + + if (comboMatched) + { + combo.timeLastMatched = event.timeStamp; + combo.matched = true; + combo.timeMatched = event.timeStamp; + } + + return comboMatched; +}; + +module.exports = ProcessKeyCombo; + + +/***/ }), +/* 509 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Used internally by the KeyCombo class. + * Return `true` if it reached the end of the combo, `false` if not. + * + * @function Phaser.Input.Keyboard.AdvanceKeyCombo + * @private + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native Keyboard Event. + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. + * + * @return {boolean} `true` if it reached the end of the combo, `false` if not. + */ +var AdvanceKeyCombo = function (event, combo) +{ + combo.timeLastMatched = event.timeStamp; + combo.index++; + + if (combo.index === combo.size) + { + return true; + } + else + { + combo.current = combo.keyCodes[combo.index]; + return false; + } +}; + +module.exports = AdvanceKeyCombo; + + +/***/ }), +/* 510 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Used internally by the KeyCombo class. + * + * @function Phaser.Input.Keyboard.ResetKeyCombo + * @private + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo to reset. + * + * @return {Phaser.Input.Keyboard.KeyCombo} The KeyCombo. + */ +var ResetKeyCombo = function (combo) +{ + combo.current = combo.keyCodes[0]; + combo.index = 0; + combo.timeLastMatched = 0; + combo.matched = false; + combo.timeMatched = 0; + + return combo; +}; + +module.exports = ResetKeyCombo; + + +/***/ }), +/* 511 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MergeXHRSettings = __webpack_require__(237); + +/** + * 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; + + +/***/ }), +/* 512 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var HTML5AudioFile = __webpack_require__(513); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Audio File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. + * + * @class AudioFile + * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {any} [urlConfig] - The absolute or relative URL to load this file from in a config object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @param {AudioContext} [audioContext] - The AudioContext this file will use to process itself. + */ +var AudioFile = new Class({ + + Extends: File, + + initialize: + + // URL is an object created by AudioFile.findAudioURL + function AudioFile (loader, key, urlConfig, xhrSettings, audioContext) + { + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + audioContext = GetFastValue(config, 'context', audioContext); + } + + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: urlConfig.type, + responseType: 'arraybuffer', + key: key, + url: urlConfig.url, + xhrSettings: xhrSettings, + config: { context: audioContext } + }; + + 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.AudioFile#onProcess + * @since 3.0.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + var _this = this; + + // interesting read https://github.com/WebAudio/web-audio-api/issues/1305 + this.config.context.decodeAudioData(this.xhrLoader.response, + function (audioBuffer) + { + _this.data = audioBuffer; + + _this.onProcessComplete(); + }, + function (e) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + _this.key + ' - ', e ? e.message : null); + + _this.onProcessError(); + } + ); + + this.config.context = null; + } + +}); + +AudioFile.create = function (loader, key, urls, config, xhrSettings) +{ + var game = loader.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + // url may be inside key, which may be an object + if (IsPlainObject(key)) + { + urls = GetFastValue(key, 'url', []); + config = GetFastValue(key, 'config', {}); + } + + var urlConfig = AudioFile.getAudioURL(game, urls); + + if (!urlConfig) + { + return null; + } + + // https://developers.google.com/web/updates/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs + // var stream = GetFastValue(config, 'stream', false); + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + return new AudioFile(loader, key, urlConfig, xhrSettings, game.sound.context); + } + else + { + return new HTML5AudioFile(loader, key, urlConfig, config); + } +}; + +AudioFile.getAudioURL = function (game, urls) +{ + if (!Array.isArray(urls)) + { + urls = [ urls ]; + } + + for (var i = 0; i < urls.length; i++) + { + var url = GetFastValue(urls[i], 'url', urls[i]); + + if (url.indexOf('blob:') === 0 || url.indexOf('data:') === 0) + { + return { + url: url, + type: '' + }; + } + + var audioType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); + + audioType = GetFastValue(urls[i], 'type', (audioType) ? audioType[1] : '').toLowerCase(); + + if (game.device.audio[audioType]) + { + return { + url: url, + type: audioType + }; + } + } + + return null; +}; + +/** + * Adds an Audio or HTML5Audio file, or array of audio 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.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); + * } + * ``` + * + * 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 Audio Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Audio 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 Audio Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.audio({ + * key: 'title', + * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ] + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.AudioFileConfig` for more details. + * + * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. + * + * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats. + * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on + * browser support. + * + * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded. + * + * Note: The ability to load this type of file will only be available if the Audio 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#audio + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.AudioFileConfig|Phaser.Types.Loader.FileTypes.AudioFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {(string|string[])} [urls] - The absolute or relative URL to load the audio files from. + * @param {any} [config] - An object containing an `instances` property for HTML5Audio. Defaults to 1. + * @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('audio', function (key, urls, config, xhrSettings) +{ + var game = this.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + // Sounds are disabled, so skip loading audio + return this; + } + + var audioFile; + + 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 + audioFile = AudioFile.create(this, key[i]); + + if (audioFile) + { + this.addFile(audioFile); + } + } + } + else + { + audioFile = AudioFile.create(this, key, urls, config, xhrSettings); + + if (audioFile) + { + this.addFile(audioFile); + } + } + + return this; +}); + +module.exports = AudioFile; + + +/***/ }), +/* 513 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(91); +var File = __webpack_require__(23); +var GetFastValue = __webpack_require__(2); +var GetURL = __webpack_require__(153); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Audio File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. + * + * @class HTML5AudioFile + * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string} [urlConfig] - The absolute or relative URL to load this file from. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var HTML5AudioFile = new Class({ + + Extends: File, + + initialize: + + function HTML5AudioFile (loader, key, urlConfig, audioConfig) + { + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + audioConfig = GetFastValue(config, 'config', audioConfig); + } + + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: urlConfig.type, + key: key, + url: urlConfig.url, + config: audioConfig + }; + + File.call(this, loader, fileConfig); + + // New properties specific to this class + this.locked = 'ontouchstart' in window; + this.loaded = false; + this.filesLoaded = 0; + this.filesTotal = 0; + }, + + /** + * Called when the file finishes loading. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad + * @since 3.0.0 + */ + onLoad: function () + { + if (this.loaded) + { + return; + } + + this.loaded = true; + + this.loader.nextFile(this, true); + }, + + /** + * Called if the file errors while loading. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onError + * @since 3.0.0 + */ + onError: function () + { + for (var i = 0; i < this.data.length; i++) + { + var audio = this.data[i]; + + audio.oncanplaythrough = null; + audio.onerror = null; + } + + this.loader.nextFile(this, false); + }, + + /** + * Called during the file load progress. Is sent a DOM ProgressEvent. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress + * @fires Phaser.Loader.Events#FILE_PROGRESS + * @since 3.0.0 + */ + onProgress: function (event) + { + var audio = event.target; + + audio.oncanplaythrough = null; + audio.onerror = null; + + this.filesLoaded++; + + this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1); + + this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); + + if (this.filesLoaded === this.filesTotal) + { + this.onLoad(); + } + }, + + /** + * 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.FileTypes.HTML5AudioFile#load + * @since 3.0.0 + */ + load: function () + { + this.data = []; + + var instances = (this.config && this.config.instances) || 1; + + this.filesTotal = instances; + this.filesLoaded = 0; + this.percentComplete = 0; + + for (var i = 0; i < instances; i++) + { + var audio = new Audio(); + + if (!audio.dataset) + { + audio.dataset = {}; + } + + audio.dataset.name = this.key + ('0' + i).slice(-2); + audio.dataset.used = 'false'; + + if (this.locked) + { + audio.dataset.locked = 'true'; + } + else + { + audio.dataset.locked = 'false'; + + audio.preload = 'auto'; + audio.oncanplaythrough = this.onProgress.bind(this); + audio.onerror = this.onError.bind(this); + } + + this.data.push(audio); + } + + for (i = 0; i < this.data.length; i++) + { + audio = this.data[i]; + audio.src = GetURL(this, this.loader.baseURL); + + if (!this.locked) + { + audio.load(); + } + } + + if (this.locked) + { + // This is super-dangerous but works. Race condition potential high. + // Is there another way? + setTimeout(this.onLoad.bind(this)); + } + } + +}); + +module.exports = HTML5AudioFile; + + +/***/ }), +/* 514 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Script File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#script method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#script. + * + * @class ScriptFile + * @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.ScriptFileConfig)} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var ScriptFile = new Class({ + + Extends: File, + + initialize: + + function ScriptFile (loader, key, url, xhrSettings) + { + var extension = 'js'; + + 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: 'script', + cache: false, + 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.ScriptFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = document.createElement('script'); + this.data.language = 'javascript'; + this.data.type = 'text/javascript'; + this.data.defer = false; + this.data.text = this.xhrLoader.responseText; + + document.head.appendChild(this.data); + + this.onProcessComplete(); + } + +}); + +/** + * Adds a Script file, or array of Script 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.script('aliens', 'lib/aliens.js'); + * } + * ``` + * + * 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 and not already in-use by another file in the Loader. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.script({ + * key: 'aliens', + * url: 'lib/aliens.js' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.ScriptFileConfig` for more details. + * + * Once the file has finished loading it will automatically be converted into a script element + * via `document.createElement('script')`. It will have its language set to JavaScript, `defer` set to + * false and then the resulting element will be appended to `document.head`. Any code then in the + * script will be executed. + * + * 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.js". It will always add `.js` 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 Script 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#script + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.ScriptFileConfig|Phaser.Types.Loader.FileTypes.ScriptFileConfig[])} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". + * @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('script', 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 ScriptFile(this, key[i])); + } + } + else + { + this.addFile(new ScriptFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = ScriptFile; + + +/***/ }), +/* 515 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeImage = __webpack_require__(516); +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var PhysicsGroup = __webpack_require__(518); +var StaticPhysicsGroup = __webpack_require__(519); + +/** + * @classdesc + * The Arcade Physics Factory allows you to easily create Arcade Physics enabled Game Objects. + * Objects that are created by this Factory are automatically added to the physics world. + * + * @class Factory + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics World instance. + */ +var Factory = new Class({ + + initialize: + + function Factory (world) + { + /** + * A reference to the Arcade Physics World. + * + * @name Phaser.Physics.Arcade.Factory#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * A reference to the Scene this Arcade Physics instance belongs to. + * + * @name Phaser.Physics.Arcade.Factory#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = world.scene; + + /** + * A reference to the Scene.Systems this Arcade Physics instance belongs to. + * + * @name Phaser.Physics.Arcade.Factory#sys + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.sys = world.scene.sys; + }, + + /** + * Creates a new Arcade Physics Collider object. + * + * @method Phaser.Physics.Arcade.Factory#collider + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for collision. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + collider: function (object1, object2, collideCallback, processCallback, callbackContext) + { + return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext); + }, + + /** + * Creates a new Arcade Physics Collider Overlap object. + * + * @method Phaser.Physics.Arcade.Factory#overlap + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for overlap. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for overlap. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + overlap: function (object1, object2, collideCallback, processCallback, callbackContext) + { + return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext); + }, + + /** + * Adds an Arcade Physics Body to the given Game Object. + * + * @method Phaser.Physics.Arcade.Factory#existing + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - A Game Object. + * @param {boolean} [isStatic=false] - Create a Static body (true) or Dynamic body (false). + * + * @return {Phaser.Types.Physics.Arcade.GameObjectWithBody} The Game Object. + */ + existing: function (gameObject, isStatic) + { + var type = (isStatic) ? CONST.STATIC_BODY : CONST.DYNAMIC_BODY; + + this.world.enableBody(gameObject, type); + + return gameObject; + }, + + /** + * Creates a new Arcade Image object with a Static body. + * + * @method Phaser.Physics.Arcade.Factory#staticImage + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.ImageWithStaticBody} The Image object that was created. + */ + staticImage: function (x, y, key, frame) + { + var image = new ArcadeImage(this.scene, x, y, key, frame); + + this.sys.displayList.add(image); + + this.world.enableBody(image, CONST.STATIC_BODY); + + return image; + }, + + /** + * Creates a new Arcade Image object with a Dynamic body. + * + * @method Phaser.Physics.Arcade.Factory#image + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.ImageWithDynamicBody} The Image object that was created. + */ + image: function (x, y, key, frame) + { + var image = new ArcadeImage(this.scene, x, y, key, frame); + + this.sys.displayList.add(image); + + this.world.enableBody(image, CONST.DYNAMIC_BODY); + + return image; + }, + + /** + * Creates a new Arcade Sprite object with a Static body. + * + * @method Phaser.Physics.Arcade.Factory#staticSprite + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created. + */ + staticSprite: function (x, y, key, frame) + { + var sprite = new ArcadeSprite(this.scene, x, y, key, frame); + + this.sys.displayList.add(sprite); + this.sys.updateList.add(sprite); + + this.world.enableBody(sprite, CONST.STATIC_BODY); + + return sprite; + }, + + /** + * Creates a new Arcade Sprite object with a Dynamic body. + * + * @method Phaser.Physics.Arcade.Factory#sprite + * @since 3.0.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 Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.SpriteWithDynamicBody} The Sprite object that was created. + */ + sprite: function (x, y, key, frame) + { + var sprite = new ArcadeSprite(this.scene, x, y, key, frame); + + this.sys.displayList.add(sprite); + this.sys.updateList.add(sprite); + + this.world.enableBody(sprite, CONST.DYNAMIC_BODY); + + return sprite; + }, + + /** + * Creates a Static Physics Group object. + * All Game Objects created by this Group will automatically be static Arcade Physics objects. + * + * @method Phaser.Physics.Arcade.Factory#staticGroup + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + * + * @return {Phaser.Physics.Arcade.StaticGroup} The Static Group object that was created. + */ + staticGroup: function (children, config) + { + return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config)); + }, + + /** + * Creates a Physics Group object. + * All Game Objects created by this Group will automatically be dynamic Arcade Physics objects. + * + * @method Phaser.Physics.Arcade.Factory#group + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + * + * @return {Phaser.Physics.Arcade.Group} The Group object that was created. + */ + group: function (children, config) + { + return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config)); + }, + + /** + * Destroys this Factory. + * + * @method Phaser.Physics.Arcade.Factory#destroy + * @since 3.5.0 + */ + destroy: function () + { + this.world = null; + this.scene = null; + this.sys = null; + } + +}); + +module.exports = Factory; + + +/***/ }), +/* 516 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(240); +var Image = __webpack_require__(124); + +/** + * @classdesc + * An Arcade Physics Image is an Image with an Arcade Physics body and related components. + * The body can be dynamic or static. + * + * The main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image. + * + * @class Image + * @extends Phaser.GameObjects.Image + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @extends Phaser.Physics.Arcade.Components.Acceleration + * @extends Phaser.Physics.Arcade.Components.Angular + * @extends Phaser.Physics.Arcade.Components.Bounce + * @extends Phaser.Physics.Arcade.Components.Debug + * @extends Phaser.Physics.Arcade.Components.Drag + * @extends Phaser.Physics.Arcade.Components.Enable + * @extends Phaser.Physics.Arcade.Components.Friction + * @extends Phaser.Physics.Arcade.Components.Gravity + * @extends Phaser.Physics.Arcade.Components.Immovable + * @extends Phaser.Physics.Arcade.Components.Mass + * @extends Phaser.Physics.Arcade.Components.Pushable + * @extends Phaser.Physics.Arcade.Components.Size + * @extends Phaser.Physics.Arcade.Components.Velocity + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Tint + * @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 - 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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + */ +var ArcadeImage = new Class({ + + Extends: Image, + + Mixins: [ + Components.Acceleration, + Components.Angular, + Components.Bounce, + Components.Debug, + Components.Drag, + Components.Enable, + Components.Friction, + Components.Gravity, + Components.Immovable, + Components.Mass, + Components.Pushable, + Components.Size, + Components.Velocity + ], + + initialize: + + function ArcadeImage (scene, x, y, texture, frame) + { + Image.call(this, scene, x, y, texture, frame); + + /** + * This Game Object's Physics Body. + * + * @name Phaser.Physics.Arcade.Image#body + * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} + * @default null + * @since 3.0.0 + */ + this.body = null; + } + +}); + +module.exports = ArcadeImage; + + +/***/ }), +/* 517 */ +/***/ (function(module, exports, __webpack_require__) { + +var OverlapRect = __webpack_require__(241); +var Circle = __webpack_require__(62); +var CircleToCircle = __webpack_require__(228); +var CircleToRectangle = __webpack_require__(150); + +/** + * This method will search the given circular area and return an array of all physics bodies that + * overlap with it. It can return either Dynamic, Static bodies or a mixture of both. + * + * A body only has to intersect with the search area to be considered, it doesn't have to be fully + * contained within it. + * + * If Arcade Physics is set to use the RTree (which it is by default) then the search is rather fast, + * otherwise the search is O(N) for Dynamic Bodies. + * + * @function Phaser.Physics.Arcade.Components.OverlapCirc + * @since 3.21.0 + * + * @param {number} x - The x coordinate of the center of the area to search within. + * @param {number} y - The y coordinate of the center of the area to search within. + * @param {number} radius - The radius of the area to search within. + * @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies? + * @param {boolean} [includeStatic=false] - Should the search include Static Bodies? + * + * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. + */ +var OverlapCirc = function (world, x, y, radius, includeDynamic, includeStatic) +{ + var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); + + if (bodiesInRect.length === 0) + { + return bodiesInRect; + } + + var area = new Circle(x, y, radius); + var circFromBody = new Circle(); + var bodiesInArea = []; + + for (var i = 0; i < bodiesInRect.length; i++) + { + var body = bodiesInRect[i]; + + if (body.isCircle) + { + circFromBody.setTo(body.center.x, body.center.y, body.halfWidth); + + if (CircleToCircle(area, circFromBody)) + { + bodiesInArea.push(body); + } + } + else if (CircleToRectangle(area, body)) + { + bodiesInArea.push(body); + } + } + + return bodiesInArea; +}; + +module.exports = OverlapCirc; + + +/***/ }), +/* 518 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var GetFastValue = __webpack_require__(2); +var Group = __webpack_require__(110); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * An Arcade Physics Group object. + * + * The primary use of a Physics Group is a way to collect together physics enable objects + * that share the same intrinsic structure into a single pool. They can they be easily + * compared against other Groups, or Game Objects. + * + * All Game Objects created by, or added to this Group will automatically be given **dynamic** + * Arcade Physics bodies (if they have no body already) and the bodies will receive the + * Groups {@link Phaser.Physics.Arcade.Group#defaults default values}. + * + * You should not pass objects into this Group that should not receive a body. For example, + * do not add basic Geometry or Tilemap Layers into a Group, as they will not behave in the + * way you may expect. Groups should all ideally have objects of the same type in them. + * + * If you wish to create a Group filled with Static Bodies, please see {@link Phaser.Physics.Arcade.StaticGroup}. + * + * @class Group + * @extends Phaser.GameObjects.Group + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The physics simulation. + * @param {Phaser.Scene} scene - The scene this group belongs to. + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + */ +var PhysicsGroup = new Class({ + + Extends: Group, + + initialize: + + function PhysicsGroup (world, scene, children, config) + { + if (!children && !config) + { + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + else if (IsPlainObject(children)) + { + // children is a plain object, so swizzle them: + config = children; + children = null; + + config.internalCreateCallback = this.createCallbackHandler; + config.internalRemoveCallback = this.removeCallbackHandler; + } + else if (Array.isArray(children) && IsPlainObject(children[0])) + { + // children is an array of plain objects (i.e., configs) + config = children[0]; + + var _this = this; + + children.forEach(function (singleConfig) + { + singleConfig.internalCreateCallback = _this.createCallbackHandler; + singleConfig.internalRemoveCallback = _this.removeCallbackHandler; + }); + + children = null; + } + else + { + // config is not defined and children is not a plain object nor an array of plain objects + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + + /** + * The physics simulation. + * + * @name Phaser.Physics.Arcade.Group#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The class to create new Group members from. + * + * This should be either `Phaser.Physics.Arcade.Image`, `Phaser.Physics.Arcade.Sprite`, or a class extending one of those. + * + * @name Phaser.Physics.Arcade.Group#classType + * @type {Function} + * @default ArcadeSprite + * @since 3.0.0 + */ + config.classType = GetFastValue(config, 'classType', ArcadeSprite); + + /** + * The physics type of the Group's members. + * + * @name Phaser.Physics.Arcade.Group#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.DYNAMIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.DYNAMIC_BODY; + + /** + * Default physics properties applied to Game Objects added to the Group or created by the Group. Derived from the `config` argument. + * + * You can remove the default values by setting this property to `{}`. + * + * @name Phaser.Physics.Arcade.Group#defaults + * @type {Phaser.Types.Physics.Arcade.PhysicsGroupDefaults} + * @since 3.0.0 + */ + this.defaults = { + setCollideWorldBounds: GetFastValue(config, 'collideWorldBounds', false), + setBoundsRectangle: GetFastValue(config, 'customBoundsRectangle', null), + setAccelerationX: GetFastValue(config, 'accelerationX', 0), + setAccelerationY: GetFastValue(config, 'accelerationY', 0), + setAllowDrag: GetFastValue(config, 'allowDrag', true), + setAllowGravity: GetFastValue(config, 'allowGravity', true), + setAllowRotation: GetFastValue(config, 'allowRotation', true), + setBounceX: GetFastValue(config, 'bounceX', 0), + setBounceY: GetFastValue(config, 'bounceY', 0), + setDragX: GetFastValue(config, 'dragX', 0), + setDragY: GetFastValue(config, 'dragY', 0), + setEnable: GetFastValue(config, 'enable', true), + setGravityX: GetFastValue(config, 'gravityX', 0), + setGravityY: GetFastValue(config, 'gravityY', 0), + setFrictionX: GetFastValue(config, 'frictionX', 0), + setFrictionY: GetFastValue(config, 'frictionY', 0), + setMaxVelocityX: GetFastValue(config, 'maxVelocityX', 10000), + setMaxVelocityY: GetFastValue(config, 'maxVelocityY', 10000), + setVelocityX: GetFastValue(config, 'velocityX', 0), + setVelocityY: GetFastValue(config, 'velocityY', 0), + setAngularVelocity: GetFastValue(config, 'angularVelocity', 0), + setAngularAcceleration: GetFastValue(config, 'angularAcceleration', 0), + setAngularDrag: GetFastValue(config, 'angularDrag', 0), + setMass: GetFastValue(config, 'mass', 1), + setImmovable: GetFastValue(config, 'immovable', false) + }; + + Group.call(this, scene, children, config); + + /** + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.Physics.Arcade.Group#type + * @type {string} + * @default 'PhysicsGroup' + * @since 3.21.0 + */ + this.type = 'PhysicsGroup'; + }, + + /** + * Enables a Game Object's Body and assigns `defaults`. Called when a Group member is added or created. + * + * @method Phaser.Physics.Arcade.Group#createCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object being added. + */ + createCallbackHandler: function (child) + { + if (!child.body) + { + this.world.enableBody(child, CONST.DYNAMIC_BODY); + } + + var body = child.body; + + for (var key in this.defaults) + { + body[key](this.defaults[key]); + } + }, + + /** + * Disables a Game Object's Body. Called when a Group member is removed. + * + * @method Phaser.Physics.Arcade.Group#removeCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object being removed. + */ + removeCallbackHandler: function (child) + { + if (child.body) + { + this.world.disableBody(child); + } + }, + + /** + * Sets the velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocity + * @since 3.0.0 + * + * @param {number} x - The horizontal velocity. + * @param {number} y - The vertical velocity. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x, y), the second (x + step, y + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocity: function (x, y, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.set(x + (i * step), y + (i * step)); + } + + return this; + }, + + /** + * Sets the horizontal velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocityX + * @since 3.0.0 + * + * @param {number} value - The velocity value. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x), the second (x + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocityX: function (value, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.x = value + (i * step); + } + + return this; + }, + + /** + * Sets the vertical velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocityY + * @since 3.0.0 + * + * @param {number} value - The velocity value. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (y), the second (y + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocityY: function (value, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.y = value + (i * step); + } + + return this; + } + +}); + +module.exports = PhysicsGroup; + + +/***/ }), +/* 519 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var GetFastValue = __webpack_require__(2); +var Group = __webpack_require__(110); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * An Arcade Physics Static Group object. + * + * All Game Objects created by or added to this Group will automatically be given static Arcade Physics bodies, if they have no body. + * + * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Group}. + * + * @class StaticGroup + * @extends Phaser.GameObjects.Group + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The physics simulation. + * @param {Phaser.Scene} scene - The scene this group belongs to. + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + */ +var StaticPhysicsGroup = new Class({ + + Extends: Group, + + initialize: + + function StaticPhysicsGroup (world, scene, children, config) + { + if (!children && !config) + { + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler, + createMultipleCallback: this.createMultipleCallbackHandler, + classType: ArcadeSprite + }; + } + else if (IsPlainObject(children)) + { + // children is a plain object, so swizzle them: + config = children; + children = null; + + config.internalCreateCallback = this.createCallbackHandler; + config.internalRemoveCallback = this.removeCallbackHandler; + config.createMultipleCallback = this.createMultipleCallbackHandler; + config.classType = GetFastValue(config, 'classType', ArcadeSprite); + } + else if (Array.isArray(children) && IsPlainObject(children[0])) + { + // children is an array of plain objects + config = children; + children = null; + + config.forEach(function (singleConfig) + { + singleConfig.internalCreateCallback = this.createCallbackHandler; + singleConfig.internalRemoveCallback = this.removeCallbackHandler; + singleConfig.createMultipleCallback = this.createMultipleCallbackHandler; + singleConfig.classType = GetFastValue(singleConfig, 'classType', ArcadeSprite); + }); + } + else + { + // config is not defined and children is not a plain object nor an array of plain objects + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + + /** + * The physics simulation. + * + * @name Phaser.Physics.Arcade.StaticGroup#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The scene this group belongs to. + * + * @name Phaser.Physics.Arcade.StaticGroup#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.STATIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.STATIC_BODY; + + Group.call(this, scene, children, config); + + /** + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.Physics.Arcade.StaticGroup#type + * @type {string} + * @default 'StaticPhysicsGroup' + * @since 3.21.0 + */ + this.type = 'StaticPhysicsGroup'; + }, + + /** + * Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation. + * + * @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The new group member. + * + * @see Phaser.Physics.Arcade.World#enableBody + */ + createCallbackHandler: function (child) + { + if (!child.body) + { + this.world.enableBody(child, CONST.STATIC_BODY); + } + }, + + /** + * Disables the group member's physics body, removing it from the simulation. + * + * @method Phaser.Physics.Arcade.StaticGroup#removeCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The group member being removed. + * + * @see Phaser.Physics.Arcade.World#disableBody + */ + removeCallbackHandler: function (child) + { + if (child.body) + { + this.world.disableBody(child); + } + }, + + /** + * Refreshes the group. + * + * @method Phaser.Physics.Arcade.StaticGroup#createMultipleCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject[]} entries - The newly created group members. + * + * @see Phaser.Physics.Arcade.StaticGroup#refresh + */ + createMultipleCallbackHandler: function () + { + this.refresh(); + }, + + /** + * Resets each Body to the position of its parent Game Object. + * Body sizes aren't changed (use {@link Phaser.Physics.Arcade.Components.Enable#refreshBody} for that). + * + * @method Phaser.Physics.Arcade.StaticGroup#refresh + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.StaticGroup} This group. + * + * @see Phaser.Physics.Arcade.StaticBody#reset + */ + refresh: function () + { + var children = this.children.entries; + + for (var i = 0; i < children.length; i++) + { + children[i].body.reset(); + } + + return this; + } + +}); + +module.exports = StaticPhysicsGroup; + + +/***/ }), +/* 520 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AngleBetweenPoints = __webpack_require__(344); +var Body = __webpack_require__(521); +var Clamp = __webpack_require__(18); +var Class = __webpack_require__(0); +var Collider = __webpack_require__(522); +var CONST = __webpack_require__(60); +var DistanceBetween = __webpack_require__(48); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(242); +var FuzzyEqual = __webpack_require__(123); +var FuzzyGreaterThan = __webpack_require__(348); +var FuzzyLessThan = __webpack_require__(349); +var GetOverlapX = __webpack_require__(243); +var GetOverlapY = __webpack_require__(244); +var GetTilesWithinWorldXY = __webpack_require__(523); +var GetValue = __webpack_require__(6); +var MATH_CONST = __webpack_require__(14); +var ProcessQueue = __webpack_require__(208); +var ProcessTileCallbacks = __webpack_require__(524); +var Rectangle = __webpack_require__(10); +var RTree = __webpack_require__(525); +var SeparateTile = __webpack_require__(526); +var SeparateX = __webpack_require__(531); +var SeparateY = __webpack_require__(532); +var Set = __webpack_require__(148); +var StaticBody = __webpack_require__(533); +var TileIntersectsBody = __webpack_require__(245); +var TransformMatrix = __webpack_require__(25); +var Vector2 = __webpack_require__(3); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * The Arcade Physics World. + * + * The World is responsible for creating, managing, colliding and updating all of the bodies within it. + * + * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. + * + * @class World + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this World instance belongs. + * @param {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} config - An Arcade Physics Configuration object. + */ +var World = new Class({ + + Extends: EventEmitter, + + initialize: + + function World (scene, config) + { + EventEmitter.call(this); + + /** + * The Scene this simulation belongs to. + * + * @name Phaser.Physics.Arcade.World#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; + + /** + * Dynamic Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#bodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.bodies = new Set(); + + /** + * Static Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#staticBodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.staticBodies = new Set(); + + /** + * Static Bodies marked for deletion. + * + * @name Phaser.Physics.Arcade.World#pendingDestroy + * @type {Phaser.Structs.Set.<(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)>} + * @since 3.1.0 + */ + this.pendingDestroy = new Set(); + + /** + * This simulation's collision processors. + * + * @name Phaser.Physics.Arcade.World#colliders + * @type {Phaser.Structs.ProcessQueue.} + * @since 3.0.0 + */ + this.colliders = new ProcessQueue(); + + /** + * Acceleration of Bodies due to gravity, in pixels per second. + * + * @name Phaser.Physics.Arcade.World#gravity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.gravity = new Vector2(GetValue(config, 'gravity.x', 0), GetValue(config, 'gravity.y', 0)); + + /** + * A boundary constraining Bodies. + * + * @name Phaser.Physics.Arcade.World#bounds + * @type {Phaser.Geom.Rectangle} + * @since 3.0.0 + */ + this.bounds = new Rectangle( + GetValue(config, 'x', 0), + GetValue(config, 'y', 0), + GetValue(config, 'width', scene.sys.scale.width), + GetValue(config, 'height', scene.sys.scale.height) + ); + + /** + * The boundary edges that Bodies can collide with. + * + * @name Phaser.Physics.Arcade.World#checkCollision + * @type {Phaser.Types.Physics.Arcade.CheckCollisionObject} + * @since 3.0.0 + */ + this.checkCollision = { + up: GetValue(config, 'checkCollision.up', true), + down: GetValue(config, 'checkCollision.down', true), + left: GetValue(config, 'checkCollision.left', true), + right: GetValue(config, 'checkCollision.right', true) + }; + + /** + * The number of physics steps to be taken per second. + * + * This property is read-only. Use the `setFPS` method to modify it at run-time. + * + * @name Phaser.Physics.Arcade.World#fps + * @readonly + * @type {number} + * @default 60 + * @since 3.10.0 + */ + this.fps = GetValue(config, 'fps', 60); + + /** + * Should Physics use a fixed update time-step (true) or sync to the render fps (false)?. + * False value of this property disables fps and timeScale properties. + * + * @name Phaser.Physics.Arcade.World#fixedStep + * @type {boolean} + * @default true + * @since 3.23.0 + */ + this.fixedStep = GetValue(config, 'fixedStep', true); + + /** + * The amount of elapsed ms since the last frame. + * + * @name Phaser.Physics.Arcade.World#_elapsed + * @private + * @type {number} + * @since 3.10.0 + */ + this._elapsed = 0; + + /** + * Internal frame time value. + * + * @name Phaser.Physics.Arcade.World#_frameTime + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTime = 1 / this.fps; + + /** + * Internal frame time ms value. + * + * @name Phaser.Physics.Arcade.World#_frameTimeMS + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTimeMS = 1000 * this._frameTime; + + /** + * The number of steps that took place in the last frame. + * + * @name Phaser.Physics.Arcade.World#stepsLastFrame + * @readonly + * @type {number} + * @since 3.10.0 + */ + this.stepsLastFrame = 0; + + /** + * Scaling factor applied to the frame rate. + * + * - 1.0 = normal speed + * - 2.0 = half speed + * - 0.5 = double speed + * + * @name Phaser.Physics.Arcade.World#timeScale + * @type {number} + * @default 1 + * @since 3.10.0 + */ + this.timeScale = GetValue(config, 'timeScale', 1); + + /** + * The maximum absolute difference of a Body's per-step velocity and its overlap with another Body that will result in separation on *each axis*. + * Larger values favor separation. + * Smaller values favor no separation. + * + * @name Phaser.Physics.Arcade.World#OVERLAP_BIAS + * @type {number} + * @default 4 + * @since 3.0.0 + */ + this.OVERLAP_BIAS = GetValue(config, 'overlapBias', 4); + + /** + * The maximum absolute value of a Body's overlap with a tile that will result in separation on *each axis*. + * Larger values favor separation. + * Smaller values favor no separation. + * The optimum value may be similar to the tile size. + * + * @name Phaser.Physics.Arcade.World#TILE_BIAS + * @type {number} + * @default 16 + * @since 3.0.0 + */ + this.TILE_BIAS = GetValue(config, 'tileBias', 16); + + /** + * Always separate overlapping Bodies horizontally before vertically. + * False (the default) means Bodies are first separated on the axis of greater gravity, or the vertical axis if neither is greater. + * + * @name Phaser.Physics.Arcade.World#forceX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.forceX = GetValue(config, 'forceX', false); + + /** + * Whether the simulation advances with the game loop. + * + * @name Phaser.Physics.Arcade.World#isPaused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isPaused = GetValue(config, 'isPaused', false); + + /** + * Temporary total of colliding Bodies. + * + * @name Phaser.Physics.Arcade.World#_total + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._total = 0; + + /** + * Enables the debug display. + * + * @name Phaser.Physics.Arcade.World#drawDebug + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.drawDebug = GetValue(config, 'debug', false); + + /** + * The graphics object drawing the debug display. + * + * @name Phaser.Physics.Arcade.World#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.0.0 + */ + this.debugGraphic; + + /** + * Default debug display settings for new Bodies. + * + * @name Phaser.Physics.Arcade.World#defaults + * @type {Phaser.Types.Physics.Arcade.ArcadeWorldDefaults} + * @since 3.0.0 + */ + this.defaults = { + debugShowBody: GetValue(config, 'debugShowBody', true), + debugShowStaticBody: GetValue(config, 'debugShowStaticBody', true), + debugShowVelocity: GetValue(config, 'debugShowVelocity', true), + bodyDebugColor: GetValue(config, 'debugBodyColor', 0xff00ff), + staticBodyDebugColor: GetValue(config, 'debugStaticBodyColor', 0x0000ff), + velocityDebugColor: GetValue(config, 'debugVelocityColor', 0x00ff00) + }; + + /** + * The maximum number of items per node on the RTree. + * + * This is ignored if `useTree` is `false`. If you have a large number of bodies in + * your world then you may find search performance improves by increasing this value, + * to allow more items per node and less node division. + * + * @name Phaser.Physics.Arcade.World#maxEntries + * @type {number} + * @default 16 + * @since 3.0.0 + */ + this.maxEntries = GetValue(config, 'maxEntries', 16); + + /** + * Should this Arcade Physics World use an RTree for Dynamic bodies? + * + * An RTree is a fast way of spatially sorting of all the bodies in the world. + * However, at certain limits, the cost of clearing and inserting the bodies into the + * tree every frame becomes more expensive than the search speed gains it provides. + * + * If you have a large number of dynamic bodies in your world then it may be best to + * disable the use of the RTree by setting this property to `false` in the physics config. + * + * The number it can cope with depends on browser and device, but a conservative estimate + * of around 5,000 bodies should be considered the max before disabling it. + * + * This only applies to dynamic bodies. Static bodies are always kept in an RTree, + * because they don't have to be cleared every frame, so you benefit from the + * massive search speeds all the time. + * + * @name Phaser.Physics.Arcade.World#useTree + * @type {boolean} + * @default true + * @since 3.10.0 + */ + this.useTree = GetValue(config, 'useTree', true); + + /** + * The spatial index of Dynamic Bodies. + * + * @name Phaser.Physics.Arcade.World#tree + * @type {Phaser.Structs.RTree} + * @since 3.0.0 + */ + this.tree = new RTree(this.maxEntries); + + /** + * The spatial index of Static Bodies. + * + * @name Phaser.Physics.Arcade.World#staticTree + * @type {Phaser.Structs.RTree} + * @since 3.0.0 + */ + this.staticTree = new RTree(this.maxEntries); + + /** + * Recycled input for tree searches. + * + * @name Phaser.Physics.Arcade.World#treeMinMax + * @type {Phaser.Types.Physics.Arcade.ArcadeWorldTreeMinMax} + * @since 3.0.0 + */ + this.treeMinMax = { minX: 0, minY: 0, maxX: 0, maxY: 0 }; + + /** + * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. + * + * @name Phaser.Physics.Arcade.World#_tempMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix = new TransformMatrix(); + + /** + * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. + * + * @name Phaser.Physics.Arcade.World#_tempMatrix2 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + if (this.drawDebug) + { + this.createDebugGraphic(); + } + }, + + /** + * Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group. + * + * The difference between this and the `enableBody` method is that you can pass arrays or Groups + * to this method. + * + * You can specify if the bodies are to be Dynamic or Static. A dynamic body can move via velocity and + * acceleration. A static body remains fixed in place and as such is able to use an optimized search + * tree, making it ideal for static elements such as level objects. You can still collide and overlap + * with static bodies. + * + * Normally, rather than calling this method directly, you'd use the helper methods available in the + * Arcade Physics Factory, such as: + * + * ```javascript + * this.physics.add.image(x, y, textureKey); + * this.physics.add.sprite(x, y, textureKey); + * ``` + * + * Calling factory methods encapsulates the creation of a Game Object and the creation of its + * body at the same time. If you are creating custom classes then you can pass them to this + * method to have their bodies created. + * + * @method Phaser.Physics.Arcade.World#enable + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to create the bodies. + * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. + */ + enable: function (object, bodyType) + { + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } + + if (!Array.isArray(object)) + { + object = [ object ]; + } + + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; + + if (entry.isParent) + { + var children = entry.getChildren(); + + for (var c = 0; c < children.length; c++) + { + var child = children[c]; + + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.enable(child, bodyType); + } + else + { + this.enableBody(child, bodyType); + } + } + } + else + { + this.enableBody(entry, bodyType); + } + } + }, + + /** + * Creates an Arcade Physics Body on a single Game Object. + * + * If the Game Object already has a body, this method will simply add it back into the simulation. + * + * You can specify if the body is Dynamic or Static. A dynamic body can move via velocity and + * acceleration. A static body remains fixed in place and as such is able to use an optimized search + * tree, making it ideal for static elements such as level objects. You can still collide and overlap + * with static bodies. + * + * Normally, rather than calling this method directly, you'd use the helper methods available in the + * Arcade Physics Factory, such as: + * + * ```javascript + * this.physics.add.image(x, y, textureKey); + * this.physics.add.sprite(x, y, textureKey); + * ``` + * + * Calling factory methods encapsulates the creation of a Game Object and the creation of its + * body at the same time. If you are creating custom classes then you can pass them to this + * method to have their bodies created. + * + * @method Phaser.Physics.Arcade.World#enableBody + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} object - The Game Object on which to create the body. + * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. + * + * @return {Phaser.GameObjects.GameObject} The Game Object on which the body was created. + */ + enableBody: function (object, bodyType) + { + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } + + if (!object.body) + { + if (bodyType === CONST.DYNAMIC_BODY) + { + object.body = new Body(this, object); + } + else if (bodyType === CONST.STATIC_BODY) + { + object.body = new StaticBody(this, object); + } + } + + this.add(object.body); + + return object; + }, + + /** + * Adds an existing Arcade Physics Body or StaticBody to the simulation. + * + * The body is enabled and added to the local search trees. + * + * @method Phaser.Physics.Arcade.World#add + * @since 3.10.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be added to the simulation. + * + * @return {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} The Body that was added to the simulation. + */ + add: function (body) + { + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.bodies.set(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.set(body); + + this.staticTree.insert(body); + } + + body.enable = true; + + return body; + }, + + /** + * Disables the Arcade Physics Body of a Game Object, an array of Game Objects, or the children of a Group. + * + * The difference between this and the `disableBody` method is that you can pass arrays or Groups + * to this method. + * + * The body itself is not deleted, it just has its `enable` property set to false, which + * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. + * + * @method Phaser.Physics.Arcade.World#disable + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to disable the bodies. + */ + disable: function (object) + { + if (!Array.isArray(object)) + { + object = [ object ]; + } + + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; + + if (entry.isParent) + { + var children = entry.getChildren(); + + for (var c = 0; c < children.length; c++) + { + var child = children[c]; + + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.disable(child); + } + else + { + this.disableBody(child.body); + } + } + } + else + { + this.disableBody(entry.body); + } + } + }, + + /** + * Disables an existing Arcade Physics Body or StaticBody and removes it from the simulation. + * + * The body is disabled and removed from the local search trees. + * + * The body itself is not deleted, it just has its `enable` property set to false, which + * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. + * + * @method Phaser.Physics.Arcade.World#disableBody + * @since 3.0.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be disabled. + */ + disableBody: function (body) + { + this.remove(body); + + body.enable = false; + }, + + /** + * Removes an existing Arcade Physics Body or StaticBody from the simulation. + * + * The body is disabled and removed from the local search trees. + * + * The body itself is not deleted, it just has its `enabled` property set to false, which + * means you can re-enable it again at any point by passing it to enable `enable` or `add`. + * + * @method Phaser.Physics.Arcade.World#remove + * @since 3.0.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation. + */ + remove: function (body) + { + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.tree.remove(body); + this.bodies.delete(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.delete(body); + this.staticTree.remove(body); + } + }, + + /** + * Creates a Graphics Game Object that the world will use to render the debug display to. + * + * This is called automatically when the World is instantiated if the `debug` config property + * was set to `true`. However, you can call it at any point should you need to display the + * debug Graphic from a fixed point. + * + * You can control which objects are drawn to the Graphics object, and the colors they use, + * by setting the debug properties in the physics config. + * + * You should not typically use this in a production game. Use it to aid during debugging. + * + * @method Phaser.Physics.Arcade.World#createDebugGraphic + * @since 3.0.0 + * + * @return {Phaser.GameObjects.Graphics} The Graphics object that was created for use by the World. + */ + createDebugGraphic: function () + { + var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); + + graphic.setDepth(Number.MAX_VALUE); + + this.debugGraphic = graphic; + + this.drawDebug = true; + + return graphic; + }, + + /** + * Sets the position, size and properties of the World boundary. + * + * The World boundary is an invisible rectangle that defines the edges of the World. + * If a Body is set to collide with the world bounds then it will automatically stop + * when it reaches any of the edges. You can optionally set which edges of the boundary + * should be checked against. + * + * @method Phaser.Physics.Arcade.World#setBounds + * @since 3.0.0 + * + * @param {number} x - The top-left x coordinate of the boundary. + * @param {number} y - The top-left y coordinate of the boundary. + * @param {number} width - The width of the boundary. + * @param {number} height - The height of the boundary. + * @param {boolean} [checkLeft] - Should bodies check against the left edge of the boundary? + * @param {boolean} [checkRight] - Should bodies check against the right edge of the boundary? + * @param {boolean} [checkUp] - Should bodies check against the top edge of the boundary? + * @param {boolean} [checkDown] - Should bodies check against the bottom edge of the boundary? + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + setBounds: function (x, y, width, height, checkLeft, checkRight, checkUp, checkDown) + { + this.bounds.setTo(x, y, width, height); + + if (checkLeft !== undefined) + { + this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); + } + + return this; + }, + + /** + * Enables or disables collisions on each edge of the World boundary. + * + * @method Phaser.Physics.Arcade.World#setBoundsCollision + * @since 3.0.0 + * + * @param {boolean} [left=true] - Should bodies check against the left edge of the boundary? + * @param {boolean} [right=true] - Should bodies check against the right edge of the boundary? + * @param {boolean} [up=true] - Should bodies check against the top edge of the boundary? + * @param {boolean} [down=true] - Should bodies check against the bottom edge of the boundary? + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + setBoundsCollision: function (left, right, up, down) + { + if (left === undefined) { left = true; } + if (right === undefined) { right = true; } + if (up === undefined) { up = true; } + if (down === undefined) { down = true; } + + this.checkCollision.left = left; + this.checkCollision.right = right; + this.checkCollision.up = up; + this.checkCollision.down = down; + + return this; + }, + + /** + * Pauses the simulation. + * + * A paused simulation does not update any existing bodies, or run any Colliders. + * + * However, you can still enable and disable bodies within it, or manually run collide or overlap + * checks. + * + * @method Phaser.Physics.Arcade.World#pause + * @fires Phaser.Physics.Arcade.Events#PAUSE + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + pause: function () + { + this.isPaused = true; + + this.emit(Events.PAUSE); + + return this; + }, + + /** + * Resumes the simulation, if paused. + * + * @method Phaser.Physics.Arcade.World#resume + * @fires Phaser.Physics.Arcade.Events#RESUME + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + resume: function () + { + this.isPaused = false; + + this.emit(Events.RESUME); + + return this; + }, + + /** + * Creates a new Collider object and adds it to the simulation. + * + * A Collider is a way to automatically perform collision checks between two objects, + * calling the collide and process callbacks if they occur. + * + * Colliders are run as part of the World update, after all of the Bodies have updated. + * + * By creating a Collider you don't need then call `World.collide` in your `update` loop, + * as it will be handled for you automatically. + * + * @method Phaser.Physics.Arcade.World#addCollider + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#collide + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + addCollider: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); + + this.colliders.add(collider); + + return collider; + }, + + /** + * Creates a new Overlap Collider object and adds it to the simulation. + * + * A Collider is a way to automatically perform overlap checks between two objects, + * calling the collide and process callbacks if they occur. + * + * Colliders are run as part of the World update, after all of the Bodies have updated. + * + * By creating a Collider you don't need then call `World.overlap` in your `update` loop, + * as it will be handled for you automatically. + * + * @method Phaser.Physics.Arcade.World#addOverlap + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects overlap. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + addOverlap: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); + + this.colliders.add(collider); + + return collider; + }, + + /** + * Removes a Collider from the simulation so it is no longer processed. + * + * This method does not destroy the Collider. If you wish to add it back at a later stage you can call + * `World.colliders.add(Collider)`. + * + * If you no longer need the Collider you can call the `Collider.destroy` method instead, which will + * automatically clear all of its references and then remove it from the World. If you call destroy on + * a Collider you _don't_ need to pass it to this method too. + * + * @method Phaser.Physics.Arcade.World#removeCollider + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Collider} collider - The Collider to remove from the simulation. + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + removeCollider: function (collider) + { + this.colliders.remove(collider); + + return this; + }, + + /** + * Sets the frame rate to run the simulation at. + * + * The frame rate value is used to simulate a fixed update time step. This fixed + * time step allows for a straightforward implementation of a deterministic game state. + * + * This frame rate is independent of the frequency at which the game is rendering. The + * higher you set the fps, the more physics simulation steps will occur per game step. + * Conversely, the lower you set it, the less will take place. + * + * You can optionally advance the simulation directly yourself by calling the `step` method. + * + * @method Phaser.Physics.Arcade.World#setFPS + * @since 3.10.0 + * + * @param {number} framerate - The frame rate to advance the simulation at. + * + * @return {this} This World object. + */ + setFPS: function (framerate) + { + this.fps = framerate; + this._frameTime = 1 / this.fps; + this._frameTimeMS = 1000 * this._frameTime; + + return this; + }, + + /** + * Advances the simulation based on the elapsed time and fps rate. + * + * This is called automatically by your Scene and does not need to be invoked directly. + * + * @method Phaser.Physics.Arcade.World#update + * @fires Phaser.Physics.Arcade.Events#WORLD_STEP + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + update: function (time, delta) + { + if (this.isPaused || this.bodies.size === 0) + { + return; + } + + var i; + var fixedDelta = this._frameTime; + var msPerFrame = this._frameTimeMS * this.timeScale; + + this._elapsed += delta; + + // Update all active bodies + var body; + var bodies = this.bodies.entries; + + // Will a step happen this frame? + var willStep = (this._elapsed >= msPerFrame); + + if (!this.fixedStep) + { + fixedDelta = delta * 0.001; + willStep = true; + this._elapsed = 0; + } + + for (i = 0; i < bodies.length; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.preUpdate(willStep, fixedDelta); + } + } + + // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs + if (willStep) + { + this._elapsed -= msPerFrame; + this.stepsLastFrame = 1; + + // Optionally populate our dynamic collision tree + if (this.useTree) + { + this.tree.clear(); + this.tree.load(bodies); + } + + // Process any colliders + var colliders = this.colliders.update(); + + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; + + if (collider.active) + { + collider.update(); + } + } + + this.emit(Events.WORLD_STEP, fixedDelta); + } + + // Process any additional steps this frame + while (this._elapsed >= msPerFrame) + { + this._elapsed -= msPerFrame; + + this.step(fixedDelta); + } + }, + + /** + * Advances the simulation by a time increment. + * + * @method Phaser.Physics.Arcade.World#step + * @fires Phaser.Physics.Arcade.Events#WORLD_STEP + * @since 3.10.0 + * + * @param {number} delta - The delta time amount, in seconds, by which to advance the simulation. + */ + step: function (delta) + { + // Update all active bodies + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.update(delta); + } + } + + // Optionally populate our dynamic collision tree + if (this.useTree) + { + this.tree.clear(); + this.tree.load(bodies); + } + + // Process any colliders + var colliders = this.colliders.update(); + + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; + + if (collider.active) + { + collider.update(); + } + } + + this.emit(Events.WORLD_STEP, delta); + + this.stepsLastFrame++; + }, + + /** + * Updates bodies, draws the debug display, and handles pending queue operations. + * + * @method Phaser.Physics.Arcade.World#postUpdate + * @since 3.0.0 + */ + postUpdate: function () + { + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; + + var dynamic = this.bodies; + var staticBodies = this.staticBodies; + + // We don't need to postUpdate if there wasn't a step this frame + if (this.stepsLastFrame) + { + this.stepsLastFrame = 0; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.postUpdate(); + } + } + } + + if (this.drawDebug) + { + var graphics = this.debugGraphic; + + graphics.clear(); + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } + } + + bodies = staticBodies.entries; + len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } + } + } + + var pending = this.pendingDestroy; + + if (pending.size > 0) + { + var dynamicTree = this.tree; + var staticTree = this.staticTree; + + bodies = pending.entries; + len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.physicsType === CONST.DYNAMIC_BODY) + { + dynamicTree.remove(body); + dynamic.delete(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + staticTree.remove(body); + staticBodies.delete(body); + } + + body.world = undefined; + body.gameObject = undefined; + } + + pending.clear(); + } + }, + + /** + * Calculates a Body's velocity and updates its position. + * + * @method Phaser.Physics.Arcade.World#updateMotion + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to be updated. + * @param {number} delta - The delta value to be used in the motion calculations, in seconds. + */ + updateMotion: function (body, delta) + { + if (body.allowRotation) + { + this.computeAngularVelocity(body, delta); + } + + this.computeVelocity(body, delta); + }, + + /** + * Calculates a Body's angular velocity. + * + * @method Phaser.Physics.Arcade.World#computeAngularVelocity + * @since 3.10.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. + * @param {number} delta - The delta value to be used in the calculation, in seconds. + */ + computeAngularVelocity: function (body, delta) + { + var velocity = body.angularVelocity; + var acceleration = body.angularAcceleration; + var drag = body.angularDrag; + var max = body.maxAngular; + + if (acceleration) + { + velocity += acceleration * delta; + } + else if (body.allowDrag && drag) + { + drag *= delta; + + if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) + { + velocity -= drag; + } + else if (FuzzyLessThan(velocity + drag, 0, 0.1)) + { + velocity += drag; + } + else + { + velocity = 0; + } + } + + velocity = Clamp(velocity, -max, max); + + var velocityDelta = velocity - body.angularVelocity; + + body.angularVelocity += velocityDelta; + body.rotation += (body.angularVelocity * delta); + }, + + /** + * Calculates a Body's per-axis velocity. + * + * @method Phaser.Physics.Arcade.World#computeVelocity + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. + * @param {number} delta - The delta value to be used in the calculation, in seconds. + */ + computeVelocity: function (body, delta) + { + var velocityX = body.velocity.x; + var accelerationX = body.acceleration.x; + var dragX = body.drag.x; + var maxX = body.maxVelocity.x; + + var velocityY = body.velocity.y; + var accelerationY = body.acceleration.y; + var dragY = body.drag.y; + var maxY = body.maxVelocity.y; + + var speed = body.speed; + var maxSpeed = body.maxSpeed; + var allowDrag = body.allowDrag; + var useDamping = body.useDamping; + + if (body.allowGravity) + { + velocityX += (this.gravity.x + body.gravity.x) * delta; + velocityY += (this.gravity.y + body.gravity.y) * delta; + } + + if (accelerationX) + { + velocityX += accelerationX * delta; + } + else if (allowDrag && dragX) + { + if (useDamping) + { + // Damping based deceleration + dragX = Math.pow(dragX, delta); + + velocityX *= dragX; + + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityX = 0; + } + } + else + { + // Linear deceleration + dragX *= delta; + + if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) + { + velocityX -= dragX; + } + else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) + { + velocityX += dragX; + } + else + { + velocityX = 0; + } + } + } + + if (accelerationY) + { + velocityY += accelerationY * delta; + } + else if (allowDrag && dragY) + { + if (useDamping) + { + // Damping based deceleration + dragY = Math.pow(dragY, delta); + + velocityY *= dragY; + + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityY = 0; + } + } + else + { + // Linear deceleration + dragY *= delta; + + if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) + { + velocityY -= dragY; + } + else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) + { + velocityY += dragY; + } + else + { + velocityY = 0; + } + } + } + + velocityX = Clamp(velocityX, -maxX, maxX); + velocityY = Clamp(velocityY, -maxY, maxY); + + body.velocity.set(velocityX, velocityY); + + if (maxSpeed > -1 && speed > maxSpeed) + { + body.velocity.normalize().scale(maxSpeed); + speed = maxSpeed; + } + + body.speed = speed; + }, + + /** + * Separates two Bodies. + * + * @method Phaser.Physics.Arcade.World#separate + * @fires Phaser.Physics.Arcade.Events#COLLIDE + * @fires Phaser.Physics.Arcade.Events#OVERLAP + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. + * @param {ArcadePhysicsCallback} [processCallback] - The process callback. + * @param {*} [callbackContext] - The context in which to invoke the callback. + * @param {boolean} [overlapOnly] - If this a collide or overlap check? + * @param {boolean} [intersects] - Assert that the bodies intersect and should not be tested before separation. + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects) + { + if ( + !intersects && + !body1.enable || + !body2.enable || + body1.checkCollision.none || + body2.checkCollision.none || + !this.intersects(body1, body2)) + { + return false; + } + + // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort. + if (processCallback && processCallback.call(callbackContext, body1.gameObject, body2.gameObject) === false) + { + return false; + } + + // Circle vs. Circle quick bail out + if (body1.isCircle && body2.isCircle) + { + return this.separateCircle(body1, body2, overlapOnly); + } + + // We define the behavior of bodies in a collision circle and rectangle + // If a collision occurs in the corner points of the rectangle, the body behave like circles + + // Either body1 or body2 is a circle + if (body1.isCircle !== body2.isCircle) + { + var bodyRect = (body1.isCircle) ? body2 : body1; + var bodyCircle = (body1.isCircle) ? body1 : body2; + + var rect = { + x: bodyRect.x, + y: bodyRect.y, + right: bodyRect.right, + bottom: bodyRect.bottom + }; + + var circle = bodyCircle.center; + + if (circle.y < rect.y || circle.y > rect.bottom) + { + if (circle.x < rect.x || circle.x > rect.right) + { + return this.separateCircle(body1, body2, overlapOnly); + } + } + } + + var resultX = false; + var resultY = false; + + // Do we separate on x first or y first or both? + if (overlapOnly) + { + // No separation but we need to calculate overlapX, overlapY, etc. + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + else if (this.forceX || Math.abs(this.gravity.y + body1.gravity.y) < Math.abs(this.gravity.x + body1.gravity.x)) + { + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + } + else + { + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + } + + var result = (resultX || resultY); + + if (result) + { + if (overlapOnly) + { + if (body1.onOverlap || body2.onOverlap) + { + this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); + } + } + else if (body1.onCollide || body2.onCollide) + { + this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); + } + } + + return result; + }, + + /** + * Separates two Bodies, when both are circular. + * + * @method Phaser.Physics.Arcade.World#separateCircle + * @fires Phaser.Physics.Arcade.Events#COLLIDE + * @fires Phaser.Physics.Arcade.Events#OVERLAP + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. + * @param {boolean} [overlapOnly] - If this a collide or overlap check? + * @param {number} [bias] - A small value added to the calculations. + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separateCircle: function (body1, body2, overlapOnly, bias) + { + // Set the bounding box overlap values into the bodies themselves (hence we don't use the return values here) + GetOverlapX(body1, body2, false, bias); + GetOverlapY(body1, body2, false, bias); + + var overlap = 0; + + if (body1.isCircle !== body2.isCircle) + { + var rect = { + x: (body2.isCircle) ? body1.position.x : body2.position.x, + y: (body2.isCircle) ? body1.position.y : body2.position.y, + right: (body2.isCircle) ? body1.right : body2.right, + bottom: (body2.isCircle) ? body1.bottom : body2.bottom + }; + + var circle = { + x: (body1.isCircle) ? body1.center.x : body2.center.x, + y: (body1.isCircle) ? body1.center.y : body2.center.y, + radius: (body1.isCircle) ? body1.halfWidth : body2.halfWidth + }; + + if (circle.y < rect.y) + { + if (circle.x < rect.x) + { + overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.y) - circle.radius; + } + else if (circle.x > rect.right) + { + overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.y) - circle.radius; + } + } + else if (circle.y > rect.bottom) + { + if (circle.x < rect.x) + { + overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.bottom) - circle.radius; + } + else if (circle.x > rect.right) + { + overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.bottom) - circle.radius; + } + } + + overlap *= -1; + } + else + { + overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y); + } + + body1.overlapR = overlap; + body2.overlapR = overlap; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1.immovable && body2.immovable) || body1.customSeparateX || body2.customSeparateX) + { + if (overlap !== 0 && (body1.onOverlap || body2.onOverlap)) + { + this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); + } + + // return true if there was some overlap, otherwise false + return (overlap !== 0); + } + + var dx = body1.center.x - body2.center.x; + var dy = body1.center.y - body2.center.y; + var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + var nx = ((body2.center.x - body1.center.x) / d) || 0; + var ny = ((body2.center.y - body1.center.y) / d) || 0; + var p = 2 * (body1.velocity.x * nx + body1.velocity.y * ny - body2.velocity.x * nx - body2.velocity.y * ny) / (body1.mass + body2.mass); + + if (body1.immovable || body2.immovable) + { + p *= 2; + } + + if (!body1.immovable) + { + body1.velocity.x = (body1.velocity.x - p / body1.mass * nx); + body1.velocity.y = (body1.velocity.y - p / body1.mass * ny); + } + + if (!body2.immovable) + { + body2.velocity.x = (body2.velocity.x + p / body2.mass * nx); + body2.velocity.y = (body2.velocity.y + p / body2.mass * ny); + } + + if (!body1.immovable && !body2.immovable) + { + overlap /= 2; + } + + // Note: This is inadequate for circle-rectangle separation + + var angle = AngleBetweenPoints(body1.center, body2.center); + var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle); + var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle); + + if (!body1.immovable) + { + body1.x -= overlapX; + body1.y -= overlapY; + + body1.updateCenter(); + } + + if (!body2.immovable) + { + body2.x += overlapX; + body2.y += overlapY; + + body2.updateCenter(); + } + + body1.velocity.x *= body1.bounce.x; + body1.velocity.y *= body1.bounce.y; + body2.velocity.x *= body2.bounce.x; + body2.velocity.y *= body2.bounce.y; + + if (body1.onCollide || body2.onCollide) + { + this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); + } + + return true; + }, + + /** + * Checks to see if two Bodies intersect at all. + * + * @method Phaser.Physics.Arcade.World#intersects + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first body to check. + * @param {Phaser.Physics.Arcade.Body} body2 - The second body to check. + * + * @return {boolean} True if the two bodies intersect, otherwise false. + */ + intersects: function (body1, body2) + { + if (body1 === body2) + { + return false; + } + + if (!body1.isCircle && !body2.isCircle) + { + // Rect vs. Rect + return !( + body1.right <= body2.position.x || + body1.bottom <= body2.position.y || + body1.position.x >= body2.right || + body1.position.y >= body2.bottom + ); + } + else if (body1.isCircle) + { + if (body2.isCircle) + { + // Circle vs. Circle + return DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y) <= (body1.halfWidth + body2.halfWidth); + } + else + { + // Circle vs. Rect + return this.circleBodyIntersects(body1, body2); + } + } + else + { + // Rect vs. Circle + return this.circleBodyIntersects(body2, body1); + } + }, + + /** + * Tests if a circular Body intersects with another Body. + * + * @method Phaser.Physics.Arcade.World#circleBodyIntersects + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} circle - The circular body to test. + * @param {Phaser.Physics.Arcade.Body} body - The rectangular body to test. + * + * @return {boolean} True if the two bodies intersect, otherwise false. + */ + circleBodyIntersects: function (circle, body) + { + var x = Clamp(circle.center.x, body.left, body.right); + var y = Clamp(circle.center.y, body.top, body.bottom); + + var dx = (circle.center.x - x) * (circle.center.x - x); + var dy = (circle.center.y - y) * (circle.center.y - y); + + return (dx + dy) <= (circle.halfWidth * circle.halfWidth); + }, + + /** + * Tests if Game Objects overlap. + * + * See details in {@link Phaser.Physics.Arcade.World#collide}. + * + * @method Phaser.Physics.Arcade.World#overlap + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `overlapCallback` will only be called if this callback returns `true`. + * @param {*} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if at least one Game Object overlaps another. + * + * @see Phaser.Physics.Arcade.World#collide + */ + overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) + { + if (overlapCallback === undefined) { overlapCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = overlapCallback; } + + return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true); + }, + + /** + * Performs a collision check and separation between the two physics enabled objects given, which can be single + * Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups. + * + * If you don't require separation then use {@link Phaser.Physics.Arcade.World#overlap} instead. + * + * If two Groups or arrays are passed, each member of one will be tested against each member of the other. + * + * If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members. + * + * If **only** one Array is passed, the array is iterated and every element in it is tested against the others. + * + * Two callbacks can be provided; they receive the colliding game objects as arguments. + * If an overlap is detected, the `processCallback` is called first. It can cancel the collision by returning false. + * Next the objects are separated and `collideCallback` is invoked. + * + * Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable + * for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other. + * The separation that stops two objects penetrating may create a new penetration against a different object. If you + * require a high level of stability please consider using an alternative physics system, such as Matter.js. + * + * @method Phaser.Physics.Arcade.World#collide + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} `true` if any overlapping Game Objects were separated, otherwise `false`. + */ + collide: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); + }, + + /** + * Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideObjects + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideObjects: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) + { + var i; + var j; + + if (object1.isParent && object1.physicsType === undefined) + { + object1 = object1.children.entries; + } + + if (object2 && object2.isParent && object2.physicsType === undefined) + { + object2 = object2.children.entries; + } + + var object1isArray = Array.isArray(object1); + var object2isArray = Array.isArray(object2); + + this._total = 0; + + if (!object1isArray && !object2isArray) + { + // Neither of them are arrays - do this first as it's the most common use-case + this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (!object1isArray && object2isArray) + { + // Object 2 is an Array + for (i = 0; i < object2.length; i++) + { + this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + else if (object1isArray && !object2isArray) + { + // Object 1 is an Array + if (!object2) + { + // Special case for array vs. self + for (i = 0; i < object1.length; i++) + { + var child = object1[i]; + + for (j = i + 1; j < object1.length; j++) + { + if (i === j) + { + continue; + } + + this.collideHandler(child, object1[j], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + else + { + for (i = 0; i < object1.length; i++) + { + this.collideHandler(object1[i], object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + else + { + // They're both arrays + for (i = 0; i < object1.length; i++) + { + for (j = 0; j < object2.length; j++) + { + this.collideHandler(object1[i], object2[j], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + + return (this._total > 0); + }, + + /** + * Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead. + * + * @method Phaser.Physics.Arcade.World#collideHandler + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) + { + // Collide Group with Self + // Only collide valid objects + if (object2 === undefined && object1.isParent) + { + return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + + // If neither of the objects are set then bail out + if (!object1 || !object2) + { + return false; + } + + // A Body + if (object1.body) + { + if (object2.body) + { + return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isTilemap) + { + return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + + // GROUPS + else if (object1.isParent) + { + if (object2.body) + { + return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isTilemap) + { + return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + + // TILEMAP LAYERS + else if (object1.isTilemap) + { + if (object2.body) + { + return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + }, + + /** + * Internal handler for Sprite vs. Sprite collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsSprite + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite1 - The first object to check for collision. + * @param {Phaser.GameObjects.GameObject} sprite2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) + { + if (!sprite1.body || !sprite2.body) + { + return false; + } + + if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite1, sprite2); + } + + this._total++; + } + + return true; + }, + + /** + * Internal handler for Sprite vs. Group collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsGroup + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.GameObjects.Group} group - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. + */ + collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) + { + var bodyA = sprite.body; + + if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) + { + return; + } + + // Does sprite collide with anything? + + var i; + var len; + var bodyB; + + if (this.useTree || group.physicsType === CONST.STATIC_BODY) + { + var minMax = this.treeMinMax; + + minMax.minX = bodyA.left; + minMax.minY = bodyA.top; + minMax.maxX = bodyA.right; + minMax.maxY = bodyA.bottom; + + var results = (group.physicsType === CONST.DYNAMIC_BODY) ? this.tree.search(minMax) : this.staticTree.search(minMax); + + len = results.length; + + for (i = 0; i < len; i++) + { + bodyB = results[i]; + + if (bodyA === bodyB || !bodyB.enable || bodyB.checkCollision.none || !group.contains(bodyB.gameObject)) + { + // Skip if comparing against itself, or if bodyB isn't collidable, or if bodyB isn't actually part of the Group + continue; + } + + if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); + } + + this._total++; + } + } + } + else + { + var children = group.getChildren(); + var skipIndex = group.children.entries.indexOf(sprite); + + len = children.length; + + for (i = 0; i < len; i++) + { + bodyB = children[i].body; + + if (!bodyB || i === skipIndex || !bodyB.enable) + { + continue; + } + + if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); + } + + this._total++; + } + } + } + }, + + /** + * Internal handler for Group vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Group} group - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + { + var children = group.getChildren(); + + if (children.length === 0) + { + return false; + } + + var didCollide = false; + + for (var i = 0; i < children.length; i++) + { + if (children[i].body) + { + if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) + { + didCollide = true; + } + } + } + + return didCollide; + }, + + /** + * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. + * + * You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform + * tile filtering and culling for you, as well as handle the interesting face collision automatically. + * + * This method is offered for those who would like to check for collision with specific Tiles in a layer, without + * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions + * on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, + * you should filter them before passing them to this method. + * + * Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have + * say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the + * tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on + * dynamic maps, this method can prove very useful. + * + * @method Phaser.Physics.Arcade.World#collideTiles + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) + { + if (!sprite.body.enable || tiles.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); + } + }, + + /** + * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. + * + * You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform + * tile filtering and culling for you, as well as handle the interesting face collision automatically. + * + * This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without + * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap + * tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, + * you should filter them before passing them to this method. + * + * @method Phaser.Physics.Arcade.World#overlapTiles + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + overlapTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) + { + if (!sprite.body.enable || tiles.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); + } + }, + + /** + * Internal handler for Sprite vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsTilemapLayer + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + { + var body = sprite.body; + + if (!body.enable || body.checkCollision.none) + { + return false; + } + + var x = body.position.x; + var y = body.position.y; + var w = body.width; + var h = body.height; + + var layerData = tilemapLayer.layer; + + if (layerData.tileWidth > layerData.baseTileWidth) + { + // The x origin of a tile is the left side, so x and width need to be adjusted. + var xDiff = (layerData.tileWidth - layerData.baseTileWidth) * tilemapLayer.scaleX; + x -= xDiff; + w += xDiff; + } + + if (layerData.tileHeight > layerData.baseTileHeight) + { + // The y origin of a tile is the bottom side, so just the height needs to be adjusted. + var yDiff = (layerData.tileHeight - layerData.baseTileHeight) * tilemapLayer.scaleY; + h += yDiff; + } + + var mapData = GetTilesWithinWorldXY(x, y, w, h, null, tilemapLayer.scene.cameras.main, tilemapLayer.layer); + + if (mapData.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); + } + }, + + /** + * Internal handler for Sprite vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @private + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. + * @param {boolean} [isLayer] - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) + { + var body = sprite.body; + + var tile; + var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 }; + var tilemapLayer; + var collision = false; + + for (var i = 0; i < tiles.length; i++) + { + tile = tiles[i]; + + tilemapLayer = tile.tilemapLayer; + + var point = tilemapLayer.tileToWorldXY(tile.x, tile.y); + + tileWorldRect.left = point.x; + tileWorldRect.top = point.y; + + // If the maps base tile size differs from the layer tile size, only the top of the rect + // needs to be adjusted since its origin is (0, 1). + if (tile.baseHeight !== tile.height) + { + tileWorldRect.top -= (tile.height - tile.baseHeight) * tilemapLayer.scaleY; + } + + tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; + tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; + + if (TileIntersectsBody(tileWorldRect, body) + && (!processCallback || processCallback.call(callbackContext, sprite, tile)) + && ProcessTileCallbacks(tile, sprite) + && (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS, isLayer))) + { + this._total++; + + collision = true; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, tile); + } + + if (overlapOnly && body.onOverlap) + { + this.emit(Events.TILE_OVERLAP, sprite, tile, body); + } + else if (body.onCollide) + { + this.emit(Events.TILE_COLLIDE, sprite, tile, body); + } + } + } + + return collision; + }, + + /** + * Internal helper for Group vs. Group collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideGroupVsGroup + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Group} group1 - The first object to check for collision. + * @param {Phaser.GameObjects.Group} group2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) + { + if (group1.length === 0 || group2.length === 0) + { + return; + } + + var children = group1.getChildren(); + + for (var i = 0; i < children.length; i++) + { + this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); + } + }, + + /** + * Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}. + * + * If the object is outside any boundary edge (left, top, right, bottom), it will be moved to the same offset from the opposite edge (the interior). + * + * @method Phaser.Physics.Arcade.World#wrap + * @since 3.3.0 + * + * @param {any} object - A Game Object, a Group, an object with `x` and `y` coordinates, or an array of such objects. + * @param {number} [padding=0] - An amount added to each boundary edge during the operation. + */ + wrap: function (object, padding) + { + if (object.body) + { + this.wrapObject(object, padding); + } + else if (object.getChildren) + { + this.wrapArray(object.getChildren(), padding); + } + else if (Array.isArray(object)) + { + this.wrapArray(object, padding); + } + else + { + this.wrapObject(object, padding); + } + }, + + /** + * Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. + * + * @method Phaser.Physics.Arcade.World#wrapArray + * @since 3.3.0 + * + * @param {Array.<*>} objects - An array of objects to be wrapped. + * @param {number} [padding=0] - An amount added to the boundary. + */ + wrapArray: function (objects, padding) + { + for (var i = 0; i < objects.length; i++) + { + this.wrapObject(objects[i], padding); + } + }, + + /** + * Wrap an object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. + * + * @method Phaser.Physics.Arcade.World#wrapObject + * @since 3.3.0 + * + * @param {*} object - A Game Object, a Physics Body, or any object with `x` and `y` coordinates + * @param {number} [padding=0] - An amount added to the boundary. + */ + wrapObject: function (object, padding) + { + if (padding === undefined) { padding = 0; } + + object.x = Wrap(object.x, this.bounds.left - padding, this.bounds.right + padding); + object.y = Wrap(object.y, this.bounds.top - padding, this.bounds.bottom + padding); + }, + + /** + * Shuts down the simulation, clearing physics data and removing listeners. + * + * @method Phaser.Physics.Arcade.World#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + this.tree.clear(); + this.staticTree.clear(); + this.bodies.clear(); + this.staticBodies.clear(); + this.colliders.destroy(); + + this.removeAllListeners(); + }, + + /** + * Shuts down the simulation and disconnects it from the current scene. + * + * @method Phaser.Physics.Arcade.World#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + + this.scene = null; + } + +}); + +module.exports = World; + + +/***/ }), +/* 521 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Benjamin D. Richards + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var Events = __webpack_require__(242); +var RadToDeg = __webpack_require__(193); +var Rectangle = __webpack_require__(10); +var RectangleContains = __webpack_require__(56); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A Dynamic Arcade Body. + * + * Its static counterpart is {@link Phaser.Physics.Arcade.StaticBody}. + * + * @class Body + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Body belongs to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. + */ +var Body = new Class({ + + initialize: + + function Body (world, gameObject) + { + var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; + var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; + + /** + * The Arcade Physics simulation this Body belongs to. + * + * @name Phaser.Physics.Arcade.Body#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The Game Object this Body belongs to. + * + * @name Phaser.Physics.Arcade.Body#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = gameObject; + + /** + * Transformations applied to this Body. + * + * @name Phaser.Physics.Arcade.Body#transform + * @type {object} + * @since 3.4.0 + */ + this.transform = { + x: gameObject.x, + y: gameObject.y, + rotation: gameObject.angle, + scaleX: gameObject.scaleX, + scaleY: gameObject.scaleY, + displayOriginX: gameObject.displayOriginX, + displayOriginY: gameObject.displayOriginY + }; + + /** + * Whether the Body is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugShowBody + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowBody = world.defaults.debugShowBody; + + /** + * Whether the Body's velocity is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugShowVelocity + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowVelocity = world.defaults.debugShowVelocity; + + /** + * The color of this Body on the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugBodyColor + * @type {number} + * @since 3.0.0 + */ + this.debugBodyColor = world.defaults.bodyDebugColor; + + /** + * Whether this Body is updated by the physics simulation. + * + * @name Phaser.Physics.Arcade.Body#enable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enable = true; + + /** + * Whether this Body is circular (true) or rectangular (false). + * + * @name Phaser.Physics.Arcade.Body#isCircle + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setCircle + */ + this.isCircle = false; + + /** + * If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels. + * The true radius is equal to `halfWidth`. + * + * @name Phaser.Physics.Arcade.Body#radius + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setCircle + */ + this.radius = 0; + + /** + * The offset of this Body's position from its Game Object's position, in source pixels. + * + * @name Phaser.Physics.Arcade.Body#offset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setOffset + */ + this.offset = new Vector2(); + + /** + * The position of this Body within the simulation. + * + * @name Phaser.Physics.Arcade.Body#position + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.position = new Vector2( + gameObject.x - gameObject.scaleX * gameObject.displayOriginX, + gameObject.y - gameObject.scaleY * gameObject.displayOriginY + ); + + /** + * The position of this Body during the previous step. + * + * @name Phaser.Physics.Arcade.Body#prev + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.prev = this.position.clone(); + + /** + * The position of this Body during the previous frame. + * + * @name Phaser.Physics.Arcade.Body#prevFrame + * @type {Phaser.Math.Vector2} + * @since 3.20.0 + */ + this.prevFrame = this.position.clone(); + + /** + * Whether this Body's `rotation` is affected by its angular acceleration and angular velocity. + * + * @name Phaser.Physics.Arcade.Body#allowRotation + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.allowRotation = true; + + /** + * This body's rotation, in degrees, based on its angular acceleration and angular velocity. + * The Body's rotation controls the `angle` of its Game Object. + * It doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle. + * + * @name Phaser.Physics.Arcade.Body#rotation + * @type {number} + * @since 3.0.0 + */ + this.rotation = gameObject.angle; + + /** + * The Body rotation, in degrees, during the previous step. + * + * @name Phaser.Physics.Arcade.Body#preRotation + * @type {number} + * @since 3.0.0 + */ + this.preRotation = gameObject.angle; + + /** + * The width of the Body, in pixels. + * If the Body is circular, this is also the diameter. + * If you wish to change the width use the `Body.setSize` method. + * + * @name Phaser.Physics.Arcade.Body#width + * @type {number} + * @readonly + * @default 64 + * @since 3.0.0 + */ + this.width = width; + + /** + * The height of the Body, in pixels. + * If the Body is circular, this is also the diameter. + * If you wish to change the height use the `Body.setSize` method. + * + * @name Phaser.Physics.Arcade.Body#height + * @type {number} + * @readonly + * @default 64 + * @since 3.0.0 + */ + this.height = height; + + /** + * The unscaled width of the Body, in source pixels, as set by setSize(). + * The default is the width of the Body's Game Object's texture frame. + * + * @name Phaser.Physics.Arcade.Body#sourceWidth + * @type {number} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setSize + */ + this.sourceWidth = width; + + /** + * The unscaled height of the Body, in source pixels, as set by setSize(). + * The default is the height of the Body's Game Object's texture frame. + * + * @name Phaser.Physics.Arcade.Body#sourceHeight + * @type {number} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setSize + */ + this.sourceHeight = height; + + if (gameObject.frame) + { + this.sourceWidth = gameObject.frame.realWidth; + this.sourceHeight = gameObject.frame.realHeight; + } + + /** + * Half the Body's width, in pixels. + * + * @name Phaser.Physics.Arcade.Body#halfWidth + * @type {number} + * @since 3.0.0 + */ + this.halfWidth = Math.abs(width / 2); + + /** + * Half the Body's height, in pixels. + * + * @name Phaser.Physics.Arcade.Body#halfHeight + * @type {number} + * @since 3.0.0 + */ + this.halfHeight = Math.abs(height / 2); + + /** + * The center of the Body. + * The midpoint of its `position` (top-left corner) and its bottom-right corner. + * + * @name Phaser.Physics.Arcade.Body#center + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + /** + * The Body's velocity, in pixels per second. + * + * @name Phaser.Physics.Arcade.Body#velocity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.velocity = new Vector2(); + + /** + * The Body's change in position (due to velocity) at the last step, in pixels. + * + * The size of this value depends on the simulation's step rate. + * + * @name Phaser.Physics.Arcade.Body#newVelocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.newVelocity = new Vector2(); + + /** + * The Body's absolute maximum change in position, in pixels per step. + * + * @name Phaser.Physics.Arcade.Body#deltaMax + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.deltaMax = new Vector2(); + + /** + * The Body's change in velocity, in pixels per second squared. + * + * @name Phaser.Physics.Arcade.Body#acceleration + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.acceleration = new Vector2(); + + /** + * Whether this Body's velocity is affected by its `drag`. + * + * @name Phaser.Physics.Arcade.Body#allowDrag + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.allowDrag = true; + + /** + * When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared. + * + * When `useDamping` is true, this is a damping multiplier between 0 and 1. + * A value of 0 means the Body stops instantly. + * A value of 0.01 mean the Body loses 99% of its velocity per second. + * A value of 0.1 means the Body loses 90% of its velocity per second. + * A value of 1 means the Body loses no velocity. + * + * The x and y components are applied separately. + * + * Drag is applied only when `acceleration` is zero. + * + * @name Phaser.Physics.Arcade.Body#drag + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.drag = new Vector2(); + + /** + * Whether this Body's position is affected by gravity (local or world). + * + * @name Phaser.Physics.Arcade.Body#allowGravity + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#gravity + * @see Phaser.Physics.Arcade.World#gravity + */ + this.allowGravity = true; + + /** + * Acceleration due to gravity (specific to this Body), in pixels per second squared. + * Total gravity is the sum of this vector and the simulation's `gravity`. + * + * @name Phaser.Physics.Arcade.Body#gravity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#gravity + */ + this.gravity = new Vector2(); + + /** + * Rebound following a collision, relative to 1. + * + * @name Phaser.Physics.Arcade.Body#bounce + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.bounce = new Vector2(); + + /** + * Rebound following a collision with the world boundary, relative to 1. + * If null, `bounce` is used instead. + * + * @name Phaser.Physics.Arcade.Body#worldBounce + * @type {?Phaser.Math.Vector2} + * @default null + * @since 3.0.0 + */ + this.worldBounce = null; + + /** + * The rectangle used for world boundary collisions. + * + * By default it is set to the world boundary rectangle. Or, if this Body was + * created by a Physics Group, then whatever rectangle that Group defined. + * + * You can also change it by using the `Body.setBoundsRectangle` method. + * + * @name Phaser.Physics.Arcade.Body#customBoundsRectangle + * @type {Phaser.Geom.Rectangle} + * @since 3.20 + */ + this.customBoundsRectangle = world.bounds; + + // If true this Body will dispatch events + + /** + * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). + * + * @name Phaser.Physics.Arcade.Body#onWorldBounds + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#WORLD_BOUNDS + */ + this.onWorldBounds = false; + + /** + * Whether the simulation emits a `collide` event when this Body collides with another. + * + * @name Phaser.Physics.Arcade.Body#onCollide + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#COLLIDE + */ + this.onCollide = false; + + /** + * Whether the simulation emits an `overlap` event when this Body overlaps with another. + * + * @name Phaser.Physics.Arcade.Body#onOverlap + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#OVERLAP + */ + this.onOverlap = false; + + /** + * The Body's absolute maximum velocity, in pixels per second. + * The horizontal and vertical components are applied separately. + * + * @name Phaser.Physics.Arcade.Body#maxVelocity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.maxVelocity = new Vector2(10000, 10000); + + /** + * The maximum speed this Body is allowed to reach, in pixels per second. + * + * If not negative it limits the scalar value of speed. + * + * Any negative value means no maximum is being applied (the default). + * + * @name Phaser.Physics.Arcade.Body#maxSpeed + * @type {number} + * @default -1 + * @since 3.16.0 + */ + this.maxSpeed = -1; + + /** + * If this Body is `immovable` and in motion, `friction` is the proportion of this Body's motion received by the riding Body on each axis, relative to 1. + * The horizontal component (x) is applied only when two colliding Bodies are separated vertically. + * The vertical component (y) is applied only when two colliding Bodies are separated horizontally. + * The default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all. + * + * @name Phaser.Physics.Arcade.Body#friction + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.friction = new Vector2(1, 0); + + /** + * If this Body is using `drag` for deceleration this property controls how the drag is applied. + * If set to `true` drag will use a damping effect rather than a linear approach. If you are + * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in + * the game Asteroids) then you will get a far smoother and more visually correct deceleration + * by using damping, avoiding the axis-drift that is prone with linear deceleration. + * + * If you enable this property then you should use far smaller `drag` values than with linear, as + * they are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow + * deceleration. + * + * @name Phaser.Physics.Arcade.Body#useDamping + * @type {boolean} + * @default false + * @since 3.10.0 + */ + this.useDamping = false; + + /** + * The rate of change of this Body's `rotation`, in degrees per second. + * + * @name Phaser.Physics.Arcade.Body#angularVelocity + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularVelocity = 0; + + /** + * The Body's angular acceleration (change in angular velocity), in degrees per second squared. + * + * @name Phaser.Physics.Arcade.Body#angularAcceleration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularAcceleration = 0; + + /** + * Loss of angular velocity due to angular movement, in degrees per second. + * + * Angular drag is applied only when angular acceleration is zero. + * + * @name Phaser.Physics.Arcade.Body#angularDrag + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularDrag = 0; + + /** + * The Body's maximum angular velocity, in degrees per second. + * + * @name Phaser.Physics.Arcade.Body#maxAngular + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.maxAngular = 1000; + + /** + * The Body's inertia, relative to a default unit (1). + * With `bounce`, this affects the exchange of momentum (velocities) during collisions. + * + * @name Phaser.Physics.Arcade.Body#mass + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.mass = 1; + + /** + * The calculated angle of this Body's velocity vector, in radians, during the last step. + * + * @name Phaser.Physics.Arcade.Body#angle + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angle = 0; + + /** + * The calculated magnitude of the Body's velocity, in pixels per second, during the last step. + * + * @name Phaser.Physics.Arcade.Body#speed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.speed = 0; + + /** + * The direction of the Body's velocity, as calculated during the last step. + * This is a numeric constant value (FACING_UP, FACING_DOWN, FACING_LEFT, FACING_RIGHT). + * If the Body is moving on both axes, this describes motion on the vertical axis only. + * + * @name Phaser.Physics.Arcade.Body#facing + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.FACING_UP + * @see Phaser.Physics.Arcade.FACING_DOWN + * @see Phaser.Physics.Arcade.FACING_LEFT + * @see Phaser.Physics.Arcade.FACING_RIGHT + */ + this.facing = CONST.FACING_NONE; + + /** + * Whether this Body can be moved by collisions with another Body. + * + * @name Phaser.Physics.Arcade.Body#immovable + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.immovable = false; + + /** + * Sets if this Body can be pushed by another Body. + * + * A body that cannot be pushed will reflect back all of the velocity it is given to the + * colliding body. If that body is also not pushable, then the separation will be split + * between them evenly. + * + * If you want your body to never move or seperate at all, see the `setImmovable` method. + * + * By default, Dynamic Bodies are always pushable. + * + * @name Phaser.Physics.Arcade.Body#pushable + * @type {boolean} + * @default true + * @since 3.50.0 + * @see Phaser.GameObjects.Components.Pushable#setPushable + */ + this.pushable = true; + + /** + * Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity. + * + * @name Phaser.Physics.Arcade.Body#moves + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.moves = true; + + /** + * A flag disabling the default horizontal separation of colliding bodies. + * Pass your own `collideCallback` to the collider. + * + * @name Phaser.Physics.Arcade.Body#customSeparateX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateX = false; + + /** + * A flag disabling the default vertical separation of colliding bodies. + * Pass your own `collideCallback` to the collider. + * + * @name Phaser.Physics.Arcade.Body#customSeparateY + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateY = false; + + /** + * The amount of horizontal overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.Body#overlapX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapX = 0; + + /** + * The amount of vertical overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.Body#overlapY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapY = 0; + + /** + * The amount of overlap (before separation), if this Body is circular and colliding with another circular body. + * + * @name Phaser.Physics.Arcade.Body#overlapR + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapR = 0; + + /** + * Whether this Body is overlapped with another and both are not moving, on at least one axis. + * + * @name Phaser.Physics.Arcade.Body#embedded + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.embedded = false; + + /** + * Whether this Body interacts with the world boundary. + * + * @name Phaser.Physics.Arcade.Body#collideWorldBounds + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.collideWorldBounds = false; + + /** + * Whether this Body is checked for collisions and for which directions. + * You can set `checkCollision.none = true` to disable collision checks. + * + * @name Phaser.Physics.Arcade.Body#checkCollision + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; + + /** + * Whether this Body is colliding with a Body or Static Body and in which direction. + * In a collision where both bodies have zero velocity, `embedded` will be set instead. + * + * @name Phaser.Physics.Arcade.Body#touching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#blocked + * @see Phaser.Physics.Arcade.Body#embedded + */ + this.touching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This Body's `touching` value during the previous step. + * + * @name Phaser.Physics.Arcade.Body#wasTouching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#touching + */ + this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * Whether this Body is colliding with a Static Body, a tile, or the world boundary. + * In a collision with a Static Body, if this Body has zero velocity then `embedded` will be set instead. + * + * @name Phaser.Physics.Arcade.Body#blocked + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#embedded + * @see Phaser.Physics.Arcade.Body#touching + */ + this.blocked = { none: true, up: false, down: false, left: false, right: false }; + + /** + * Whether to automatically synchronize this Body's dimensions to the dimensions of its Game Object's visual bounds. + * + * @name Phaser.Physics.Arcade.Body#syncBounds + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Components.GetBounds#getBounds + */ + this.syncBounds = false; + + /** + * The Body's physics type (dynamic or static). + * + * @name Phaser.Physics.Arcade.Body#physicsType + * @type {number} + * @readonly + * @default Phaser.Physics.Arcade.DYNAMIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.DYNAMIC_BODY; + + /** + * Cached horizontal scale of the Body's Game Object. + * + * @name Phaser.Physics.Arcade.Body#_sx + * @type {number} + * @private + * @since 3.0.0 + */ + this._sx = gameObject.scaleX; + + /** + * Cached vertical scale of the Body's Game Object. + * + * @name Phaser.Physics.Arcade.Body#_sy + * @type {number} + * @private + * @since 3.0.0 + */ + this._sy = gameObject.scaleY; + + /** + * The calculated change in the Body's horizontal position during the last step. + * + * @name Phaser.Physics.Arcade.Body#_dx + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._dx = 0; + + /** + * The calculated change in the Body's vertical position during the last step. + * + * @name Phaser.Physics.Arcade.Body#_dy + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._dy = 0; + + /** + * The final calculated change in the Body's horizontal position as of `postUpdate`. + * + * @name Phaser.Physics.Arcade.Body#_tx + * @type {number} + * @private + * @default 0 + * @since 3.22.0 + */ + this._tx = 0; + + /** + * The final calculated change in the Body's vertical position as of `postUpdate`. + * + * @name Phaser.Physics.Arcade.Body#_ty + * @type {number} + * @private + * @default 0 + * @since 3.22.0 + */ + this._ty = 0; + + /** + * Stores the Game Object's bounds. + * + * @name Phaser.Physics.Arcade.Body#_bounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.0.0 + */ + this._bounds = new Rectangle(); + }, + + /** + * Updates the Body's `transform`, `width`, `height`, and `center` from its Game Object. + * The Body's `position` isn't changed. + * + * @method Phaser.Physics.Arcade.Body#updateBounds + * @since 3.0.0 + */ + updateBounds: function () + { + var sprite = this.gameObject; + + // Container? + + var transform = this.transform; + + if (sprite.parentContainer) + { + var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2); + + transform.x = matrix.tx; + transform.y = matrix.ty; + transform.rotation = RadToDeg(matrix.rotation); + transform.scaleX = matrix.scaleX; + transform.scaleY = matrix.scaleY; + transform.displayOriginX = sprite.displayOriginX; + transform.displayOriginY = sprite.displayOriginY; + } + else + { + transform.x = sprite.x; + transform.y = sprite.y; + transform.rotation = sprite.angle; + transform.scaleX = sprite.scaleX; + transform.scaleY = sprite.scaleY; + transform.displayOriginX = sprite.displayOriginX; + transform.displayOriginY = sprite.displayOriginY; + } + + var recalc = false; + + if (this.syncBounds) + { + var b = sprite.getBounds(this._bounds); + + this.width = b.width; + this.height = b.height; + recalc = true; + } + else + { + var asx = Math.abs(transform.scaleX); + var asy = Math.abs(transform.scaleY); + + if (this._sx !== asx || this._sy !== asy) + { + this.width = this.sourceWidth * asx; + this.height = this.sourceHeight * asy; + this._sx = asx; + this._sy = asy; + recalc = true; + } + } + + if (recalc) + { + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + this.updateCenter(); + } + }, + + /** + * Updates the Body's `center` from its `position`, `width`, and `height`. + * + * @method Phaser.Physics.Arcade.Body#updateCenter + * @since 3.0.0 + */ + updateCenter: function () + { + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + }, + + /** + * Updates the Body's `position`, `width`, `height`, and `center` from its Game Object and `offset`. + * + * You don't need to call this for Dynamic Bodies, as it happens automatically during the physics step. + * But you could use it if you have modified the Body offset or Game Object transform and need to immediately + * read the Body's new `position` or `center`. + * + * To resynchronize the Body with its Game Object, use `reset()` instead. + * + * @method Phaser.Physics.Arcade.Body#updateFromGameObject + * @since 3.24.0 + */ + updateFromGameObject: function () + { + this.updateBounds(); + + var transform = this.transform; + + this.position.x = transform.x + transform.scaleX * (this.offset.x - transform.displayOriginX); + this.position.y = transform.y + transform.scaleY * (this.offset.y - transform.displayOriginY); + + this.updateCenter(); + }, + + /** + * Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states. + * + * This method is only called if the physics world is going to run a step this frame. + * + * @method Phaser.Physics.Arcade.Body#resetFlags + * @since 3.18.0 + * + * @param {boolean} [clear=false] - Set the `wasTouching` values to their defaults. + */ + resetFlags: function (clear) + { + if (clear === undefined) + { + clear = false; + } + + // Store and reset collision flags + var wasTouching = this.wasTouching; + var touching = this.touching; + var blocked = this.blocked; + + if (clear) + { + wasTouching.none = true; + wasTouching.up = false; + wasTouching.down = false; + wasTouching.left = false; + wasTouching.right = false; + } + else + { + wasTouching.none = touching.none; + wasTouching.up = touching.up; + wasTouching.down = touching.down; + wasTouching.left = touching.left; + wasTouching.right = touching.right; + } + + touching.none = true; + touching.up = false; + touching.down = false; + touching.left = false; + touching.right = false; + + blocked.none = true; + blocked.up = false; + blocked.down = false; + blocked.left = false; + blocked.right = false; + + this.overlapR = 0; + this.overlapX = 0; + this.overlapY = 0; + + this.embedded = false; + }, + + /** + * Syncs the position body position with the parent Game Object. + * + * This method is called every game frame, regardless if the world steps or not. + * + * @method Phaser.Physics.Arcade.Body#preUpdate + * @since 3.17.0 + * + * @param {boolean} willStep - Will this Body run an update as well? + * @param {number} delta - The delta time, in seconds, elapsed since the last frame. + */ + preUpdate: function (willStep, delta) + { + if (willStep) + { + this.resetFlags(); + } + + this.updateFromGameObject(); + + this.rotation = this.transform.rotation; + this.preRotation = this.rotation; + + if (this.moves) + { + this.prev.x = this.position.x; + this.prev.y = this.position.y; + this.prevFrame.x = this.position.x; + this.prevFrame.y = this.position.y; + } + + if (willStep) + { + this.update(delta); + } + }, + + /** + * Performs a single physics step and updates the body velocity, angle, speed and other properties. + * + * This method can be called multiple times per game frame, depending on the physics step rate. + * + * The results are synced back to the Game Object in `postUpdate`. + * + * @method Phaser.Physics.Arcade.Body#update + * @fires Phaser.Physics.Arcade.Events#WORLD_BOUNDS + * @since 3.0.0 + * + * @param {number} delta - The delta time, in seconds, elapsed since the last frame. + */ + update: function (delta) + { + this.prev.x = this.position.x; + this.prev.y = this.position.y; + + if (this.moves) + { + this.world.updateMotion(this, delta); + + var vx = this.velocity.x; + var vy = this.velocity.y; + + this.newVelocity.set(vx * delta, vy * delta); + + this.position.add(this.newVelocity); + + this.updateCenter(); + + this.angle = Math.atan2(vy, vx); + this.speed = Math.sqrt(vx * vx + vy * vy); + + // Now the update will throw collision checks at the Body + // And finally we'll integrate the new position back to the Sprite in postUpdate + + if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) + { + this.world.emit(Events.WORLD_BOUNDS, this, this.blocked.up, this.blocked.down, this.blocked.left, this.blocked.right); + } + } + + this._dx = this.position.x - this.prev.x; + this._dy = this.position.y - this.prev.y; + }, + + /** + * Feeds the Body results back into the parent Game Object. + * + * This method is called every game frame, regardless if the world steps or not. + * + * @method Phaser.Physics.Arcade.Body#postUpdate + * @since 3.0.0 + */ + postUpdate: function () + { + var dx = this.position.x - this.prevFrame.x; + var dy = this.position.y - this.prevFrame.y; + + if (this.moves) + { + var mx = this.deltaMax.x; + var my = this.deltaMax.y; + + if (mx !== 0 && dx !== 0) + { + if (dx < 0 && dx < -mx) + { + dx = -mx; + } + else if (dx > 0 && dx > mx) + { + dx = mx; + } + } + + if (my !== 0 && dy !== 0) + { + if (dy < 0 && dy < -my) + { + dy = -my; + } + else if (dy > 0 && dy > my) + { + dy = my; + } + } + + this.gameObject.x += dx; + this.gameObject.y += dy; + } + + if (dx < 0) + { + this.facing = CONST.FACING_LEFT; + } + else if (dx > 0) + { + this.facing = CONST.FACING_RIGHT; + } + + if (dy < 0) + { + this.facing = CONST.FACING_UP; + } + else if (dy > 0) + { + this.facing = CONST.FACING_DOWN; + } + + if (this.allowRotation) + { + this.gameObject.angle += this.deltaZ(); + } + + this._tx = dx; + this._ty = dy; + }, + + /** + * Sets a custom collision boundary rectangle. Use if you want to have a custom + * boundary instead of the world boundaries. + * + * @method Phaser.Physics.Arcade.Body#setBoundsRectangle + * @since 3.20 + * + * @param {?Phaser.Geom.Rectangle} [bounds] - The new boundary rectangle. Pass `null` to use the World bounds. + * + * @return {this} This Body object. + */ + setBoundsRectangle: function (bounds) + { + this.customBoundsRectangle = (!bounds) ? this.world.bounds : bounds; + + return this; + }, + + /** + * Checks for collisions between this Body and the world boundary and separates them. + * + * @method Phaser.Physics.Arcade.Body#checkWorldBounds + * @since 3.0.0 + * + * @return {boolean} True if this Body is colliding with the world boundary. + */ + checkWorldBounds: function () + { + var pos = this.position; + var bounds = this.customBoundsRectangle; + var check = this.world.checkCollision; + + var bx = (this.worldBounce) ? -this.worldBounce.x : -this.bounce.x; + var by = (this.worldBounce) ? -this.worldBounce.y : -this.bounce.y; + + var wasSet = false; + + if (pos.x < bounds.x && check.left) + { + pos.x = bounds.x; + this.velocity.x *= bx; + this.blocked.left = true; + wasSet = true; + } + else if (this.right > bounds.right && check.right) + { + pos.x = bounds.right - this.width; + this.velocity.x *= bx; + this.blocked.right = true; + wasSet = true; + } + + if (pos.y < bounds.y && check.up) + { + pos.y = bounds.y; + this.velocity.y *= by; + this.blocked.up = true; + wasSet = true; + } + else if (this.bottom > bounds.bottom && check.down) + { + pos.y = bounds.bottom - this.height; + this.velocity.y *= by; + this.blocked.down = true; + wasSet = true; + } + + if (wasSet) + { + this.blocked.none = false; + this.updateCenter(); + } + + return wasSet; + }, + + /** + * Sets the offset of the Body's position from its Game Object's position. + * The Body's `position` isn't changed until the next `preUpdate`. + * + * @method Phaser.Physics.Arcade.Body#setOffset + * @since 3.0.0 + * + * @param {number} x - The horizontal offset, in source pixels. + * @param {number} [y=x] - The vertical offset, in source pixels. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setOffset: function (x, y) + { + if (y === undefined) { y = x; } + + this.offset.set(x, y); + + return this; + }, + + /** + * Sizes and positions this Body, as a rectangle. + * Modifies the Body `offset` if `center` is true (the default). + * Resets the width and height to match current frame, if no width and height provided and a frame is found. + * + * @method Phaser.Physics.Arcade.Body#setSize + * @since 3.0.0 + * + * @param {number} [width] - The width of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. + * @param {number} [height] - The height of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. + * @param {boolean} [center=true] - Modify the Body's `offset`, placing the Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setSize: function (width, height, center) + { + if (center === undefined) { center = true; } + + var gameObject = this.gameObject; + + if (!width && gameObject.frame) + { + width = gameObject.frame.realWidth; + } + + if (!height && gameObject.frame) + { + height = gameObject.frame.realHeight; + } + + this.sourceWidth = width; + this.sourceHeight = height; + + this.width = this.sourceWidth * this._sx; + this.height = this.sourceHeight * this._sy; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.updateCenter(); + + if (center && gameObject.getCenter) + { + var ox = (gameObject.width - width) / 2; + var oy = (gameObject.height - height) / 2; + + this.offset.set(ox, oy); + } + + this.isCircle = false; + this.radius = 0; + + return this; + }, + + /** + * Sizes and positions this Body, as a circle. + * + * @method Phaser.Physics.Arcade.Body#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the Body, in source pixels. + * @param {number} [offsetX] - The horizontal offset of the Body from its Game Object, in source pixels. + * @param {number} [offsetY] - The vertical offset of the Body from its Game Object, in source pixels. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setCircle: function (radius, offsetX, offsetY) + { + if (offsetX === undefined) { offsetX = this.offset.x; } + if (offsetY === undefined) { offsetY = this.offset.y; } + + if (radius > 0) + { + this.isCircle = true; + this.radius = radius; + + this.sourceWidth = radius * 2; + this.sourceHeight = radius * 2; + + this.width = this.sourceWidth * this._sx; + this.height = this.sourceHeight * this._sy; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.offset.set(offsetX, offsetY); + + this.updateCenter(); + } + else + { + this.isCircle = false; + } + + return this; + }, + + /** + * Sets this Body's parent Game Object to the given coordinates and resets this Body at the new coordinates. + * If the Body had any velocity or acceleration it is lost as a result of calling this. + * + * @method Phaser.Physics.Arcade.Body#reset + * @since 3.0.0 + * + * @param {number} x - The horizontal position to place the Game Object. + * @param {number} y - The vertical position to place the Game Object. + */ + reset: function (x, y) + { + this.stop(); + + var gameObject = this.gameObject; + + gameObject.setPosition(x, y); + + if (gameObject.getTopLeft) + { + gameObject.getTopLeft(this.position); + } + else + { + this.position.set(x, y); + } + + this.prev.copy(this.position); + this.prevFrame.copy(this.position); + + this.rotation = gameObject.angle; + this.preRotation = gameObject.angle; + + this.updateBounds(); + this.updateCenter(); + this.resetFlags(true); + }, + + /** + * Sets acceleration, velocity, and speed to zero. + * + * @method Phaser.Physics.Arcade.Body#stop + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + stop: function () + { + this.velocity.set(0); + this.acceleration.set(0); + this.speed = 0; + this.angularVelocity = 0; + this.angularAcceleration = 0; + + return this; + }, + + /** + * Copies the coordinates of this Body's edges into an object. + * + * @method Phaser.Physics.Arcade.Body#getBounds + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into. + * + * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}. + */ + getBounds: function (obj) + { + obj.x = this.x; + obj.y = this.y; + obj.right = this.right; + obj.bottom = this.bottom; + + return obj; + }, + + /** + * Tests if the coordinates are within this Body. + * + * @method Phaser.Physics.Arcade.Body#hitTest + * @since 3.0.0 + * + * @param {number} x - The horizontal coordinate. + * @param {number} y - The vertical coordinate. + * + * @return {boolean} True if (x, y) is within this Body. + */ + hitTest: function (x, y) + { + if (!this.isCircle) + { + return RectangleContains(this, x, y); + } + + // Check if x/y are within the bounds first + if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) + { + var dx = (this.center.x - x) * (this.center.x - x); + var dy = (this.center.y - y) * (this.center.y - y); + + return (dx + dy) <= (this.radius * this.radius); + } + + return false; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving down. + * + * @method Phaser.Physics.Arcade.Body#onFloor + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onFloor: function () + { + return this.blocked.down; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving up. + * + * @method Phaser.Physics.Arcade.Body#onCeiling + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onCeiling: function () + { + return this.blocked.up; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving left or right. + * + * @method Phaser.Physics.Arcade.Body#onWall + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onWall: function () + { + return (this.blocked.left || this.blocked.right); + }, + + /** + * The absolute (non-negative) change in this Body's horizontal position from the previous step. + * + * @method Phaser.Physics.Arcade.Body#deltaAbsX + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaAbsX: function () + { + return (this._dx > 0) ? this._dx : -this._dx; + }, + + /** + * The absolute (non-negative) change in this Body's vertical position from the previous step. + * + * @method Phaser.Physics.Arcade.Body#deltaAbsY + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaAbsY: function () + { + return (this._dy > 0) ? this._dy : -this._dy; + }, + + /** + * The change in this Body's horizontal position from the previous step. + * This value is set during the Body's update phase. + * + * As a Body can update multiple times per step this may not hold the final + * delta value for the Body. In this case, please see the `deltaXFinal` method. + * + * @method Phaser.Physics.Arcade.Body#deltaX + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaX: function () + { + return this._dx; + }, + + /** + * The change in this Body's vertical position from the previous step. + * This value is set during the Body's update phase. + * + * As a Body can update multiple times per step this may not hold the final + * delta value for the Body. In this case, please see the `deltaYFinal` method. + * + * @method Phaser.Physics.Arcade.Body#deltaY + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaY: function () + { + return this._dy; + }, + + /** + * The change in this Body's horizontal position from the previous game update. + * + * This value is set during the `postUpdate` phase and takes into account the + * `deltaMax` and final position of the Body. + * + * Because this value is not calculated until `postUpdate`, you must listen for it + * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will + * not be calculated by that point. If you _do_ use these values in `update` they + * will represent the delta from the _previous_ game frame. + * + * @method Phaser.Physics.Arcade.Body#deltaXFinal + * @since 3.22.0 + * + * @return {number} The final delta x value. + */ + deltaXFinal: function () + { + return this._tx; + }, + + /** + * The change in this Body's vertical position from the previous game update. + * + * This value is set during the `postUpdate` phase and takes into account the + * `deltaMax` and final position of the Body. + * + * Because this value is not calculated until `postUpdate`, you must listen for it + * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will + * not be calculated by that point. If you _do_ use these values in `update` they + * will represent the delta from the _previous_ game frame. + * + * @method Phaser.Physics.Arcade.Body#deltaYFinal + * @since 3.22.0 + * + * @return {number} The final delta y value. + */ + deltaYFinal: function () + { + return this._ty; + }, + + /** + * The change in this Body's rotation from the previous step, in degrees. + * + * @method Phaser.Physics.Arcade.Body#deltaZ + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaZ: function () + { + return this.rotation - this.preRotation; + }, + + /** + * Disables this Body and marks it for deletion by the simulation. + * + * @method Phaser.Physics.Arcade.Body#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enable = false; + + if (this.world) + { + this.world.pendingDestroy.set(this); + } + }, + + /** + * Draws this Body and its velocity, if enabled. + * + * @method Phaser.Physics.Arcade.Body#drawDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to draw on. + */ + drawDebug: function (graphic) + { + var pos = this.position; + + var x = pos.x + this.halfWidth; + var y = pos.y + this.halfHeight; + + if (this.debugShowBody) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor); + + if (this.isCircle) + { + graphic.strokeCircle(x, y, this.width / 2); + } + else + { + // Only draw the sides where checkCollision is true, similar to debugger in layer + if (this.checkCollision.up) + { + graphic.lineBetween(pos.x, pos.y, pos.x + this.width, pos.y); + } + + if (this.checkCollision.right) + { + graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); + } + + if (this.checkCollision.down) + { + graphic.lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height); + } + + if (this.checkCollision.left) + { + graphic.lineBetween(pos.x, pos.y, pos.x, pos.y + this.height); + } + } + } + + if (this.debugShowVelocity) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.world.defaults.velocityDebugColor, 1); + graphic.lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2); + } + }, + + /** + * Whether this Body will be drawn to the debug display. + * + * @method Phaser.Physics.Arcade.Body#willDrawDebug + * @since 3.0.0 + * + * @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled. + */ + willDrawDebug: function () + { + return (this.debugShowBody || this.debugShowVelocity); + }, + + /** + * Sets whether this Body collides with the world boundary. + * + * Optionally also sets the World Bounce and `onWorldBounds` values. + * + * @method Phaser.Physics.Arcade.Body#setCollideWorldBounds + * @since 3.0.0 + * + * @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`. + * @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value. + * @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value. + * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setCollideWorldBounds: function (value, bounceX, bounceY, onWorldBounds) + { + if (value === undefined) { value = true; } + + this.collideWorldBounds = value; + + var setBounceX = (bounceX !== undefined); + var setBounceY = (bounceY !== undefined); + + if (setBounceX || setBounceY) + { + if (!this.worldBounce) + { + this.worldBounce = new Vector2(); + } + + if (setBounceX) + { + this.worldBounce.x = bounceX; + } + + if (setBounceY) + { + this.worldBounce.y = bounceY; + } + } + + if (onWorldBounds !== undefined) + { + this.onWorldBounds = onWorldBounds; + } + + return this; + }, + + /** + * Sets the Body's velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocity + * @since 3.0.0 + * + * @param {number} x - The horizontal velocity, in pixels per second. + * @param {number} [y=x] - The vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocity: function (x, y) + { + this.velocity.set(x, y); + + x = this.velocity.x; + y = this.velocity.y; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's horizontal velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocityX + * @since 3.0.0 + * + * @param {number} value - The velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocityX: function (value) + { + this.velocity.x = value; + + var x = value; + var y = this.velocity.y; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's vertical velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocityY + * @since 3.0.0 + * + * @param {number} value - The velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocityY: function (value) + { + this.velocity.y = value; + + var x = this.velocity.x; + var y = value; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's maximum velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocity + * @since 3.10.0 + * + * @param {number} x - The horizontal velocity, in pixels per second. + * @param {number} [y=x] - The vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocity: function (x, y) + { + this.maxVelocity.set(x, y); + + return this; + }, + + /** + * Sets the Body's maximum horizontal velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocityX + * @since 3.50.0 + * + * @param {number} value - The maximum horizontal velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocityX: function (value) + { + this.maxVelocity.x = value; + + return this; + }, + + /** + * Sets the Body's maximum vertical velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocityY + * @since 3.50.0 + * + * @param {number} value - The maximum vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocityY: function (value) + { + this.maxVelocity.y = value; + + return this; + }, + + /** + * Sets the maximum speed the Body can move. + * + * @method Phaser.Physics.Arcade.Body#setMaxSpeed + * @since 3.16.0 + * + * @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxSpeed: function (value) + { + this.maxSpeed = value; + + return this; + }, + + /** + * Sets the Body's bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounce + * @since 3.0.0 + * + * @param {number} x - The horizontal bounce, relative to 1. + * @param {number} y - The vertical bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounce: function (x, y) + { + this.bounce.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounceX + * @since 3.0.0 + * + * @param {number} value - The bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounceX: function (value) + { + this.bounce.x = value; + + return this; + }, + + /** + * Sets the Body's vertical bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounceY + * @since 3.0.0 + * + * @param {number} value - The bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounceY: function (value) + { + this.bounce.y = value; + + return this; + }, + + /** + * Sets the Body's acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAcceleration + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAcceleration: function (x, y) + { + this.acceleration.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAccelerationX + * @since 3.0.0 + * + * @param {number} value - The acceleration, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAccelerationX: function (value) + { + this.acceleration.x = value; + + return this; + }, + + /** + * Sets the Body's vertical acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAccelerationY + * @since 3.0.0 + * + * @param {number} value - The acceleration, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAccelerationY: function (value) + { + this.acceleration.y = value; + + return this; + }, + + /** + * Enables or disables drag. + * + * @method Phaser.Physics.Arcade.Body#setAllowDrag + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowDrag + * + * @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowDrag: function (value) + { + if (value === undefined) { value = true; } + + this.allowDrag = value; + + return this; + }, + + /** + * Enables or disables gravity's effect on this Body. + * + * @method Phaser.Physics.Arcade.Body#setAllowGravity + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowGravity + * + * @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowGravity: function (value) + { + if (value === undefined) { value = true; } + + this.allowGravity = value; + + return this; + }, + + /** + * Enables or disables rotation. + * + * @method Phaser.Physics.Arcade.Body#setAllowRotation + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowRotation + * + * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowRotation: function (value) + { + if (value === undefined) { value = true; } + + this.allowRotation = value; + + return this; + }, + + /** + * Sets the Body's drag. + * + * @method Phaser.Physics.Arcade.Body#setDrag + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDrag: function (x, y) + { + this.drag.set(x, y); + + return this; + }, + + /** + * If this Body is using `drag` for deceleration this property controls how the drag is applied. + * If set to `true` drag will use a damping effect rather than a linear approach. If you are + * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in + * the game Asteroids) then you will get a far smoother and more visually correct deceleration + * by using damping, avoiding the axis-drift that is prone with linear deceleration. + * + * If you enable this property then you should use far smaller `drag` values than with linear, as + * they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow + * deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately. + * + * @method Phaser.Physics.Arcade.Body#setDamping + * @since 3.50.0 + * + * @param {boolean} value - `true` to use damping, or `false` to use drag. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDamping: function (value) + { + this.useDamping = value; + + return this; + }, + + /** + * Sets the Body's horizontal drag. + * + * @method Phaser.Physics.Arcade.Body#setDragX + * @since 3.0.0 + * + * @param {number} value - The drag, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDragX: function (value) + { + this.drag.x = value; + + return this; + }, + + /** + * Sets the Body's vertical drag. + * + * @method Phaser.Physics.Arcade.Body#setDragY + * @since 3.0.0 + * + * @param {number} value - The drag, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDragY: function (value) + { + this.drag.y = value; + + return this; + }, + + /** + * Sets the Body's gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravity + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravity: function (x, y) + { + this.gravity.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravityX + * @since 3.0.0 + * + * @param {number} value - The gravity, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravityX: function (value) + { + this.gravity.x = value; + + return this; + }, + + /** + * Sets the Body's vertical gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravityY + * @since 3.0.0 + * + * @param {number} value - The gravity, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravityY: function (value) + { + this.gravity.y = value; + + return this; + }, + + /** + * Sets the Body's friction. + * + * @method Phaser.Physics.Arcade.Body#setFriction + * @since 3.0.0 + * + * @param {number} x - The horizontal component, relative to 1. + * @param {number} y - The vertical component, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFriction: function (x, y) + { + this.friction.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal friction. + * + * @method Phaser.Physics.Arcade.Body#setFrictionX + * @since 3.0.0 + * + * @param {number} value - The friction value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFrictionX: function (value) + { + this.friction.x = value; + + return this; + }, + + /** + * Sets the Body's vertical friction. + * + * @method Phaser.Physics.Arcade.Body#setFrictionY + * @since 3.0.0 + * + * @param {number} value - The friction value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFrictionY: function (value) + { + this.friction.y = value; + + return this; + }, + + /** + * Sets the Body's angular velocity. + * + * @method Phaser.Physics.Arcade.Body#setAngularVelocity + * @since 3.0.0 + * + * @param {number} value - The velocity, in degrees per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularVelocity: function (value) + { + this.angularVelocity = value; + + return this; + }, + + /** + * Sets the Body's angular acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAngularAcceleration + * @since 3.0.0 + * + * @param {number} value - The acceleration, in degrees per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularAcceleration: function (value) + { + this.angularAcceleration = value; + + return this; + }, + + /** + * Sets the Body's angular drag. + * + * @method Phaser.Physics.Arcade.Body#setAngularDrag + * @since 3.0.0 + * + * @param {number} value - The drag, in degrees per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularDrag: function (value) + { + this.angularDrag = value; + + return this; + }, + + /** + * Sets the Body's mass. + * + * @method Phaser.Physics.Arcade.Body#setMass + * @since 3.0.0 + * + * @param {number} value - The mass value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMass: function (value) + { + this.mass = value; + + return this; + }, + + /** + * Sets the Body's `immovable` property. + * + * @method Phaser.Physics.Arcade.Body#setImmovable + * @since 3.0.0 + * + * @param {boolean} [value=true] - The value to assign to `immovable`. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setImmovable: function (value) + { + if (value === undefined) { value = true; } + + this.immovable = value; + + return this; + }, + + /** + * Sets the Body's `enable` property. + * + * @method Phaser.Physics.Arcade.Body#setEnable + * @since 3.15.0 + * + * @param {boolean} [value=true] - The value to assign to `enable`. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setEnable: function (value) + { + if (value === undefined) { value = true; } + + this.enable = value; + + return this; + }, + + /** + * This is an internal handler, called by the `ProcessX` function as part + * of the collision step. You should almost never call this directly. + * + * @method Phaser.Physics.Arcade.Body#processX + * @since 3.50.0 + * + * @param {number} x - The amount to add to the Body position. + * @param {number} [vx] - The amount to add to the Body velocity. + * @param {boolean} [left] - Set the blocked.left value? + * @param {boolean} [right] - Set the blocked.right value? + */ + processX: function (x, vx, left, right) + { + this.x += x; + + this.updateCenter(); + + if (vx !== null) + { + this.velocity.x = vx; + } + + var blocked = this.blocked; + + if (left) + { + blocked.left = true; + } + + if (right) + { + blocked.right = true; + } + }, + + /** + * This is an internal handler, called by the `ProcessY` function as part + * of the collision step. You should almost never call this directly. + * + * @method Phaser.Physics.Arcade.Body#processY + * @since 3.50.0 + * + * @param {number} y - The amount to add to the Body position. + * @param {number} [vy] - The amount to add to the Body velocity. + * @param {boolean} [up] - Set the blocked.up value? + * @param {boolean} [down] - Set the blocked.down value? + */ + processY: function (y, vy, up, down) + { + this.y += y; + + this.updateCenter(); + + if (vy !== null) + { + this.velocity.y = vy; + } + + var blocked = this.blocked; + + if (up) + { + blocked.up = true; + } + + if (down) + { + blocked.down = true; + } + }, + + /** + * The Bodys horizontal position (left edge). + * + * @name Phaser.Physics.Arcade.Body#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.position.x = value; + } + + }, + + /** + * The Bodys vertical position (top edge). + * + * @name Phaser.Physics.Arcade.Body#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.position.y = value; + } + + }, + + /** + * The left edge of the Body. Identical to x. + * + * @name Phaser.Physics.Arcade.Body#left + * @type {number} + * @readonly + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.position.x; + } + + }, + + /** + * The right edge of the Body. + * + * @name Phaser.Physics.Arcade.Body#right + * @type {number} + * @readonly + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.position.x + this.width; + } + + }, + + /** + * The top edge of the Body. Identical to y. + * + * @name Phaser.Physics.Arcade.Body#top + * @type {number} + * @readonly + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.position.y; + } + + }, + + /** + * The bottom edge of this Body. + * + * @name Phaser.Physics.Arcade.Body#bottom + * @type {number} + * @readonly + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.position.y + this.height; + } + + } + +}); + +module.exports = Body; + + +/***/ }), +/* 522 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects + * every step. If a collision, or overlap, occurs it will invoke the given callbacks. + * + * @class Collider + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade physics World that will manage the collisions. + * @param {boolean} overlapOnly - Whether to check for collisions or overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + */ +var Collider = new Class({ + + initialize: + + function Collider (world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) + { + /** + * The world in which the bodies will collide. + * + * @name Phaser.Physics.Arcade.Collider#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The name of the collider (unused by Phaser). + * + * @name Phaser.Physics.Arcade.Collider#name + * @type {string} + * @since 3.1.0 + */ + this.name = ''; + + /** + * Whether the collider is active. + * + * @name Phaser.Physics.Arcade.Collider#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Whether to check for collisions or overlaps. + * + * @name Phaser.Physics.Arcade.Collider#overlapOnly + * @type {boolean} + * @since 3.0.0 + */ + this.overlapOnly = overlapOnly; + + /** + * The first object to check for collision. + * + * @name Phaser.Physics.Arcade.Collider#object1 + * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} + * @since 3.0.0 + */ + this.object1 = object1; + + /** + * The second object to check for collision. + * + * @name Phaser.Physics.Arcade.Collider#object2 + * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} + * @since 3.0.0 + */ + this.object2 = object2; + + /** + * The callback to invoke when the two objects collide. + * + * @name Phaser.Physics.Arcade.Collider#collideCallback + * @type {ArcadePhysicsCallback} + * @since 3.0.0 + */ + this.collideCallback = collideCallback; + + /** + * If a processCallback exists it must return true or collision checking will be skipped. + * + * @name Phaser.Physics.Arcade.Collider#processCallback + * @type {ArcadePhysicsCallback} + * @since 3.0.0 + */ + this.processCallback = processCallback; + + /** + * The context the collideCallback and processCallback will run in. + * + * @name Phaser.Physics.Arcade.Collider#callbackContext + * @type {object} + * @since 3.0.0 + */ + this.callbackContext = callbackContext; + }, + + /** + * A name for the Collider. + * + * Phaser does not use this value, it's for your own reference. + * + * @method Phaser.Physics.Arcade.Collider#setName + * @since 3.1.0 + * + * @param {string} name - The name to assign to the Collider. + * + * @return {Phaser.Physics.Arcade.Collider} This Collider instance. + */ + setName: function (name) + { + this.name = name; + + return this; + }, + + /** + * Called by World as part of its step processing, initial operation of collision checking. + * + * @method Phaser.Physics.Arcade.Collider#update + * @since 3.0.0 + */ + update: function () + { + this.world.collideObjects( + this.object1, + this.object2, + this.collideCallback, + this.processCallback, + this.callbackContext, + this.overlapOnly + ); + }, + + /** + * Removes Collider from World and disposes of its resources. + * + * @method Phaser.Physics.Arcade.Collider#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.world.removeCollider(this); + + this.active = false; + + this.world = null; + + this.object1 = null; + this.object2 = null; + + this.collideCallback = null; + this.processCallback = null; + this.callbackContext = null; + } + +}); + +module.exports = Collider; + + +/***/ }), +/* 523 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(26); +var Vector2 = __webpack_require__(3); + +var pointStart = new Vector2(); +var pointEnd = new Vector2(); + +/** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * @function Phaser.Tilemaps.Components.GetTilesWithinWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} filteringOptions - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when factoring in which tiles to return. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. + */ +var GetTilesWithinWorldXY = function (worldX, worldY, width, height, filteringOptions, camera, layer) +{ + var worldToTileXY = layer.tilemapLayer.tilemap._convert.WorldToTileXY; + + // Top left corner of the rect, rounded down to include partial tiles + worldToTileXY(worldX, worldY, true, pointStart, camera, layer); + + var xStart = pointStart.x; + var yStart = pointStart.y; + + // Bottom right corner of the rect, rounded up to include partial tiles + worldToTileXY(worldX + width, worldY + height, false, pointEnd, camera, layer); + + var xEnd = Math.ceil(pointEnd.x); + var yEnd = Math.ceil(pointEnd.y); + + return GetTilesWithin(xStart, yStart, xEnd - xStart, yEnd - yStart, filteringOptions, layer); +}; + +module.exports = GetTilesWithinWorldXY; + + +/***/ }), +/* 524 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A function to process the collision callbacks between a single tile and an Arcade Physics enabled Game Object. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileCallbacks + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.Tile} tile - The Tile to process. + * @param {Phaser.GameObjects.Sprite} sprite - The Game Object to process with the Tile. + * + * @return {boolean} The result of the callback, `true` for further processing, or `false` to skip this pair. + */ +var ProcessTileCallbacks = function (tile, sprite) +{ + // Tile callbacks take priority over layer level callbacks + if (tile.collisionCallback) + { + return !tile.collisionCallback.call(tile.collisionCallbackContext, sprite, tile); + } + else if (tile.layer.callbacks[tile.index]) + { + return !tile.layer.callbacks[tile.index].callback.call( + tile.layer.callbacks[tile.index].callbackContext, sprite, tile + ); + } + + return true; +}; + +module.exports = ProcessTileCallbacks; + + +/***/ }), +/* 525 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Vladimir Agafonkin + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var quickselect = __webpack_require__(430); + +/** + * @classdesc + * RBush is a high-performance JavaScript library for 2D spatial indexing of points and rectangles. + * It's based on an optimized R-tree data structure with bulk insertion support. + * + * Spatial index is a special data structure for points and rectangles that allows you to perform queries like + * "all items within this bounding box" very efficiently (e.g. hundreds of times faster than looping over all items). + * + * This version of RBush uses a fixed min/max accessor structure of `[ '.left', '.top', '.right', '.bottom' ]`. + * This is to avoid the eval like function creation that the original library used, which caused CSP policy violations. + * + * rbush is forked from https://github.com/mourner/rbush by Vladimir Agafonkin + * + * @class RTree + * @memberof Phaser.Structs + * @constructor + * @since 3.0.0 + */ + +function rbush (maxEntries) +{ + var format = [ '.left', '.top', '.right', '.bottom' ]; + + if (!(this instanceof rbush)) return new rbush(maxEntries, format); + + // max entries in a node is 9 by default; min node fill is 40% for best performance + this._maxEntries = Math.max(4, maxEntries || 9); + this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); + + this.clear(); +} + +rbush.prototype = { + + all: function () + { + return this._all(this.data, []); + }, + + search: function (bbox) + { + var node = this.data, + result = [], + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return result; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf) result.push(child); + else if (contains(bbox, childBBox)) this._all(child, result); + else nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return result; + }, + + collides: function (bbox) + { + var node = this.data, + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return false; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf || contains(bbox, childBBox)) return true; + nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return false; + }, + + load: function (data) + { + if (!(data && data.length)) return this; + + if (data.length < this._minEntries) { + for (var i = 0, len = data.length; i < len; i++) { + this.insert(data[i]); + } + return this; + } + + // recursively build the tree with the given data from scratch using OMT algorithm + var node = this._build(data.slice(), 0, data.length - 1, 0); + + if (!this.data.children.length) { + // save as is if tree is empty + this.data = node; + + } else if (this.data.height === node.height) { + // split root if trees have the same height + this._splitRoot(this.data, node); + + } else { + if (this.data.height < node.height) { + // swap trees if inserted one is bigger + var tmpNode = this.data; + this.data = node; + node = tmpNode; + } + + // insert the small tree into the large tree at appropriate level + this._insert(node, this.data.height - node.height - 1, true); + } + + return this; + }, + + insert: function (item) + { + if (item) this._insert(item, this.data.height - 1); + return this; + }, + + clear: function () + { + this.data = createNode([]); + return this; + }, + + remove: function (item, equalsFn) + { + if (!item) return this; + + var node = this.data, + bbox = this.toBBox(item), + path = [], + indexes = [], + i, parent, index, goingUp; + + // depth-first iterative tree traversal + while (node || path.length) { + + if (!node) { // go up + node = path.pop(); + parent = path[path.length - 1]; + i = indexes.pop(); + goingUp = true; + } + + if (node.leaf) { // check current node + index = findItem(item, node.children, equalsFn); + + if (index !== -1) { + // item found, remove the item and condense tree upwards + node.children.splice(index, 1); + path.push(node); + this._condense(path); + return this; + } + } + + if (!goingUp && !node.leaf && contains(node, bbox)) { // go down + path.push(node); + indexes.push(i); + i = 0; + parent = node; + node = node.children[0]; + + } else if (parent) { // go right + i++; + node = parent.children[i]; + goingUp = false; + + } else node = null; // nothing found + } + + return this; + }, + + toBBox: function (item) { return item; }, + + compareMinX: compareNodeMinX, + compareMinY: compareNodeMinY, + + toJSON: function () { return this.data; }, + + fromJSON: function (data) + { + this.data = data; + return this; + }, + + _all: function (node, result) + { + var nodesToSearch = []; + while (node) { + if (node.leaf) result.push.apply(result, node.children); + else nodesToSearch.push.apply(nodesToSearch, node.children); + + node = nodesToSearch.pop(); + } + return result; + }, + + _build: function (items, left, right, height) + { + var N = right - left + 1, + M = this._maxEntries, + node; + + if (N <= M) { + // reached leaf level; return leaf + node = createNode(items.slice(left, right + 1)); + calcBBox(node, this.toBBox); + return node; + } + + if (!height) { + // target height of the bulk-loaded tree + height = Math.ceil(Math.log(N) / Math.log(M)); + + // target number of root entries to maximize storage utilization + M = Math.ceil(N / Math.pow(M, height - 1)); + } + + node = createNode([]); + node.leaf = false; + node.height = height; + + // split the items into M mostly square tiles + + var N2 = Math.ceil(N / M), + N1 = N2 * Math.ceil(Math.sqrt(M)), + i, j, right2, right3; + + multiSelect(items, left, right, N1, this.compareMinX); + + for (i = left; i <= right; i += N1) { + + right2 = Math.min(i + N1 - 1, right); + + multiSelect(items, i, right2, N2, this.compareMinY); + + for (j = i; j <= right2; j += N2) { + + right3 = Math.min(j + N2 - 1, right2); + + // pack each entry recursively + node.children.push(this._build(items, j, right3, height - 1)); + } + } + + calcBBox(node, this.toBBox); + + return node; + }, + + _chooseSubtree: function (bbox, node, level, path) + { + var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; + + while (true) { + path.push(node); + + if (node.leaf || path.length - 1 === level) break; + + minArea = minEnlargement = Infinity; + + for (i = 0, len = node.children.length; i < len; i++) { + child = node.children[i]; + area = bboxArea(child); + enlargement = enlargedArea(bbox, child) - area; + + // choose entry with the least area enlargement + if (enlargement < minEnlargement) { + minEnlargement = enlargement; + minArea = area < minArea ? area : minArea; + targetNode = child; + + } else if (enlargement === minEnlargement) { + // otherwise choose one with the smallest area + if (area < minArea) { + minArea = area; + targetNode = child; + } + } + } + + node = targetNode || node.children[0]; + } + + return node; + }, + + _insert: function (item, level, isNode) + { + var toBBox = this.toBBox, + bbox = isNode ? item : toBBox(item), + insertPath = []; + + // find the best node for accommodating the item, saving all nodes along the path too + var node = this._chooseSubtree(bbox, this.data, level, insertPath); + + // put the item into the node + node.children.push(item); + extend(node, bbox); + + // split on node overflow; propagate upwards if necessary + while (level >= 0) { + if (insertPath[level].children.length > this._maxEntries) { + this._split(insertPath, level); + level--; + } else break; + } + + // adjust bboxes along the insertion path + this._adjustParentBBoxes(bbox, insertPath, level); + }, + + // split overflowed node into two + _split: function (insertPath, level) + { + var node = insertPath[level], + M = node.children.length, + m = this._minEntries; + + this._chooseSplitAxis(node, m, M); + + var splitIndex = this._chooseSplitIndex(node, m, M); + + var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); + newNode.height = node.height; + newNode.leaf = node.leaf; + + calcBBox(node, this.toBBox); + calcBBox(newNode, this.toBBox); + + if (level) insertPath[level - 1].children.push(newNode); + else this._splitRoot(node, newNode); + }, + + _splitRoot: function (node, newNode) + { + // split root node + this.data = createNode([node, newNode]); + this.data.height = node.height + 1; + this.data.leaf = false; + calcBBox(this.data, this.toBBox); + }, + + _chooseSplitIndex: function (node, m, M) + { + var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; + + minOverlap = minArea = Infinity; + + for (i = m; i <= M - m; i++) { + bbox1 = distBBox(node, 0, i, this.toBBox); + bbox2 = distBBox(node, i, M, this.toBBox); + + overlap = intersectionArea(bbox1, bbox2); + area = bboxArea(bbox1) + bboxArea(bbox2); + + // choose distribution with minimum overlap + if (overlap < minOverlap) { + minOverlap = overlap; + index = i; + + minArea = area < minArea ? area : minArea; + + } else if (overlap === minOverlap) { + // otherwise choose distribution with minimum area + if (area < minArea) { + minArea = area; + index = i; + } + } + } + + return index; + }, + + // sorts node children by the best axis for split + _chooseSplitAxis: function (node, m, M) + { + var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, + compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, + xMargin = this._allDistMargin(node, m, M, compareMinX), + yMargin = this._allDistMargin(node, m, M, compareMinY); + + // if total distributions margin value is minimal for x, sort by minX, + // otherwise it's already sorted by minY + if (xMargin < yMargin) node.children.sort(compareMinX); + }, + + // total margin of all possible split distributions where each node is at least m full + _allDistMargin: function (node, m, M, compare) + { + node.children.sort(compare); + + var toBBox = this.toBBox, + leftBBox = distBBox(node, 0, m, toBBox), + rightBBox = distBBox(node, M - m, M, toBBox), + margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), + i, child; + + for (i = m; i < M - m; i++) { + child = node.children[i]; + extend(leftBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(leftBBox); + } + + for (i = M - m - 1; i >= m; i--) { + child = node.children[i]; + extend(rightBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(rightBBox); + } + + return margin; + }, + + _adjustParentBBoxes: function (bbox, path, level) + { + // adjust bboxes along the given tree path + for (var i = level; i >= 0; i--) { + extend(path[i], bbox); + } + }, + + _condense: function (path) + { + // go through the path, removing empty nodes and updating bboxes + for (var i = path.length - 1, siblings; i >= 0; i--) { + if (path[i].children.length === 0) { + if (i > 0) { + siblings = path[i - 1].children; + siblings.splice(siblings.indexOf(path[i]), 1); + + } else this.clear(); + + } else calcBBox(path[i], this.toBBox); + } + }, + + compareMinX: function (a, b) + { + return a.left - b.left; + }, + + compareMinY: function (a, b) + { + return a.top - b.top; + }, + + toBBox: function (a) + { + return { + minX: a.left, + minY: a.top, + maxX: a.right, + maxY: a.bottom + }; + } +}; + +function findItem (item, items, equalsFn) +{ + if (!equalsFn) return items.indexOf(item); + + for (var i = 0; i < items.length; i++) { + if (equalsFn(item, items[i])) return i; + } + return -1; +} + +// calculate node's bbox from bboxes of its children +function calcBBox (node, toBBox) +{ + distBBox(node, 0, node.children.length, toBBox, node); +} + +// min bounding rectangle of node children from k to p-1 +function distBBox (node, k, p, toBBox, destNode) +{ + if (!destNode) destNode = createNode(null); + destNode.minX = Infinity; + destNode.minY = Infinity; + destNode.maxX = -Infinity; + destNode.maxY = -Infinity; + + for (var i = k, child; i < p; i++) { + child = node.children[i]; + extend(destNode, node.leaf ? toBBox(child) : child); + } + + return destNode; +} + +function extend (a, b) +{ + a.minX = Math.min(a.minX, b.minX); + a.minY = Math.min(a.minY, b.minY); + a.maxX = Math.max(a.maxX, b.maxX); + a.maxY = Math.max(a.maxY, b.maxY); + return a; +} + +function compareNodeMinX (a, b) { return a.minX - b.minX; } +function compareNodeMinY (a, b) { return a.minY - b.minY; } + +function bboxArea (a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } +function bboxMargin (a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } + +function enlargedArea (a, b) +{ + return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * + (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); +} + +function intersectionArea (a, b) +{ + var minX = Math.max(a.minX, b.minX), + minY = Math.max(a.minY, b.minY), + maxX = Math.min(a.maxX, b.maxX), + maxY = Math.min(a.maxY, b.maxY); + + return Math.max(0, maxX - minX) * + Math.max(0, maxY - minY); +} + +function contains (a, b) +{ + return a.minX <= b.minX && + a.minY <= b.minY && + b.maxX <= a.maxX && + b.maxY <= a.maxY; +} + +function intersects (a, b) +{ + return b.minX <= a.maxX && + b.minY <= a.maxY && + b.maxX >= a.minX && + b.maxY >= a.minY; +} + +function createNode (children) +{ + return { + children: children, + height: 1, + leaf: true, + minX: Infinity, + minY: Infinity, + maxX: -Infinity, + maxY: -Infinity + }; +} + +// sort an array so that items come in groups of n unsorted items, with groups sorted between each other; +// combines selection algorithm with binary divide & conquer approach + +function multiSelect (arr, left, right, n, compare) +{ + var stack = [left, right], + mid; + + while (stack.length) + { + right = stack.pop(); + left = stack.pop(); + + if (right - left <= n) continue; + + mid = left + Math.ceil((right - left) / n / 2) * n; + quickselect(arr, mid, left, right, compare); + + stack.push(left, mid, mid, right); + } +} + +module.exports = rbush; + +/***/ }), +/* 526 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TileCheckX = __webpack_require__(527); +var TileCheckY = __webpack_require__(529); +var TileIntersectsBody = __webpack_require__(245); + +/** + * The core separation function to separate a physics body and a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.SeparateTile + * @since 3.0.0 + * + * @param {number} i - The index of the tile within the map data. + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to collide against. + * @param {Phaser.Geom.Rectangle} tileWorldRect - A rectangle-like object defining the dimensions of the tile. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The tilemapLayer to collide against. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {boolean} `true` if the body was separated, otherwise `false`. + */ +var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) +{ + var tileLeft = tileWorldRect.left; + var tileTop = tileWorldRect.top; + var tileRight = tileWorldRect.right; + var tileBottom = tileWorldRect.bottom; + var faceHorizontal = tile.faceLeft || tile.faceRight; + var faceVertical = tile.faceTop || tile.faceBottom; + + if (!isLayer) + { + faceHorizontal = true; + faceVertical = true; + } + + // We don't need to go any further if this tile doesn't actually have any colliding faces. This + // could happen if the tile was meant to be collided with re: a callback, but otherwise isn't + // needed for separation. + if (!faceHorizontal && !faceVertical) + { + return false; + } + + var ox = 0; + var oy = 0; + var minX = 0; + var minY = 1; + + if (body.deltaAbsX() > body.deltaAbsY()) + { + // Moving faster horizontally, check X axis first + minX = -1; + } + else if (body.deltaAbsX() < body.deltaAbsY()) + { + // Moving faster vertically, check Y axis first + minY = -1; + } + + if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical) + { + // We only need do this if both axes have colliding faces AND we're moving in both + // directions + minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft)); + minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop)); + } + + if (minX < minY) + { + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); + + // That's horizontal done, check if we still intersects? If not then we can return now + if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } + + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + } + } + else + { + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + + // That's vertical done, check if we still intersects? If not then we can return now + if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } + + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); + } + } + + return (ox !== 0 || oy !== 0); +}; + +module.exports = SeparateTile; + + +/***/ }), +/* 527 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ProcessTileSeparationX = __webpack_require__(528); + +/** + * Check the body against the given tile on the X axis. + * Used internally by the SeparateTile function. + * + * @function Phaser.Physics.Arcade.Tilemap.TileCheckX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to check. + * @param {number} tileLeft - The left position of the tile within the tile world. + * @param {number} tileRight - The right position of the tile within the tile world. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {number} The amount of separation that occurred. + */ +var TileCheckX = function (body, tile, tileLeft, tileRight, tileBias, isLayer) +{ + var ox = 0; + + var faceLeft = tile.faceLeft; + var faceRight = tile.faceRight; + var collideLeft = tile.collideLeft; + var collideRight = tile.collideRight; + + if (!isLayer) + { + faceLeft = true; + faceRight = true; + collideLeft = true; + collideRight = true; + } + + if (body.deltaX() < 0 && collideRight && body.checkCollision.left) + { + // Body is moving LEFT + if (faceRight && body.x < tileRight) + { + ox = body.x - tileRight; + + if (ox < -tileBias) + { + ox = 0; + } + } + } + else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) + { + // Body is moving RIGHT + if (faceLeft && body.right > tileLeft) + { + ox = body.right - tileLeft; + + if (ox > tileBias) + { + ox = 0; + } + } + } + + if (ox !== 0) + { + if (body.customSeparateX) + { + body.overlapX = ox; + } + else + { + ProcessTileSeparationX(body, ox); + } + } + + return ox; +}; + +module.exports = TileCheckX; + + +/***/ }), +/* 528 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Internal function to process the separation of a physics body from a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} x - The x separation amount. + */ +var ProcessTileSeparationX = function (body, x) +{ + if (x < 0) + { + body.blocked.none = false; + body.blocked.left = true; + } + else if (x > 0) + { + body.blocked.none = false; + body.blocked.right = true; + } + + body.position.x -= x; + + if (body.bounce.x === 0) + { + body.velocity.x = 0; + } + else + { + body.velocity.x = -body.velocity.x * body.bounce.x; + } +}; + +module.exports = ProcessTileSeparationX; + + +/***/ }), +/* 529 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ProcessTileSeparationY = __webpack_require__(530); + +/** + * Check the body against the given tile on the Y axis. + * Used internally by the SeparateTile function. + * + * @function Phaser.Physics.Arcade.Tilemap.TileCheckY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to check. + * @param {number} tileTop - The top position of the tile within the tile world. + * @param {number} tileBottom - The bottom position of the tile within the tile world. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {number} The amount of separation that occurred. + */ +var TileCheckY = function (body, tile, tileTop, tileBottom, tileBias, isLayer) +{ + var oy = 0; + + var faceTop = tile.faceTop; + var faceBottom = tile.faceBottom; + var collideUp = tile.collideUp; + var collideDown = tile.collideDown; + + if (!isLayer) + { + faceTop = true; + faceBottom = true; + collideUp = true; + collideDown = true; + } + + if (body.deltaY() < 0 && collideDown && body.checkCollision.up) + { + // Body is moving UP + if (faceBottom && body.y < tileBottom) + { + oy = body.y - tileBottom; + + if (oy < -tileBias) + { + oy = 0; + } + } + } + else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) + { + // Body is moving DOWN + if (faceTop && body.bottom > tileTop) + { + oy = body.bottom - tileTop; + + if (oy > tileBias) + { + oy = 0; + } + } + } + + if (oy !== 0) + { + if (body.customSeparateY) + { + body.overlapY = oy; + } + else + { + ProcessTileSeparationY(body, oy); + } + } + + return oy; +}; + +module.exports = TileCheckY; + + +/***/ }), +/* 530 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Internal function to process the separation of a physics body from a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} y - The y separation amount. + */ +var ProcessTileSeparationY = function (body, y) +{ + if (y < 0) + { + body.blocked.none = false; + body.blocked.up = true; + } + else if (y > 0) + { + body.blocked.none = false; + body.blocked.down = true; + } + + body.position.y -= y; + + if (body.bounce.y === 0) + { + body.velocity.y = 0; + } + else + { + body.velocity.y = -body.velocity.y * body.bounce.y; + } +}; + +module.exports = ProcessTileSeparationY; + + +/***/ }), +/* 531 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetOverlapX = __webpack_require__(243); +var ProcessX = __webpack_require__(1383); + +/** + * Separates two overlapping bodies on the X-axis (horizontally). + * + * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. + * + * The bodies won't be separated if there is no horizontal overlap between them, if they are static, or if either one uses custom logic for its separation. + * + * @function Phaser.Physics.Arcade.SeparateX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. + * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. + * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateX = function (body1, body2, overlapOnly, bias) +{ + var overlap = GetOverlapX(body1, body2, overlapOnly, bias); + + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateX || body2.customSeparateX) + { + // return true if there was some overlap, otherwise false + return (overlap !== 0) || (body1.embedded && body2.embedded); + } + + var blockedState = ProcessX.Set(body1, body2, overlap); + + if (!body1Immovable && !body2Immovable) + { + if (blockedState > 0) + { + return true; + } + + return ProcessX.Check(); + } + else if (body1Immovable) + { + ProcessX.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessX.RunImmovableBody2(blockedState); + } + + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; + +module.exports = SeparateX; + + +/***/ }), +/* 532 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetOverlapY = __webpack_require__(244); +var ProcessY = __webpack_require__(1384); + +/** + * Separates two overlapping bodies on the Y-axis (vertically). + * + * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. + * + * The bodies won't be separated if there is no vertical overlap between them, if they are static, or if either one uses custom logic for its separation. + * + * @function Phaser.Physics.Arcade.SeparateY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. + * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. + * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateY = function (body1, body2, overlapOnly, bias) +{ + var overlap = GetOverlapY(body1, body2, overlapOnly, bias); + + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateY || body2.customSeparateY) + { + // return true if there was some overlap, otherwise false + return (overlap !== 0) || (body1.embedded && body2.embedded); + } + + var blockedState = ProcessY.Set(body1, body2, overlap); + + if (!body1Immovable && !body2Immovable) + { + if (blockedState > 0) + { + return true; + } + + return ProcessY.Check(); + } + else if (body1Immovable) + { + ProcessY.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessY.RunImmovableBody2(blockedState); + } + + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; + +module.exports = SeparateY; + + +/***/ }), +/* 533 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircleContains = __webpack_require__(63); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var RectangleContains = __webpack_require__(56); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A Static Arcade Physics Body. + * + * A Static Body never moves, and isn't automatically synchronized with its parent Game Object. + * That means if you make any change to the parent's origin, position, or scale after creating or adding the body, you'll need to update the Static Body manually. + * + * A Static Body can collide with other Bodies, but is never moved by collisions. + * + * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Body}. + * + * @class StaticBody + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Static Body belongs to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Static Body belongs to. + */ +var StaticBody = new Class({ + + initialize: + + function StaticBody (world, gameObject) + { + var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; + var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; + + /** + * The Arcade Physics simulation this Static Body belongs to. + * + * @name Phaser.Physics.Arcade.StaticBody#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The Game Object this Static Body belongs to. + * + * @name Phaser.Physics.Arcade.StaticBody#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = gameObject; + + /** + * Whether the Static Body's boundary is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.StaticBody#debugShowBody + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowBody = world.defaults.debugShowStaticBody; + + /** + * The color of this Static Body on the debug display. + * + * @name Phaser.Physics.Arcade.StaticBody#debugBodyColor + * @type {number} + * @since 3.0.0 + */ + this.debugBodyColor = world.defaults.staticBodyDebugColor; + + /** + * Whether this Static Body is updated by the physics simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#enable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enable = true; + + /** + * Whether this Static Body's boundary is circular (`true`) or rectangular (`false`). + * + * @name Phaser.Physics.Arcade.StaticBody#isCircle + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isCircle = false; + + /** + * If this Static Body is circular, this is the radius of the boundary, as set by {@link Phaser.Physics.Arcade.StaticBody#setCircle}, in pixels. + * Equal to `halfWidth`. + * + * @name Phaser.Physics.Arcade.StaticBody#radius + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.radius = 0; + + /** + * The offset set by {@link Phaser.Physics.Arcade.StaticBody#setCircle} or {@link Phaser.Physics.Arcade.StaticBody#setSize}. + * + * This doesn't affect the Static Body's position, because a Static Body does not follow its Game Object. + * + * @name Phaser.Physics.Arcade.StaticBody#offset + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.offset = new Vector2(); + + /** + * The position of this Static Body within the simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#position + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.position = new Vector2(gameObject.x - (width * gameObject.originX), gameObject.y - (height * gameObject.originY)); + + /** + * The width of the Static Body's boundary, in pixels. + * If the Static Body is circular, this is also the Static Body's diameter. + * + * @name Phaser.Physics.Arcade.StaticBody#width + * @type {number} + * @since 3.0.0 + */ + this.width = width; + + /** + * The height of the Static Body's boundary, in pixels. + * If the Static Body is circular, this is also the Static Body's diameter. + * + * @name Phaser.Physics.Arcade.StaticBody#height + * @type {number} + * @since 3.0.0 + */ + this.height = height; + + /** + * Half the Static Body's width, in pixels. + * If the Static Body is circular, this is also the Static Body's radius. + * + * @name Phaser.Physics.Arcade.StaticBody#halfWidth + * @type {number} + * @since 3.0.0 + */ + this.halfWidth = Math.abs(this.width / 2); + + /** + * Half the Static Body's height, in pixels. + * If the Static Body is circular, this is also the Static Body's radius. + * + * @name Phaser.Physics.Arcade.StaticBody#halfHeight + * @type {number} + * @since 3.0.0 + */ + this.halfHeight = Math.abs(this.height / 2); + + /** + * The center of the Static Body's boundary. + * This is the midpoint of its `position` (top-left corner) and its bottom-right corner. + * + * @name Phaser.Physics.Arcade.StaticBody#center + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + /** + * A constant zero velocity used by the Arcade Physics simulation for calculations. + * + * @name Phaser.Physics.Arcade.StaticBody#velocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.velocity = Vector2.ZERO; + + /** + * A constant `false` value expected by the Arcade Physics simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#allowGravity + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.allowGravity = false; + + /** + * Gravitational force applied specifically to this Body. Values are in pixels per second squared. Always zero for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#gravity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.gravity = Vector2.ZERO; + + /** + * Rebound, or restitution, following a collision, relative to 1. Always zero for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#bounce + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.bounce = Vector2.ZERO; + + // If true this Body will dispatch events + + /** + * Whether the simulation emits a `worldbounds` event when this StaticBody collides with the world boundary. + * Always false for a Static Body. (Static Bodies never collide with the world boundary and never trigger a `worldbounds` event.) + * + * @name Phaser.Physics.Arcade.StaticBody#onWorldBounds + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.onWorldBounds = false; + + /** + * Whether the simulation emits a `collide` event when this StaticBody collides with another. + * + * @name Phaser.Physics.Arcade.StaticBody#onCollide + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.onCollide = false; + + /** + * Whether the simulation emits an `overlap` event when this StaticBody overlaps with another. + * + * @name Phaser.Physics.Arcade.StaticBody#onOverlap + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.onOverlap = false; + + /** + * The StaticBody's inertia, relative to a default unit (1). With `bounce`, this affects the exchange of momentum (velocities) during collisions. + * + * @name Phaser.Physics.Arcade.StaticBody#mass + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.mass = 1; + + /** + * Whether this object can be moved by collisions with another body. + * + * @name Phaser.Physics.Arcade.StaticBody#immovable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.immovable = true; + + /** + * Sets if this Body can be pushed by another Body. + * + * A body that cannot be pushed will reflect back all of the velocity it is given to the + * colliding body. If that body is also not pushable, then the separation will be split + * between them evenly. + * + * If you want your body to never move or seperate at all, see the `setImmovable` method. + * + * By default, Static Bodies are not pushable. + * + * @name Phaser.Physics.Arcade.StaticBody#pushable + * @type {boolean} + * @default false + * @since 3.50.0 + * @see Phaser.GameObjects.Components.Pushable#setPushable + */ + this.pushable = false; + + /** + * A flag disabling the default horizontal separation of colliding bodies. Pass your own `collideHandler` to the collider. + * + * @name Phaser.Physics.Arcade.StaticBody#customSeparateX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateX = false; + + /** + * A flag disabling the default vertical separation of colliding bodies. Pass your own `collideHandler` to the collider. + * + * @name Phaser.Physics.Arcade.StaticBody#customSeparateY + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateY = false; + + /** + * The amount of horizontal overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapX = 0; + + /** + * The amount of vertical overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapY = 0; + + /** + * The amount of overlap (before separation), if this StaticBody is circular and colliding with another circular body. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapR + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapR = 0; + + /** + * Whether this StaticBody has ever overlapped with another while both were not moving. + * + * @name Phaser.Physics.Arcade.StaticBody#embedded + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.embedded = false; + + /** + * Whether this StaticBody interacts with the world boundary. + * Always false for a Static Body. (Static Bodies never collide with the world boundary.) + * + * @name Phaser.Physics.Arcade.StaticBody#collideWorldBounds + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.collideWorldBounds = false; + + /** + * Whether this StaticBody is checked for collisions and for which directions. You can set `checkCollision.none = false` to disable collision checks. + * + * @name Phaser.Physics.Arcade.StaticBody#checkCollision + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * + * @name Phaser.Physics.Arcade.StaticBody#touching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.touching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * The values are always false for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#wasTouching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * + * @name Phaser.Physics.Arcade.StaticBody#blocked + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.blocked = { none: true, up: false, down: false, left: false, right: false }; + + /** + * The StaticBody's physics type (static by default). + * + * @name Phaser.Physics.Arcade.StaticBody#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.STATIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.STATIC_BODY; + + /** + * The calculated change in the Static Body's horizontal position during the current step. + * For a static body this is always zero. + * + * @name Phaser.Physics.Arcade.StaticBody#_dx + * @type {number} + * @private + * @default 0 + * @since 3.10.0 + */ + this._dx = 0; + + /** + * The calculated change in the Static Body's vertical position during the current step. + * For a static body this is always zero. + * + * @name Phaser.Physics.Arcade.StaticBody#_dy + * @type {number} + * @private + * @default 0 + * @since 3.10.0 + */ + this._dy = 0; + }, + + /** + * Changes the Game Object this Body is bound to. + * First it removes its reference from the old Game Object, then sets the new one. + * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#setGameObject + * @since 3.1.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. + * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * + * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject + */ + setGameObject: function (gameObject, update) + { + if (gameObject && gameObject !== this.gameObject) + { + // Remove this body from the old game object + this.gameObject.body = null; + + gameObject.body = this; + + // Update our reference + this.gameObject = gameObject; + } + + if (update) + { + this.updateFromGameObject(); + } + + return this; + }, + + /** + * Syncs the Static Body's position and size with its parent Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject + * @since 3.1.0 + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + updateFromGameObject: function () + { + this.world.staticTree.remove(this); + + var gameObject = this.gameObject; + + gameObject.getTopLeft(this.position); + + this.width = gameObject.displayWidth; + this.height = gameObject.displayHeight; + + this.halfWidth = Math.abs(this.width / 2); + this.halfHeight = Math.abs(this.height / 2); + + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Positions the Static Body at an offset from its Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#setOffset + * @since 3.4.0 + * + * @param {number} x - The horizontal offset of the Static Body from the Game Object's `x`. + * @param {number} y - The vertical offset of the Static Body from the Game Object's `y`. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setOffset: function (x, y) + { + if (y === undefined) { y = x; } + + this.world.staticTree.remove(this); + + this.position.x -= this.offset.x; + this.position.y -= this.offset.y; + + this.offset.set(x, y); + + this.position.x += this.offset.x; + this.position.y += this.offset.y; + + this.updateCenter(); + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Sets the size of the Static Body. + * When `center` is true, also repositions it. + * Resets the width and height to match current frame, if no width and height provided and a frame is found. + * + * @method Phaser.Physics.Arcade.StaticBody#setSize + * @since 3.0.0 + * + * @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. + * @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. + * @param {boolean} [center=true] - Place the Static Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setSize: function (width, height, center) + { + if (center === undefined) { center = true; } + + var gameObject = this.gameObject; + + if (!width && gameObject.frame) + { + width = gameObject.frame.realWidth; + } + + if (!height && gameObject.frame) + { + height = gameObject.frame.realHeight; + } + + this.world.staticTree.remove(this); + + this.width = width; + this.height = height; + + this.halfWidth = Math.floor(width / 2); + this.halfHeight = Math.floor(height / 2); + + if (center && gameObject.getCenter) + { + var ox = gameObject.displayWidth / 2; + var oy = gameObject.displayHeight / 2; + + this.position.x -= this.offset.x; + this.position.y -= this.offset.y; + + this.offset.set(ox - this.halfWidth, oy - this.halfHeight); + + this.position.x += this.offset.x; + this.position.y += this.offset.y; + } + + this.updateCenter(); + + this.isCircle = false; + this.radius = 0; + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Sets this Static Body to have a circular body and sets its size and position. + * + * @method Phaser.Physics.Arcade.StaticBody#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the StaticBody, in pixels. + * @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels. + * @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setCircle: function (radius, offsetX, offsetY) + { + if (offsetX === undefined) { offsetX = this.offset.x; } + if (offsetY === undefined) { offsetY = this.offset.y; } + + if (radius > 0) + { + this.world.staticTree.remove(this); + + this.isCircle = true; + + this.radius = radius; + + this.width = radius * 2; + this.height = radius * 2; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.offset.set(offsetX, offsetY); + + this.updateCenter(); + + this.world.staticTree.insert(this); + } + else + { + this.isCircle = false; + } + + return this; + }, + + /** + * Updates the StaticBody's `center` from its `position` and dimensions. + * + * @method Phaser.Physics.Arcade.StaticBody#updateCenter + * @since 3.0.0 + */ + updateCenter: function () + { + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + }, + + /** + * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. + * + * @method Phaser.Physics.Arcade.StaticBody#reset + * @since 3.0.0 + * + * @param {number} [x] - The x coordinate to reset the body to. If not given will use the parent Game Object's coordinate. + * @param {number} [y] - The y coordinate to reset the body to. If not given will use the parent Game Object's coordinate. + */ + reset: function (x, y) + { + var gameObject = this.gameObject; + + if (x === undefined) { x = gameObject.x; } + if (y === undefined) { y = gameObject.y; } + + this.world.staticTree.remove(this); + + gameObject.setPosition(x, y); + + gameObject.getTopLeft(this.position); + + this.updateCenter(); + + this.world.staticTree.insert(this); + }, + + /** + * NOOP function. A Static Body cannot be stopped. + * + * @method Phaser.Physics.Arcade.StaticBody#stop + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + stop: function () + { + return this; + }, + + /** + * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. + * + * @method Phaser.Physics.Arcade.StaticBody#getBounds + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. + * + * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody. + */ + getBounds: function (obj) + { + obj.x = this.x; + obj.y = this.y; + obj.right = this.right; + obj.bottom = this.bottom; + + return obj; + }, + + /** + * Checks to see if a given x,y coordinate is colliding with this Static Body. + * + * @method Phaser.Physics.Arcade.StaticBody#hitTest + * @since 3.0.0 + * + * @param {number} x - The x coordinate to check against this body. + * @param {number} y - The y coordinate to check against this body. + * + * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. + */ + hitTest: function (x, y) + { + return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); + }, + + /** + * NOOP + * + * @method Phaser.Physics.Arcade.StaticBody#postUpdate + * @since 3.12.0 + */ + postUpdate: function () + { + }, + + /** + * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX + * @since 3.0.0 + * + * @return {number} Always zero for a Static Body. + */ + deltaAbsX: function () + { + return 0; + }, + + /** + * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY + * @since 3.0.0 + * + * @return {number} Always zero for a Static Body. + */ + deltaAbsY: function () + { + return 0; + }, + + /** + * The change in this StaticBody's horizontal position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaX + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + */ + deltaX: function () + { + return 0; + }, + + /** + * The change in this StaticBody's vertical position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaY + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + */ + deltaY: function () + { + return 0; + }, + + /** + * The change in this StaticBody's rotation from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaZ + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. + */ + deltaZ: function () + { + return 0; + }, + + /** + * Disables this Body and marks it for destruction during the next step. + * + * @method Phaser.Physics.Arcade.StaticBody#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enable = false; + + this.world.pendingDestroy.set(this); + }, + + /** + * Draws a graphical representation of the StaticBody for visual debugging purposes. + * + * @method Phaser.Physics.Arcade.StaticBody#drawDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. + */ + drawDebug: function (graphic) + { + var pos = this.position; + + var x = pos.x + this.halfWidth; + var y = pos.y + this.halfHeight; + + if (this.debugShowBody) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor, 1); + + if (this.isCircle) + { + graphic.strokeCircle(x, y, this.width / 2); + } + else + { + graphic.strokeRect(pos.x, pos.y, this.width, this.height); + } + + } + }, + + /** + * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. + * + * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug + * @since 3.0.0 + * + * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. + */ + willDrawDebug: function () + { + return this.debugShowBody; + }, + + /** + * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. + * + * @method Phaser.Physics.Arcade.StaticBody#setMass + * @since 3.0.0 + * + * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setMass: function (value) + { + if (value <= 0) + { + // Causes havoc otherwise + value = 0.1; + } + + this.mass = value; + + return this; + }, + + /** + * The x coordinate of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.world.staticTree.remove(this); + + this.position.x = value; + + this.world.staticTree.insert(this); + } + + }, + + /** + * The y coordinate of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.world.staticTree.remove(this); + + this.position.y = value; + + this.world.staticTree.insert(this); + } + + }, + + /** + * Returns the left-most x coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#left + * @type {number} + * @readonly + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.position.x; + } + + }, + + /** + * The right-most x coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#right + * @type {number} + * @readonly + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.position.x + this.width; + } + + }, + + /** + * The highest y coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#top + * @type {number} + * @readonly + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.position.y; + } + + }, + + /** + * The lowest y coordinate of the area of the StaticBody. (y + height) + * + * @name Phaser.Physics.Arcade.StaticBody#bottom + * @type {number} + * @readonly + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.position.y + this.height; + } + + } + +}); + +module.exports = StaticBody; + + +/***/ }), +/* 534 */, +/* 535 */, +/* 536 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* @author Richard Davey +* @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; + + +/***/ }), +/* 537 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +var point = new Vector2(); + +/** + * Checks if the given tile coordinate is within the isometric layer bounds, or not. + * + * @function Phaser.Tilemaps.Components.CheckIsoBounds + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to check against. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. + * + * @return {boolean} Returns `true` if the coordinates are within the iso bounds. + */ +var CheckIsoBounds = function (tileX, tileY, layer, camera) +{ + var tilemapLayer = layer.tilemapLayer; + + var cullPaddingX = tilemapLayer.cullPaddingX; + var cullPaddingY = tilemapLayer.cullPaddingY; + + var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer); + + // we always subtract 1/2 of the tile's height/width to make the culling distance start from the center of the tiles. + return pos.x > camera.worldView.x + tilemapLayer.scaleX * layer.tileWidth * (-cullPaddingX - 0.5) + && pos.x < camera.worldView.right + tilemapLayer.scaleX * layer.tileWidth * (cullPaddingX - 0.5) + && pos.y > camera.worldView.y + tilemapLayer.scaleY * layer.tileHeight * (-cullPaddingY - 1.0) + && pos.y < camera.worldView.bottom + tilemapLayer.scaleY * layer.tileHeight * (cullPaddingY - 0.5); +}; + +module.exports = CheckIsoBounds; + + +/***/ }), +/* 538 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(26); + +/** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * @function Phaser.Tilemaps.Components.ReplaceByIndex + * @since 3.0.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var ReplaceByIndex = function (findIndex, newIndex, tileX, tileY, width, height, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) + { + if (tiles[i] && tiles[i].index === findIndex) + { + tiles[i].index = newIndex; + } + } +}; + +module.exports = ReplaceByIndex; + + +/***/ }), +/* 539 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +var bounds = new Rectangle(); + +/** + * Returns the bounds in the given orthogonal layer that are within the cameras viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.CullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {Phaser.Geom.Rectangle} A rectangle containing the culled bounds. If you wish to retain this object, clone it, as it's recycled internally. + */ +var CullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY; + + return bounds.setTo( + boundsLeft, + boundsTop, + (boundsRight - boundsLeft), + (boundsBottom - boundsTop) + ); +}; + +module.exports = CullBounds; + + +/***/ }), +/* 540 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(539); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.CullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var CullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + var bounds = CullBounds(layer, camera); + + if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) + { + bounds.left = 0; + bounds.right = layer.width; + bounds.top = 0; + bounds.bottom = layer.height; + } + + RunCull(layer, bounds, renderOrder, outputArray); + + return outputArray; +}; + +module.exports = CullTiles; + + +/***/ }), +/* 541 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(542); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.HexagonalCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var HexagonalCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + { + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + + var bounds = CullBounds(layer, camera); + + RunCull(layer, bounds, renderOrder, outputArray); + } + + return outputArray; +}; + +module.exports = HexagonalCullTiles; + + +/***/ }), +/* 542 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +/** + * Returns the bounds in the given layer that are within the camera's viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.HexagonalCullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + */ +var HexagonalCullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var len = layer.hexSideLength; + var rowH = ((tileH - len) / 2 + len); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY; + + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; + +module.exports = HexagonalCullBounds; + + +/***/ }), +/* 543 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CheckIsoBounds = __webpack_require__(537); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.IsometricCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + + var drawLeft = 0; + var drawRight = mapWidth; + var drawTop = 0; + var drawBottom = mapHeight; + + if (!tilemapLayer.skipCull) + { + var x; + var y; + var tile; + + if (renderOrder === 0) + { + // right-down + + for (y = drawTop; y < drawBottom; y++) + { + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 1) + { + // left-down + + for (y = drawTop; y < drawBottom; y++) + { + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 2) + { + // right-up + + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 3) + { + // left-up + + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + } + + tilemapLayer.tilesDrawn = outputArray.length; + tilemapLayer.tilesTotal = mapWidth * mapHeight; + + return outputArray; +}; + +module.exports = IsometricCullTiles; + + +/***/ }), +/* 544 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(545); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.StaggeredCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var StaggeredCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + { + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + + var bounds = CullBounds(layer, camera); + + RunCull(layer, bounds, renderOrder, outputArray); + } + + return outputArray; +}; + +module.exports = StaggeredCullTiles; + + +/***/ }), +/* 545 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +/** + * Returns the bounds in the given layer that are within the camera's viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.StaggeredCullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + */ +var StaggeredCullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH / 2, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH / 2, 0, true) + tilemapLayer.cullPaddingY; + + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; + +module.exports = StaggeredCullBounds; + + +/***/ }), +/* 546 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from hexagonal tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.HexagonalTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = layer.hexSideLength; + var rowHeight = ((tileHeight - len) / 2 + len); + + // similar to staggered, because Tiled uses the oddr representation. + var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); + var y = layerWorldY + tileY * rowHeight; + + return point.set(x, y); +}; + +module.exports = HexagonalTileToWorldXY; + + +/***/ }), +/* 547 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from isometric tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.IsometricTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var IsometricTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); + var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); + + return point.set(x, y); +}; + +module.exports = IsometricTileToWorldXY; + + +/***/ }), +/* 548 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from staggered tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.StaggeredTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var StaggeredTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); + var y = layerWorldY + tileY * (tileHeight / 2); + + return point.set(x, y); +}; + +module.exports = StaggeredTileToWorldXY; + + +/***/ }), +/* 549 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TileToWorldX = __webpack_require__(249); +var TileToWorldY = __webpack_require__(250); +var Vector2 = __webpack_require__(3); + +/** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.TileToWorldXY + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var TileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(0, 0); } + + point.x = TileToWorldX(tileX, camera, layer); + point.y = TileToWorldY(tileY, camera, layer); + + return point; +}; + +module.exports = TileToWorldXY; + + +/***/ }), +/* 550 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from hexagonal tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layer's position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.HexagonalTileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in world coordinates. + */ +var HexagonalTileToWorldY = function (tileY, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = tilemapLayer.tilemap.hexSideLength; + + var rowHeight = ((tileHeight - len) / 2 + len); + + return layerWorldY + tileY * rowHeight; +}; + +module.exports = HexagonalTileToWorldY; + + +/***/ }), +/* 551 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from staggered tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.StaggeredTileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in world coordinates. + */ +var StaggeredTileToWorldY = function (tileY, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + return layerWorldY + tileY * (tileHeight / 2); +}; + +module.exports = StaggeredTileToWorldY; + + +/***/ }), +/* 552 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinates down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + var len = layer.hexSideLength; + var rowHeight = ((tileHeight - len) / 2 + len); + + // similar to staggered, because Tiled uses the oddr representation. + var y = (snapToFloor) ? Math.floor((worldY / rowHeight)) : (worldY / rowHeight); + var x = (snapToFloor) ? Math.floor((worldX - (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX - (y % 2) * 0.5 * tileWidth) / tileWidth; + + return point.set(x, y); +}; + +module.exports = HexagonalWorldToTileXY; + + +/***/ }), +/* 553 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to isometric tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.IsometricWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var IsometricWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + worldX -= tileWidth / 2; + + var x = (snapToFloor) ? Math.floor((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2) : ((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2); + var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2) : ((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2); + + return point.set(x, y); +}; + +module.exports = IsometricWorldToTileXY; + + +/***/ }), +/* 554 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to staggered tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.StaggeredWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var StaggeredWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2))) : (worldY / (tileHeight / 2)); + var x = (snapToFloor) ? Math.floor((worldX + (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX + (y % 2) * 0.5 * tileWidth) / tileWidth; + + return point.set(x, y); +}; + +module.exports = StaggeredWorldToTileXY; + + +/***/ }), +/* 555 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WorldToTileX = __webpack_require__(251); +var WorldToTileY = __webpack_require__(252); +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.WorldToTileXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var WorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (snapToFloor === undefined) { snapToFloor = true; } + if (!point) { point = new Vector2(0, 0); } + + point.x = WorldToTileX(worldX, snapToFloor, camera, layer); + point.y = WorldToTileY(worldY, snapToFloor, camera, layer); + + return point; +}; + +module.exports = WorldToTileXY; + + +/***/ }), +/* 556 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from world Y coordinates (pixels) to hexagonal tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in tile units. + */ +var HexagonalWorldToTileY = function (worldY, snapToFloor, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = layer.hexSideLength; + + var rowHeight = ((tileHeight - len) / 2 + len); + + return (snapToFloor) ? Math.floor(worldY / rowHeight) : worldY / rowHeight; +}; + +module.exports = HexagonalWorldToTileY; + + +/***/ }), +/* 557 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from world Y coordinates (pixels) to staggered tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.StaggeredWorldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in tile units. + */ +var StaggeredWorldToTileY = function (worldY, snapToFloor, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + return (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); +}; + +module.exports = StaggeredWorldToTileY; + + +/***/ }), +/* 558 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var IsInLayerBounds = __webpack_require__(118); + +/** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @function Phaser.Tilemaps.Components.HasTileAt + * @since 3.0.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ +var HasTileAt = function (tileX, tileY, layer) +{ + if (IsInLayerBounds(tileX, tileY, layer)) + { + var tile = layer.data[tileY][tileX]; + + return (tile !== null && tile.index > -1); + } + else + { + return false; + } +}; + +module.exports = HasTileAt; + + +/***/ }), +/* 559 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tile = __webpack_require__(83); +var IsInLayerBounds = __webpack_require__(118); +var CalculateFacesAt = __webpack_require__(248); + +/** + * Removes the tile at the given tile coordinates in the specified layer and updates the layer's + * collision information. + * + * @function Phaser.Tilemaps.Components.RemoveTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate. + * @param {number} tileY - The y coordinate. + * @param {boolean} replaceWithNull - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} recalculateFaces - `true` if the faces data should be recalculated. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was removed. + */ +var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) +{ + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + if (!IsInLayerBounds(tileX, tileY, layer)) + { + return null; + } + + var tile = layer.data[tileY][tileX]; + + if (!tile) + { + return null; + } + else + { + layer.data[tileY][tileX] = (replaceWithNull) ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight); + } + + // Recalculate faces only if the removed tile was a colliding tile + if (recalculateFaces && tile && tile.collides) + { + CalculateFacesAt(tileX, tileY, layer); + } + + return tile; +}; + +module.exports = RemoveTileAt; + + +/***/ }), +/* 560 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var Parse2DArray = __webpack_require__(255); +var ParseCSV = __webpack_require__(561); +var ParseJSONTiled = __webpack_require__(562); +var ParseWeltmeister = __webpack_require__(573); + +/** + * Parses raw data of a given Tilemap format into a new MapData object. If no recognized data format + * is found, returns `null`. When loading from CSV or a 2D array, you should specify the tileWidth & + * tileHeight. When parsing from a map from Tiled, the tileWidth & tileHeight will be pulled from + * the map data. + * + * @function Phaser.Tilemaps.Parsers.Parse + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {number} mapFormat - See ../Formats.js. + * @param {(number[][]|string|object)} data - 2D array, CSV string or Tiled JSON object. + * @param {number} tileWidth - The width of a tile in pixels. Required for 2D array and CSV, but + * ignored for Tiled JSON. + * @param {number} tileHeight - The height of a tile in pixels. Required for 2D array and CSV, but + * ignored for Tiled JSON. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {Phaser.Tilemaps.MapData} The created `MapData` object. + */ +var Parse = function (name, mapFormat, data, tileWidth, tileHeight, insertNull) +{ + var newMap; + + switch (mapFormat) + { + case (Formats.ARRAY_2D): + newMap = Parse2DArray(name, data, tileWidth, tileHeight, insertNull); + break; + case (Formats.CSV): + newMap = ParseCSV(name, data, tileWidth, tileHeight, insertNull); + break; + case (Formats.TILED_JSON): + newMap = ParseJSONTiled(name, data, insertNull); + break; + case (Formats.WELTMEISTER): + newMap = ParseWeltmeister(name, data, insertNull); + break; + default: + console.warn('Unrecognized tilemap data format: ' + mapFormat); + newMap = null; + } + + return newMap; +}; + +module.exports = Parse; + + +/***/ }), +/* 561 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var Parse2DArray = __webpack_require__(255); + +/** + * Parses a CSV string of tile indexes into a new MapData object with a single layer. + * + * @function Phaser.Tilemaps.Parsers.ParseCSV + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {string} data - CSV string of tile indexes. + * @param {number} tileWidth - The width of a tile in pixels. + * @param {number} tileHeight - The height of a tile in pixels. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {Phaser.Tilemaps.MapData} The resulting MapData object. + */ +var ParseCSV = function (name, data, tileWidth, tileHeight, insertNull) +{ + var array2D = data + .trim() + .split('\n') + .map(function (row) { return row.split(','); }); + + var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); + map.format = Formats.CSV; + + return map; +}; + +module.exports = ParseCSV; + + +/***/ }), +/* 562 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AssignTileProperties = __webpack_require__(563); +var BuildTilesetIndex = __webpack_require__(564); +var CONST = __webpack_require__(29); +var Formats = __webpack_require__(38); +var FromOrientationString = __webpack_require__(254); +var MapData = __webpack_require__(120); +var ParseImageLayers = __webpack_require__(565); +var ParseObjectLayers = __webpack_require__(566); +var ParseTileLayers = __webpack_require__(569); +var ParseTilesets = __webpack_require__(571); + +/** + * Parses a Tiled JSON object into a new MapData object. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {object} json - The Tiled JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + */ +var ParseJSONTiled = function (name, json, insertNull) +{ + // Map data will consist of: layers, objects, images, tilesets, sizes + var mapData = new MapData({ + width: json.width, + height: json.height, + name: name, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + orientation: FromOrientationString(json.orientation), + format: Formats.TILED_JSON, + version: json.version, + properties: json.properties, + renderOrder: json.renderorder, + infinite: json.infinite + }); + + if (mapData.orientation === CONST.HEXAGONAL) + { + mapData.hexSideLength = json.hexsidelength; + } + + mapData.layers = ParseTileLayers(json, insertNull); + mapData.images = ParseImageLayers(json); + + var sets = ParseTilesets(json); + + mapData.tilesets = sets.tilesets; + mapData.imageCollections = sets.imageCollections; + + mapData.objects = ParseObjectLayers(json); + + mapData.tiles = BuildTilesetIndex(mapData); + + AssignTileProperties(mapData); + + return mapData; +}; + +module.exports = ParseJSONTiled; + + +/***/ }), +/* 563 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Extend = __webpack_require__(17); + +/** + * Copy properties from tileset to tiles. + * + * @function Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + */ +var AssignTileProperties = function (mapData) +{ + var layerData; + var tile; + var sid; + var set; + var row; + + // go through each of the map data layers + for (var i = 0; i < mapData.layers.length; i++) + { + layerData = mapData.layers[i]; + + set = null; + + // rows of tiles + for (var j = 0; j < layerData.data.length; j++) + { + row = layerData.data[j]; + + // individual tiles + for (var k = 0; k < row.length; k++) + { + tile = row[k]; + + if (tile === null || tile.index < 0) + { + continue; + } + + // find the relevant tileset + sid = mapData.tiles[tile.index][2]; + set = mapData.tilesets[sid]; + + // Ensure that a tile's size matches its tileset + tile.width = set.tileWidth; + tile.height = set.tileHeight; + + // if that tile type has any properties, add them to the tile object + if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) + { + tile.properties = Extend( + tile.properties, set.tileProperties[tile.index - set.firstgid] + ); + } + } + } + } +}; + +module.exports = AssignTileProperties; + + +/***/ }), +/* 564 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); + +/** + * Master list of tiles -> x, y, index in tileset. + * + * @function Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + * + * @return {array} An array of Tileset objects. + */ +var BuildTilesetIndex = function (mapData) +{ + var i; + var set; + var tiles = []; + + for (i = 0; i < mapData.imageCollections.length; i++) + { + var collection = mapData.imageCollections[i]; + var images = collection.images; + + for (var j = 0; j < images.length; j++) + { + var image = images[j]; + + set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); + + set.updateTileData(collection.imageWidth, collection.imageHeight); + + mapData.tilesets.push(set); + } + } + + for (i = 0; i < mapData.tilesets.length; i++) + { + set = mapData.tilesets[i]; + + var x = set.tileMargin; + var y = set.tileMargin; + + var count = 0; + var countX = 0; + var countY = 0; + + for (var t = set.firstgid; t < set.firstgid + set.total; t++) + { + // Can add extra properties here as needed + tiles[t] = [ x, y, i ]; + + x += set.tileWidth + set.tileSpacing; + + count++; + + if (count === set.total) + { + break; + } + + countX++; + + if (countX === set.columns) + { + x = set.tileMargin; + y += set.tileHeight + set.tileSpacing; + + countX = 0; + countY++; + + if (countY === set.rows) + { + break; + } + } + } + } + + return tiles; +}; + +module.exports = BuildTilesetIndex; + + +/***/ }), +/* 565 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var CreateGroupLayer = __webpack_require__(159); + +/** + * Parses a Tiled JSON object into an array of objects with details about the image layers. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * + * @return {array} Array of objects that include critical info about the map's image layers + */ +var ParseImageLayers = function (json) +{ + var images = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + // Get current layer and advance iterator + var curi = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + if (curi.type !== 'imagelayer') + { + if (curi.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curi, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + var layerOffsetX = GetFastValue(curi, 'offsetx', 0) + GetFastValue(curi, 'startx', 0); + var layerOffsetY = GetFastValue(curi, 'offsety', 0) + GetFastValue(curi, 'starty', 0); + images.push({ + name: (curGroupState.name + curi.name), + image: curi.image, + x: (curGroupState.x + layerOffsetX + curi.x), + y: (curGroupState.y + layerOffsetY + curi.y), + alpha: (curGroupState.opacity * curi.opacity), + visible: (curGroupState.visible && curi.visible), + properties: GetFastValue(curi, 'properties', {}) + }); + } + + return images; +}; + +module.exports = ParseImageLayers; + + +/***/ }), +/* 566 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var ParseObject = __webpack_require__(256); +var ObjectLayer = __webpack_require__(568); +var CreateGroupLayer = __webpack_require__(159); + +/** + * Parses a Tiled JSON object into an array of ObjectLayer objects. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * + * @return {array} An array of all object layers in the tilemap as `ObjectLayer`s. + */ +var ParseObjectLayers = function (json) +{ + var objectLayers = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + // Get current layer and advance iterator + var curo = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + // Modify inherited properties + curo.opacity *= curGroupState.opacity; + curo.visible = curGroupState.visible && curo.visible; + + if (curo.type !== 'objectgroup') + { + if (curo.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curo, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + curo.name = curGroupState.name + curo.name; + var offsetX = curGroupState.x + GetFastValue(curo, 'startx', 0) + GetFastValue(curo, 'offsetx', 0); + var offsetY = curGroupState.y + GetFastValue(curo, 'starty', 0) + GetFastValue(curo, 'offsety', 0); + + var objects = []; + for (var j = 0; j < curo.objects.length; j++) + { + var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); + + objects.push(parsedObject); + } + + var objectLayer = new ObjectLayer(curo); + objectLayer.objects = objects; + + objectLayers.push(objectLayer); + } + + return objectLayers; +}; + +module.exports = ParseObjectLayers; + + +/***/ }), +/* 567 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var HasValue = __webpack_require__(125); + +/** + * Returns a new object that only contains the `keys` that were found on the object provided. + * If no `keys` are found, an empty object is returned. + * + * @function Phaser.Utils.Objects.Pick + * @since 3.18.0 + * + * @param {object} object - The object to pick the provided keys from. + * @param {array} keys - An array of properties to retrieve from the provided object. + * + * @return {object} A new object that only contains the `keys` that were found on the provided object. If no `keys` were found, an empty object will be returned. + */ +var Pick = function (object, keys) +{ + var obj = {}; + + for (var i = 0; i < keys.length; i++) + { + var key = keys[i]; + + if (HasValue(object, key)) + { + obj[key] = object[key]; + } + } + + return obj; +}; + +module.exports = Pick; + + +/***/ }), +/* 568 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * A class for representing a Tiled object layer in a map. This mirrors the structure of a Tiled + * object layer, except: + * - "x" & "y" properties are ignored since these cannot be changed in Tiled. + * - "offsetx" & "offsety" are applied to the individual object coordinates directly, so they + * are ignored as well. + * - "draworder" is ignored. + * + * @class ObjectLayer + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Tilemaps.ObjectLayerConfig} [config] - The data for the layer from the Tiled JSON object. + */ +var ObjectLayer = new Class({ + + initialize: + + function ObjectLayer (config) + { + if (config === undefined) { config = {}; } + + /** + * The name of the Object Layer. + * + * @name Phaser.Tilemaps.ObjectLayer#name + * @type {string} + * @since 3.0.0 + */ + this.name = GetFastValue(config, 'name', 'object layer'); + + /** + * The opacity of the layer, between 0 and 1. + * + * @name Phaser.Tilemaps.ObjectLayer#opacity + * @type {number} + * @since 3.0.0 + */ + this.opacity = GetFastValue(config, 'opacity', 1); + + /** + * The custom properties defined on the Object Layer, keyed by their name. + * + * @name Phaser.Tilemaps.ObjectLayer#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = GetFastValue(config, 'properties', {}); + + /** + * The type of each custom property defined on the Object Layer, keyed by its name. + * + * @name Phaser.Tilemaps.ObjectLayer#propertyTypes + * @type {object} + * @since 3.0.0 + */ + this.propertyTypes = GetFastValue(config, 'propertytypes', {}); + + /** + * The type of the layer, which should be `objectgroup`. + * + * @name Phaser.Tilemaps.ObjectLayer#type + * @type {string} + * @since 3.0.0 + */ + this.type = GetFastValue(config, 'type', 'objectgroup'); + + /** + * Whether the layer is shown (`true`) or hidden (`false`). + * + * @name Phaser.Tilemaps.ObjectLayer#visible + * @type {boolean} + * @since 3.0.0 + */ + this.visible = GetFastValue(config, 'visible', true); + + /** + * An array of all objects on this Object Layer. + * + * Each Tiled object corresponds to a JavaScript object in this array. It has an `id` (unique), + * `name` (as assigned in Tiled), `type` (as assigned in Tiled), `rotation` (in clockwise degrees), + * `properties` (if any), `visible` state (`true` if visible, `false` otherwise), + * `x` and `y` coordinates (in pixels, relative to the tilemap), and a `width` and `height` (in pixels). + * + * An object tile has a `gid` property (GID of the represented tile), a `flippedHorizontal` property, + * a `flippedVertical` property, and `flippedAntiDiagonal` property. + * The {@link http://docs.mapeditor.org/en/latest/reference/tmx-map-format/|Tiled documentation} contains + * information on flipping and rotation. + * + * Polylines have a `polyline` property, which is an array of objects corresponding to points, + * where each point has an `x` property and a `y` property. Polygons have an identically structured + * array in their `polygon` property. Text objects have a `text` property with the text's properties. + * + * Rectangles and ellipses have a `rectangle` or `ellipse` property set to `true`. + * + * @name Phaser.Tilemaps.ObjectLayer#objects + * @type {Phaser.Types.Tilemaps.TiledObject[]} + * @since 3.0.0 + */ + this.objects = GetFastValue(config, 'objects', []); + } + +}); + +module.exports = ObjectLayer; + + +/***/ }), +/* 569 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Base64Decode = __webpack_require__(570); +var CONST = __webpack_require__(29); +var CreateGroupLayer = __webpack_require__(159); +var FromOrientationString = __webpack_require__(254); +var GetFastValue = __webpack_require__(2); +var LayerData = __webpack_require__(119); +var ParseGID = __webpack_require__(257); +var Tile = __webpack_require__(83); + +/** + * Parses all tilemap layers in a Tiled JSON object into new LayerData objects. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). + * + * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in + * json.layers with the type 'tilelayer'. + */ +var ParseTileLayers = function (json, insertNull) +{ + var infiniteMap = GetFastValue(json, 'infinite', false); + var tileLayers = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + var curl = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + if (curl.type !== 'tilelayer') + { + if (curl.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curl, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + // Base64 decode data if necessary. NOTE: uncompressed base64 only. + if (curl.compression) + { + console.warn( + 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' + + curl.name + '\'' + ); + continue; + } + else if (curl.encoding && curl.encoding === 'base64') + { + // Chunks for an infinite map + if (curl.chunks) + { + for (var i = 0; i < curl.chunks.length; i++) + { + curl.chunks[i].data = Base64Decode(curl.chunks[i].data); + } + } + + // Non-infinite map data + if (curl.data) + { + curl.data = Base64Decode(curl.data); + } + + delete curl.encoding; // Allow the same map to be parsed multiple times + } + + // This is an array containing the tile indexes, one after the other. -1 = no tile, + // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map + // contains multiple tilesets then the indexes are relative to that which the set starts + // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this + // manually it means you can use the same map data but a new tileset. + + var layerData; + var gidInfo; + var tile; + var blankTile; + + var output = []; + var x = 0; + + if (infiniteMap) + { + var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x); + var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y); + + layerData = new LayerData({ + name: (curGroupState.name + curl.name), + x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + layerOffsetX * json.tilewidth), + y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + layerOffsetY * json.tileheight), + width: curl.width, + height: curl.height, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + alpha: (curGroupState.opacity * curl.opacity), + visible: (curGroupState.visible && curl.visible), + properties: GetFastValue(curl, 'properties', []), + orientation: FromOrientationString(json.orientation) + }); + + if (layerData.orientation === CONST.HEXAGONAL) + { + layerData.hexSideLength = json.hexsidelength; + } + + for (var c = 0; c < curl.height; c++) + { + output.push([ null ]); + + for (var j = 0; j < curl.width; j++) + { + output[c][j] = null; + } + } + + for (c = 0, len = curl.chunks.length; c < len; c++) + { + var chunk = curl.chunks[c]; + + var offsetX = (chunk.x - layerOffsetX); + var offsetY = (chunk.y - layerOffsetY); + + var y = 0; + + for (var t = 0, len2 = chunk.data.length; t < len2; t++) + { + var newOffsetX = x + offsetX; + var newOffsetY = y + offsetY; + + gidInfo = ParseGID(chunk.data[t]); + + // index, x, y, width, height + if (gidInfo.gid > 0) + { + tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); + + // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal + // propeties into flipX, flipY and rotation + tile.rotation = gidInfo.rotation; + tile.flipX = gidInfo.flipped; + + output[newOffsetY][newOffsetX] = tile; + } + else + { + blankTile = insertNull + ? null + : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); + + output[newOffsetY][newOffsetX] = blankTile; + } + + x++; + + if (x === chunk.width) + { + y++; + x = 0; + } + } + } + } + else + { + layerData = new LayerData({ + name: (curGroupState.name + curl.name), + x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + curl.x), + y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + curl.y), + width: curl.width, + height: curl.height, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + alpha: (curGroupState.opacity * curl.opacity), + visible: (curGroupState.visible && curl.visible), + properties: GetFastValue(curl, 'properties', []), + orientation: FromOrientationString(json.orientation) + }); + + if (layerData.orientation === CONST.HEXAGONAL) + { + layerData.hexSideLength = json.hexsidelength; + } + var row = []; + + // Loop through the data field in the JSON. + for (var k = 0, len = curl.data.length; k < len; k++) + { + gidInfo = ParseGID(curl.data[k]); + + // index, x, y, width, height + if (gidInfo.gid > 0) + { + tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); + + // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal + // propeties into flipX, flipY and rotation + tile.rotation = gidInfo.rotation; + tile.flipX = gidInfo.flipped; + + row.push(tile); + } + else + { + blankTile = insertNull + ? null + : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); + row.push(blankTile); + } + + x++; + + if (x === curl.width) + { + output.push(row); + x = 0; + row = []; + } + } + } + + layerData.data = output; + tileLayers.push(layerData); + } + + return tileLayers; +}; + +module.exports = ParseTileLayers; + + +/***/ }), +/* 570 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Decode base-64 encoded data, for example as exported by Tiled. + * + * @function Phaser.Tilemaps.Parsers.Tiled.Base64Decode + * @since 3.0.0 + * + * @param {object} data - Base-64 encoded data to decode. + * + * @return {array} Array containing the decoded bytes. + */ +var Base64Decode = function (data) +{ + var binaryString = window.atob(data); + var len = binaryString.length; + var bytes = new Array(len / 4); + + // Interpret binaryString as an array of bytes representing little-endian encoded uint32 values. + for (var i = 0; i < len; i += 4) + { + bytes[i / 4] = ( + binaryString.charCodeAt(i) | + binaryString.charCodeAt(i + 1) << 8 | + binaryString.charCodeAt(i + 2) << 16 | + binaryString.charCodeAt(i + 3) << 24 + ) >>> 0; + } + + return bytes; +}; + +module.exports = Base64Decode; + + +/***/ }), +/* 571 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); +var ImageCollection = __webpack_require__(572); +var ParseObject = __webpack_require__(256); + +/** + * Tilesets and Image Collections + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseTilesets + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON data. + * + * @return {object} An object containing the tileset and image collection data. + */ +var ParseTilesets = function (json) +{ + var tilesets = []; + var imageCollections = []; + var lastSet = null; + var stringID; + + for (var i = 0; i < json.tilesets.length; i++) + { + // name, firstgid, width, height, margin, spacing, properties + var set = json.tilesets[i]; + + if (set.source) + { + console.warn('External tilesets unsupported. Use Embed Tileset and re-export'); + } + else if (set.image) + { + var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); + + if (json.version > 1) + { + // Tiled 1.2+ + + if (Array.isArray(set.tiles)) + { + var tiles = {}; + var props = {}; + + for (var t = 0; t < set.tiles.length; t++) + { + var tile = set.tiles[t]; + + // Convert tileproperties + if (tile.properties) + { + var newPropData = {}; + + tile.properties.forEach(function (propData) + { + newPropData[propData['name']] = propData['value']; + }); + + props[tile.id] = newPropData; + } + + // Convert objectgroup + if (tile.objectgroup) + { + tiles[tile.id] = { objectgroup: tile.objectgroup }; + + if (tile.objectgroup.objects) + { + var parsedObjects2 = tile.objectgroup.objects.map(function (obj) + { + return ParseObject(obj); + }); + + tiles[tile.id].objectgroup.objects = parsedObjects2; + } + } + + // Copy animation data + if (tile.animation) + { + if (tiles.hasOwnProperty(tile.id)) + { + tiles[tile.id].animation = tile.animation; + } + else + { + tiles[tile.id] = { animation: tile.animation }; + } + } + } + + newSet.tileData = tiles; + newSet.tileProperties = props; + } + } + else + { + // Tiled 1 + + // Properties stored per-tile in object with string indexes starting at "0" + if (set.tileproperties) + { + newSet.tileProperties = set.tileproperties; + } + + // Object & terrain shapes stored per-tile in object with string indexes starting at "0" + if (set.tiles) + { + newSet.tileData = set.tiles; + + // Parse the objects into Phaser format to match handling of other Tiled objects + for (stringID in newSet.tileData) + { + var objectGroup = newSet.tileData[stringID].objectgroup; + + if (objectGroup && objectGroup.objects) + { + var parsedObjects1 = objectGroup.objects.map(function (obj) + { + return ParseObject(obj); + }); + + newSet.tileData[stringID].objectgroup.objects = parsedObjects1; + } + } + } + } + + // For a normal sliced tileset the row/count/size information is computed when updated. + // This is done (again) after the image is set. + newSet.updateTileData(set.imagewidth, set.imageheight); + + tilesets.push(newSet); + } + else + { + var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); + + var maxId = 0; + + for (t = 0; t < set.tiles.length; t++) + { + tile = set.tiles[t]; + + var image = tile.image; + var tileId = parseInt(tile.id, 10); + var gid = set.firstgid + tileId; + newCollection.addImage(gid, image); + + maxId = Math.max(tileId, maxId); + } + + newCollection.maxId = maxId; + + imageCollections.push(newCollection); + } + + // We've got a new Tileset, so set the lastgid into the previous one + if (lastSet) + { + lastSet.lastgid = set.firstgid - 1; + } + + lastSet = set; + } + + return { tilesets: tilesets, imageCollections: imageCollections }; +}; + +module.exports = ParseTilesets; + + +/***/ }), +/* 572 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * An Image Collection is a special Tile Set containing multiple images, with no slicing into each image. + * + * Image Collections are normally created automatically when Tiled data is loaded. + * + * @class ImageCollection + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {string} name - The name of the image collection in the map data. + * @param {number} firstgid - The first image index this image collection contains. + * @param {number} [width=32] - Width of widest image (in pixels). + * @param {number} [height=32] - Height of tallest image (in pixels). + * @param {number} [margin=0] - The margin around all images in the collection (in pixels). + * @param {number} [spacing=0] - The spacing between each image in the collection (in pixels). + * @param {object} [properties={}] - Custom Image Collection properties. + */ +var ImageCollection = new Class({ + + initialize: + + function ImageCollection (name, firstgid, width, height, margin, spacing, properties) + { + if (width === undefined || width <= 0) { width = 32; } + if (height === undefined || height <= 0) { height = 32; } + if (margin === undefined) { margin = 0; } + if (spacing === undefined) { spacing = 0; } + + /** + * The name of the Image Collection. + * + * @name Phaser.Tilemaps.ImageCollection#name + * @type {string} + * @since 3.0.0 + */ + this.name = name; + + /** + * The Tiled firstgid value. + * This is the starting index of the first image index this Image Collection contains. + * + * @name Phaser.Tilemaps.ImageCollection#firstgid + * @type {number} + * @since 3.0.0 + */ + this.firstgid = firstgid | 0; + + /** + * The width of the widest image (in pixels). + * + * @name Phaser.Tilemaps.ImageCollection#imageWidth + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageWidth = width | 0; + + /** + * The height of the tallest image (in pixels). + * + * @name Phaser.Tilemaps.ImageCollection#imageHeight + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageHeight = height | 0; + + /** + * The margin around the images in the collection (in pixels). + * Use `setSpacing` to change. + * + * @name Phaser.Tilemaps.ImageCollection#imageMarge + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageMargin = margin | 0; + + /** + * The spacing between each image in the collection (in pixels). + * Use `setSpacing` to change. + * + * @name Phaser.Tilemaps.ImageCollection#imageSpacing + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageSpacing = spacing | 0; + + /** + * Image Collection-specific properties that are typically defined in the Tiled editor. + * + * @name Phaser.Tilemaps.ImageCollection#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = properties || {}; + + /** + * The cached images that are a part of this collection. + * + * @name Phaser.Tilemaps.ImageCollection#images + * @type {array} + * @readonly + * @since 3.0.0 + */ + this.images = []; + + /** + * The total number of images in the image collection. + * + * @name Phaser.Tilemaps.ImageCollection#total + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.total = 0; + }, + + /** + * Returns true if and only if this image collection contains the given image index. + * + * @method Phaser.Tilemaps.ImageCollection#containsImageIndex + * @since 3.0.0 + * + * @param {number} imageIndex - The image index to search for. + * + * @return {boolean} True if this Image Collection contains the given index. + */ + containsImageIndex: function (imageIndex) + { + return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); + }, + + /** + * Add an image to this Image Collection. + * + * @method Phaser.Tilemaps.ImageCollection#addImage + * @since 3.0.0 + * + * @param {number} gid - The gid of the image in the Image Collection. + * @param {string} image - The the key of the image in the Image Collection and in the cache. + * + * @return {Phaser.Tilemaps.ImageCollection} This ImageCollection object. + */ + addImage: function (gid, image) + { + this.images.push({ gid: gid, image: image }); + this.total++; + + return this; + } + +}); + +module.exports = ImageCollection; + + +/***/ }), +/* 573 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var MapData = __webpack_require__(120); +var ParseTileLayers = __webpack_require__(574); +var ParseTilesets = __webpack_require__(575); + +/** + * Parses a Weltmeister JSON object into a new MapData object. + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {object} json - The Weltmeister JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + */ +var ParseWeltmeister = function (name, json, insertNull) +{ + if (json.layer.length === 0) + { + console.warn('No layers found in the Weltmeister map: ' + name); + return null; + } + + var width = 0; + var height = 0; + + for (var i = 0; i < json.layer.length; i++) + { + if (json.layer[i].width > width) { width = json.layer[i].width; } + if (json.layer[i].height > height) { height = json.layer[i].height; } + } + + var mapData = new MapData({ + width: width, + height: height, + name: name, + tileWidth: json.layer[0].tilesize, + tileHeight: json.layer[0].tilesize, + format: Formats.WELTMEISTER + }); + + mapData.layers = ParseTileLayers(json, insertNull); + mapData.tilesets = ParseTilesets(json); + + return mapData; +}; + +module.exports = ParseWeltmeister; + + +/***/ }), +/* 574 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LayerData = __webpack_require__(119); +var Tile = __webpack_require__(83); + +/** + * Parses all tilemap layers in an Impact JSON object into new LayerData objects. + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers + * @since 3.0.0 + * + * @param {object} json - The Impact JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). + * + * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in + * json.layers with the type 'tilelayer'. + */ +var ParseTileLayers = function (json, insertNull) +{ + var tileLayers = []; + + for (var i = 0; i < json.layer.length; i++) + { + var layer = json.layer[i]; + + var layerData = new LayerData({ + name: layer.name, + width: layer.width, + height: layer.height, + tileWidth: layer.tilesize, + tileHeight: layer.tilesize, + visible: layer.visible === 1 + }); + + var row = []; + var tileGrid = []; + + // Loop through the data field in the JSON. This is a 2D array containing the tile indexes, + // one after the other. The indexes are relative to the tileset that contains the tile. + for (var y = 0; y < layer.data.length; y++) + { + for (var x = 0; x < layer.data[y].length; x++) + { + // In Weltmeister, 0 = no tile, but the Tilemap API expects -1 = no tile. + var index = layer.data[y][x] - 1; + + var tile; + + if (index > -1) + { + tile = new Tile(layerData, index, x, y, layer.tilesize, layer.tilesize); + } + else + { + tile = insertNull + ? null + : new Tile(layerData, -1, x, y, layer.tilesize, layer.tilesize); + } + + row.push(tile); + } + + tileGrid.push(row); + row = []; + } + + layerData.data = tileGrid; + + tileLayers.push(layerData); + } + + return tileLayers; +}; + +module.exports = ParseTileLayers; + + +/***/ }), +/* 575 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); + +/** + * Tilesets and Image Collections + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseTilesets + * @since 3.0.0 + * + * @param {object} json - The Impact JSON data. + * + * @return {array} An array of Tilesets. + */ +var ParseTilesets = function (json) +{ + var tilesets = []; + var tilesetsNames = []; + + for (var i = 0; i < json.layer.length; i++) + { + var layer = json.layer[i]; + + // A relative filepath to the source image (within Weltmeister) is used for the name + var tilesetName = layer.tilesetName; + + // Only add unique tilesets that have a valid name. Collision layers will have a blank name. + if (tilesetName !== '' && tilesetsNames.indexOf(tilesetName) === -1) + { + tilesetsNames.push(tilesetName); + + // Tiles are stored with an ID relative to the tileset, rather than a globally unique ID + // across all tilesets. Also, tilesets in Weltmeister have no margin or padding. + tilesets.push(new Tileset(tilesetName, 0, layer.tilesize, layer.tilesize, 0, 0)); + } + } + + return tilesets; +}; + +module.exports = ParseTilesets; + + +/***/ }), +/* 576 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var Formats = __webpack_require__(38); +var GetFastValue = __webpack_require__(2); +var LayerData = __webpack_require__(119); +var ORIENTATION = __webpack_require__(29); +var Rotate = __webpack_require__(356); +var SpliceOne = __webpack_require__(74); +var Sprite = __webpack_require__(73); +var Tile = __webpack_require__(83); +var TilemapComponents = __webpack_require__(247); +var TilemapLayer = __webpack_require__(577); +var Tileset = __webpack_require__(121); + +/** + * @callback TilemapFilterCallback + * + * @param {Phaser.GameObjects.GameObject} value - An object found in the filtered area. + * @param {number} index - The index of the object within the array. + * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. + * + * @return {Phaser.GameObjects.GameObject} The object. + */ + +/** + * @callback TilemapFindCallback + * + * @param {Phaser.GameObjects.GameObject} value - An object found. + * @param {number} index - The index of the object within the array. + * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. + * + * @return {boolean} `true` if the callback should be invoked, otherwise `false`. + */ + +/** + * @classdesc + * A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data + * about the map and allows you to add tilesets and tilemap layers to it. A map can have one or + * more tilemap layers, which are the display objects that actually render the tiles. + * + * The Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free + * software package specifically for creating tile maps, and is available from: + * http://www.mapeditor.org + * + * As of Phaser 3.50.0 the Tilemap API now supports the following types of map: + * + * 1) Orthogonal + * 2) Isometric + * 3) Hexagonal + * 4) Staggered + * + * Prior to this release, only orthogonal maps were supported. + * + * Another large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created + * either a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been + * merged and the API simplified, so now there is just the single `TilemapLayer` class. + * + * A Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing + * you to build or modify the tilemap data at runtime. + * + * Note that all Tilemaps use a base tile size to calculate dimensions from, but that a + * TilemapLayer may have its own unique tile size that overrides this. + * + * As of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these + * will be traversed and the following properties will impact children: + * + * - Opacity (blended with parent) and visibility (parent overrides child) + * - Vertical and horizontal offset + * + * The grouping hierarchy is not preserved and all layers will be flattened into a single array. + * + * Group layers are parsed during Tilemap construction but are discarded after parsing so dynamic + * layers will NOT continue to be affected by a parent. + * + * To avoid duplicate layer names, a layer that is a child of a group layer will have its parent + * group name prepended with a '/'. For example, consider a group called 'ParentGroup' with a + * child called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name + * 'ParentGroup/Layer 1'. + * + * @class Tilemap + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. + * @param {Phaser.Tilemaps.MapData} mapData - A MapData instance containing Tilemap data. + */ +var Tilemap = new Class({ + + initialize: + + function Tilemap (scene, mapData) + { + /** + * @name Phaser.Tilemaps.Tilemap#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; + + /** + * The base width of a tile in pixels. Note that individual layers may have a different tile + * width. + * + * @name Phaser.Tilemaps.Tilemap#tileWidth + * @type {number} + * @since 3.0.0 + */ + this.tileWidth = mapData.tileWidth; + + /** + * The base height of a tile in pixels. Note that individual layers may have a different + * tile height. + * + * @name Phaser.Tilemaps.Tilemap#tileHeight + * @type {number} + * @since 3.0.0 + */ + this.tileHeight = mapData.tileHeight; + + /** + * The width of the map (in tiles). + * + * @name Phaser.Tilemaps.Tilemap#width + * @type {number} + * @since 3.0.0 + */ + this.width = mapData.width; + + /** + * The height of the map (in tiles). + * + * @name Phaser.Tilemaps.Tilemap#height + * @type {number} + * @since 3.0.0 + */ + this.height = mapData.height; + + /** + * The orientation of the map data (as specified in Tiled), usually 'orthogonal'. + * + * @name Phaser.Tilemaps.Tilemap#orientation + * @type {string} + * @since 3.0.0 + */ + this.orientation = mapData.orientation; + + /** + * The render (draw) order of the map data (as specified in Tiled), usually 'right-down'. + * + * The draw orders are: + * + * right-down + * left-down + * right-up + * left-up + * + * This can be changed via the `setRenderOrder` method. + * + * @name Phaser.Tilemaps.Tilemap#renderOrder + * @type {string} + * @since 3.12.0 + */ + this.renderOrder = mapData.renderOrder; + + /** + * The format of the map data. + * + * @name Phaser.Tilemaps.Tilemap#format + * @type {number} + * @since 3.0.0 + */ + this.format = mapData.format; + + /** + * The version of the map data (as specified in Tiled, usually 1). + * + * @name Phaser.Tilemaps.Tilemap#version + * @type {number} + * @since 3.0.0 + */ + this.version = mapData.version; + + /** + * Map specific properties as specified in Tiled. + * + * @name Phaser.Tilemaps.Tilemap#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = mapData.properties; + + /** + * The width of the map in pixels based on width * tileWidth. + * + * @name Phaser.Tilemaps.Tilemap#widthInPixels + * @type {number} + * @since 3.0.0 + */ + this.widthInPixels = mapData.widthInPixels; + + /** + * The height of the map in pixels based on height * tileHeight. + * + * @name Phaser.Tilemaps.Tilemap#heightInPixels + * @type {number} + * @since 3.0.0 + */ + this.heightInPixels = mapData.heightInPixels; + + /** + * A collection of Images, as parsed from Tiled map data. + * + * @name Phaser.Tilemaps.Tilemap#imageCollections + * @type {Phaser.Tilemaps.ImageCollection[]} + * @since 3.0.0 + */ + this.imageCollections = mapData.imageCollections; + + /** + * An array of Tiled Image Layers. + * + * @name Phaser.Tilemaps.Tilemap#images + * @type {array} + * @since 3.0.0 + */ + this.images = mapData.images; + + /** + * An array of Tilemap layer data. + * + * @name Phaser.Tilemaps.Tilemap#layers + * @type {Phaser.Tilemaps.LayerData[]} + * @since 3.0.0 + */ + this.layers = mapData.layers; + + /** + * An array of Tilesets used in the map. + * + * @name Phaser.Tilemaps.Tilemap#tilesets + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.0.0 + */ + this.tilesets = mapData.tilesets; + + /** + * An array of ObjectLayer instances parsed from Tiled object layers. + * + * @name Phaser.Tilemaps.Tilemap#objects + * @type {Phaser.Tilemaps.ObjectLayer[]} + * @since 3.0.0 + */ + this.objects = mapData.objects; + + /** + * The index of the currently selected LayerData object. + * + * @name Phaser.Tilemaps.Tilemap#currentLayerIndex + * @type {number} + * @since 3.0.0 + */ + this.currentLayerIndex = 0; + + /** + * The length of the horizontal sides of the hexagon. + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.Tilemap#hexSideLength + * @type {number} + * @since 3.50.0 + */ + this.hexSideLength = mapData.hexSideLength; + + var orientation = this.orientation; + + /** + * Functions used to handle world to tile, and tile to world, conversion. + * Cached here for internal use by public methods such as `worldToTileXY`, etc. + * + * @name Phaser.Tilemaps.Tilemap#_convert + * @private + * @type {object} + * @since 3.50.0 + */ + this._convert = { + WorldToTileXY: TilemapComponents.GetWorldToTileXYFunction(orientation), + WorldToTileX: TilemapComponents.GetWorldToTileXFunction(orientation), + WorldToTileY: TilemapComponents.GetWorldToTileYFunction(orientation), + TileToWorldXY: TilemapComponents.GetTileToWorldXYFunction(orientation), + TileToWorldX: TilemapComponents.GetTileToWorldXFunction(orientation), + TileToWorldY: TilemapComponents.GetTileToWorldYFunction(orientation) + }; + }, + + /** + * @ignore + */ + createBlankDynamicLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) + { + console.warn('createBlankDynamicLayer is deprecated. Use createBlankLayer'); + + return this.createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight); + }, + + /** + * @ignore + */ + createDynamicLayer: function (layerID, tileset, x, y) + { + console.warn('createDynamicLayer is deprecated. Use createLayer'); + + return this.createLayer(layerID, tileset, x, y); + }, + + /** + * @ignore + */ + createStaticLayer: function (layerID, tileset, x, y) + { + console.warn('createStaticLayer is deprecated. Use createLayer'); + + return this.createLayer(layerID, tileset, x, y); + }, + + /** + * Sets the rendering (draw) order of the tiles in this map. + * + * The default is 'right-down', meaning it will order the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * Setting the render order does not change the tiles or how they are stored in the layer, + * it purely impacts the order in which they are rendered. + * + * You can provide either an integer (0 to 3), or the string version of the order. + * + * Calling this method _after_ creating Tilemap Layers will **not** automatically + * update them to use the new render order. If you call this method after creating layers, use their + * own `setRenderOrder` methods to change them as needed. + * + * @method Phaser.Tilemaps.Tilemap#setRenderOrder + * @since 3.12.0 + * + * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. + * + * @return {this} This Tilemap object. + */ + setRenderOrder: function (renderOrder) + { + var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; + + if (typeof renderOrder === 'number') + { + renderOrder = orders[renderOrder]; + } + + if (orders.indexOf(renderOrder) > -1) + { + this.renderOrder = renderOrder; + } + + return this; + }, + + /** + * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. + * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled + * editor. + * + * @method Phaser.Tilemaps.Tilemap#addTilesetImage + * @since 3.0.0 + * + * @param {string} tilesetName - The name of the tileset as specified in the map data. + * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If + * `undefined` or `null` it will look for an image with a key matching the tilesetName parameter. + * @param {number} [tileWidth] - The width of the tile (in pixels) in the Tileset Image. If not + * given it will default to the map's tileWidth value, or the tileWidth specified in the Tiled + * JSON file. + * @param {number} [tileHeight] - The height of the tiles (in pixels) in the Tileset Image. If + * not given it will default to the map's tileHeight value, or the tileHeight specified in the + * Tiled JSON file. + * @param {number} [tileMargin] - The margin around the tiles in the sheet (in pixels). If not + * specified, it will default to 0 or the value specified in the Tiled JSON file. + * @param {number} [tileSpacing] - The spacing between each the tile in the sheet (in pixels). + * If not specified, it will default to 0 or the value specified in the Tiled JSON file. + * @param {number} [gid=0] - If adding multiple tilesets to a blank map, specify the starting + * GID this set will use here. + * + * @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it + * failed. + */ + addTilesetImage: function (tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid) + { + if (tilesetName === undefined) { return null; } + if (key === undefined || key === null) { key = tilesetName; } + + if (!this.scene.sys.textures.exists(key)) + { + console.warn('Invalid Tileset Image: ' + key); + return null; + } + + var texture = this.scene.sys.textures.get(key); + + var index = this.getTilesetIndex(tilesetName); + + if (index === null && this.format === Formats.TILED_JSON) + { + console.warn('No data found for Tileset: ' + tilesetName); + return null; + } + + var tileset = this.tilesets[index]; + + if (tileset) + { + tileset.setTileSize(tileWidth, tileHeight); + tileset.setSpacing(tileMargin, tileSpacing); + tileset.setImage(texture); + + return tileset; + } + + if (tileWidth === undefined) { tileWidth = this.tileWidth; } + if (tileHeight === undefined) { tileHeight = this.tileHeight; } + if (tileMargin === undefined) { tileMargin = 0; } + if (tileSpacing === undefined) { tileSpacing = 0; } + if (gid === undefined) { gid = 0; } + + tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing); + + tileset.setImage(texture); + + this.tilesets.push(tileset); + + return tileset; + }, + + /** + * Copies the tiles in the source rectangular area to a new destination (all specified in tile + * coordinates) within the layer. This copies all tile properties & recalculates collision + * information in the destination region. + * + * If no layer specified, the map's current layer is used. This cannot be applied to StaticTilemapLayers. + * + * @method Phaser.Tilemaps.Tilemap#copy + * @since 3.0.0 + * + * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. + * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. + * @param {number} width - The width of the area to copy, in tiles, not pixels. + * @param {number} height - The height of the area to copy, in tiles, not pixels. + * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. + * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) + { + layer = this.getLayer(layer); + + if (layer !== null) + { + TilemapComponents.Copy( + srcTileX, srcTileY, + width, height, + destTileX, destTileY, + recalculateFaces, layer + ); + + return this; + } + else + { + return null; + } + }, + + /** + * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. + * + * Prior to v3.50.0 this method was called `createBlankDynamicLayer`. + * + * @method Phaser.Tilemaps.Tilemap#createBlankLayer + * @since 3.0.0 + * + * @param {string} name - The name of this layer. Must be unique within the map. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The world x position where the top left of this layer will be placed. + * @param {number} [y=0] - The world y position where the top left of this layer will be placed. + * @param {number} [width] - The width of the layer in tiles. If not specified, it will default to the map's width. + * @param {number} [height] - The height of the layer in tiles. If not specified, it will default to the map's height. + * @param {number} [tileWidth] - The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth. + * @param {number} [tileHeight] - The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight. + * + * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed. + */ + createBlankLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + if (tileWidth === undefined) { tileWidth = this.tileWidth; } + if (tileHeight === undefined) { tileHeight = this.tileHeight; } + + var index = this.getLayerIndex(name); + + if (index !== null) + { + console.warn('Invalid Tilemap Layer ID: ' + name); + return null; + } + + var layerData = new LayerData({ + name: name, + tileWidth: tileWidth, + tileHeight: tileHeight, + width: width, + height: height, + orientation: this.orientation + }); + + var row; + + for (var tileY = 0; tileY < height; tileY++) + { + row = []; + + for (var tileX = 0; tileX < width; tileX++) + { + row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight)); + } + + layerData.data.push(row); + } + + this.layers.push(layerData); + + this.currentLayerIndex = this.layers.length - 1; + + var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y); + + layer.setRenderOrder(this.renderOrder); + + this.scene.sys.displayList.add(layer); + + return layer; + }, + + /** + * Creates a new Tilemap Layer that renders the LayerData associated with the given + * `layerID`. The currently selected layer in the map is set to this new layer. + * + * The `layerID` is important. If you've created your map in Tiled then you can get this by + * looking in Tiled and looking at the layer name. Or you can open the JSON file it exports and + * look at the layers[].name value. Either way it must match. + * + * Prior to v3.50.0 this method was called `createDynamicLayer`. + * + * @method Phaser.Tilemaps.Tilemap#createLayer + * @since 3.0.0 + * + * @param {(number|string)} layerID - The layer array index value, or if a string is given, the layer name from Tiled. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. + * @param {number} [y=0] - The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. + * + * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed. + */ + createLayer: function (layerID, tileset, x, y) + { + var index = this.getLayerIndex(layerID); + + if (index === null) + { + console.warn('Invalid Tilemap Layer ID: ' + layerID); + + if (typeof layerID === 'string') + { + console.warn('Valid tilelayer names:\n\t' + this.getTileLayerNames().join(',\n\t')); + } + + return null; + } + + var layerData = this.layers[index]; + + // Check for an associated static or dynamic tilemap layer + if (layerData.tilemapLayer) + { + console.warn('Tilemap Layer ID already exists:' + layerID); + return null; + } + + this.currentLayerIndex = index; + + // Default the x/y position to match Tiled layer offset, if it exists. + + if (x === undefined) + { + x = layerData.x; + } + + if (y === undefined) + { + y = layerData.y; + } + + var layer = new TilemapLayer(this.scene, this, index, tileset, x, y); + + layer.setRenderOrder(this.renderOrder); + + this.scene.sys.displayList.add(layer); + + return layer; + }, + + /** + * This method will iterate through all of the objects defined in a Tiled Object Layer and then + * convert the matching results into Phaser Game Objects (by default, Sprites) + * + * Objects are matched on one of 3 criteria: The Object ID, the Object GID or the Object Name. + * + * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects + * using the same image. Finally, Object Names are strings and the same name can be used on multiple + * Objects in Tiled, they do not have to be unique. + * + * You set the configuration parameter accordingly, based on which type of criteria you wish + * to match against. For example, to convert all items on an Object Layer with a `gid` of 26: + * + * ```javascript + * createFromObjects(layerName, { + * gid: 26 + * }); + * ``` + * + * Or, to convert objects with the name 'bonus': + * + * ```javascript + * createFromObjects(layerName, { + * name: 'bonus' + * }); + * ``` + * + * Or, to convert an object with a specific id: + * + * ```javascript + * createFromObjects(layerName, { + * id: 9 + * }); + * ``` + * + * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than + * one criteria to your config. If you do not specify any criteria, then _all_ objects in the + * Object Layer will be converted. + * + * By default this method will convert objects into `Sprite` instances, but you can override + * this by providing your own class type: + * + * ```javascript + * createFromObjects(layerName, { + * gid: 26, + * classType: Coin + * }); + * ``` + * + * This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass + * any class type here, but it _must_ extend `Phaser.GameObjects.GameObject` as its base class. + * Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene + * specified in the config object or, if not given, the Scene to which this Tilemap belongs. + * + * All properties from object are copied into the Game Object, so you can use this as an easy + * way to configure properties from within the map editor. For example giving an object a + * property of `alpha: 0.5` in Tiled will be reflected in the Game Object that is created. + * + * Custom object properties that do not exist as a Game Object property are set in the + * Game Objects {@link Phaser.GameObjects.GameObject#data data store}. + * + * You can use set a `container` property in the config. If given, the class will be added to + * the Container instance instead of the Scene. + * + * Finally, you can provide an array of config objects, to convert multiple types of object in + * a single call: + * + * ```javascript + * createFromObjects(layerName, [ + * { + * gid: 26, + * classType: Coin + * }, + * { + * id: 9, + * classType: BossMonster + * }, + * { + * name: 'lava', + * classType: LavaTile + * } + * ]); + * ``` + * + * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. + * + * @method Phaser.Tilemaps.Tilemap#createFromObjects + * @since 3.0.0 + * + * @param {string} objectLayerName - The name of the Tiled object layer to create the Game Objects from. + * @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]} config - A CreateFromObjects configuration object, or an array of them. + * + * @return {Phaser.GameObjects.GameObject[]} An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found. + */ + createFromObjects: function (objectLayerName, config) + { + var results = []; + + var objectLayer = this.getObjectLayer(objectLayerName); + + if (!objectLayer) + { + console.warn('createFromObjects: Invalid objectLayerName given: ' + objectLayerName); + + return results; + } + + if (!Array.isArray(config)) + { + config = [ config ]; + } + + var objects = objectLayer.objects; + + for (var c = 0; c < config.length; c++) + { + var singleConfig = config[c]; + + var id = GetFastValue(singleConfig, 'id', null); + var gid = GetFastValue(singleConfig, 'gid', null); + var name = GetFastValue(singleConfig, 'name', null); + + var obj; + var toConvert = []; + + // Sweep to get all the objects we want to convert in this pass + for (var s = 0; s < objects.length; s++) + { + obj = objects[s]; + + if ( + (id === null && gid === null && name === null) || + (id !== null && obj.id === id) || + (gid !== null && obj.gid === gid) || + (name !== null && obj.name === name) + ) + { + toConvert.push(obj); + } + } + + // Now let's convert them ... + + var classType = GetFastValue(singleConfig, 'classType', Sprite); + var scene = GetFastValue(singleConfig, 'scene', this.scene); + var container = GetFastValue(singleConfig, 'container', null); + var texture = GetFastValue(singleConfig, 'key', null); + var frame = GetFastValue(singleConfig, 'frame', null); + + for (var i = 0; i < toConvert.length; i++) + { + obj = toConvert[i]; + + var sprite = new classType(scene); + + sprite.setName(obj.name); + sprite.setPosition(obj.x, obj.y); + sprite.setTexture(texture, frame); + + if (obj.width) + { + sprite.displayWidth = obj.width; + } + + if (obj.height) + { + sprite.displayHeight = obj.height; + } + + // Origin is (0, 1) in Tiled, so find the offset that matches the Sprites origin. + // Do not offset objects with zero dimensions (e.g. points). + var offset = { + x: sprite.originX * obj.width, + y: (sprite.originY - 1) * obj.height + }; + + // If the object is rotated, then the origin offset also needs to be rotated. + if (obj.rotation) + { + var angle = DegToRad(obj.rotation); + + Rotate(offset, angle); + + sprite.rotation = angle; + } + + sprite.x += offset.x; + sprite.y += offset.y; + + if (obj.flippedHorizontal !== undefined || obj.flippedVertical !== undefined) + { + sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical); + } + + if (!obj.visible) + { + sprite.visible = false; + } + + // Set properties the class may have, or setData those it doesn't + for (var key in obj.properties) + { + if (sprite[key] !== undefined) + { + sprite[key] = obj.properties[key]; + } + else + { + sprite.setData(key, obj.properties[key]); + } + } + + if (container) + { + container.add(sprite); + } + else + { + scene.add.existing(sprite); + } + + results.push(sprite); + } + } + + return results; + }, + + /** + * Creates a Sprite for every object matching the given tile indexes in the layer. You can + * optionally specify if each tile will be replaced with a new tile after the Sprite has been + * created. This is useful if you want to lay down special tiles in a level that are converted to + * Sprites, but want to replace the tile itself with a floor tile or similar once converted. + * + * @method Phaser.Tilemaps.Tilemap#createFromTiles + * @since 3.0.0 + * + * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. + * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted + * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a + * one-to-one mapping with the indexes array. + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} spriteConfig - The config object to pass into the Sprite creator (i.e. scene.make.sprite). + * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.GameObjects.Sprite[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); + }, + + /** + * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the + * specified index. Tiles will be set to collide if the given index is a colliding index. + * Collision information in the region will be recalculated. + * + * If no layer specified, the map's current layer is used. + * This cannot be applied to StaticTilemapLayers. + * + * @method Phaser.Tilemaps.Tilemap#fill + * @since 3.0.0 + * + * @param {number} index - The tile index to fill the area with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); + + return this; + }, + + /** + * For each object in the given object layer, run the given filter callback function. Any + * objects that pass the filter test (i.e. where the callback returns true) will returned as a + * new array. Similar to Array.prototype.Filter in vanilla JS. + * + * @method Phaser.Tilemaps.Tilemap#filterObjects + * @since 3.0.0 + * + * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. + * @param {TilemapFilterCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * + * @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid. + */ + filterObjects: function (objectLayer, callback, context) + { + if (typeof objectLayer === 'string') + { + var name = objectLayer; + + objectLayer = this.getObjectLayer(objectLayer); + + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; + } + } + + return objectLayer.objects.filter(callback, context); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns + * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#filterTiles + * @since 3.0.0 + * + * @param {function} callback - The callback. Each tile in the given area will be passed to this + * callback as the first and only parameter. The callback should return true for tiles that pass the + * filter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * Searches the entire map layer for the first tile matching the given index, then returns that Tile + * object. If no match is found, it returns null. The search starts from the top-left tile and + * continues horizontally until it hits the end of the row, then it drops down to the next column. + * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to + * the top-left. + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#findByIndex + * @since 3.0.0 + * + * @param {number} index - The tile index value to search for. + * @param {number} [skip=0] - The number of times to skip a matching tile before returning. + * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + */ + findByIndex: function (findIndex, skip, reverse, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); + }, + + /** + * Find the first object in the given object layer that satisfies the provided testing function. + * I.e. finds the first object for which `callback` returns true. Similar to + * Array.prototype.find in vanilla JS. + * + * @method Phaser.Tilemaps.Tilemap#findObject + * @since 3.0.0 + * + * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. + * @param {TilemapFindCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * + * @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found. + */ + findObject: function (objectLayer, callback, context) + { + if (typeof objectLayer === 'string') + { + var name = objectLayer; + + objectLayer = this.getObjectLayer(objectLayer); + + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; + } + } + + return objectLayer.objects.find(callback, context) || null; + }, + + /** + * Find the first tile in the given rectangular area (in tile coordinates) of the layer that + * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns + * true. Similar to Array.prototype.find in vanilla JS. + * If no layer specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#findTile + * @since 3.0.0 + * + * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + */ + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * callback. Similar to Array.prototype.forEach in vanilla JS. + * + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#forEachTile + * @since 3.0.0 + * + * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + + return this; + }, + + /** + * Gets the image layer index based on its name. + * + * @method Phaser.Tilemaps.Tilemap#getImageIndex + * @since 3.0.0 + * + * @param {string} name - The name of the image to get. + * + * @return {number} The index of the image in this tilemap, or null if not found. + */ + getImageIndex: function (name) + { + return this.getIndex(this.images, name); + }, + + /** + * Return a list of all valid imagelayer names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getImageLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap. + */ + getImageLayerNames: function () + { + if (!this.images || !Array.isArray(this.images)) + { + return []; + } + + return this.images.map(function (image) + { + return image.name; + }); + }, + + /** + * Internally used. Returns the index of the object in one of the Tilemaps arrays whose name + * property matches the given `name`. + * + * @method Phaser.Tilemaps.Tilemap#getIndex + * @since 3.0.0 + * + * @param {array} location - The Tilemap array to search. + * @param {string} name - The name of the array element to get. + * + * @return {number} The index of the element in the array, or null if not found. + */ + getIndex: function (location, name) + { + for (var i = 0; i < location.length; i++) + { + if (location[i].name === name) + { + return i; + } + } + + return null; + }, + + /** + * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. + * + * @method Phaser.Tilemaps.Tilemap#getLayer + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or Tilemap Layer. If not given will default to the maps current layer index. + * + * @return {Phaser.Tilemaps.LayerData} The corresponding LayerData within this.layers. + */ + getLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + return (index !== null) ? this.layers[index] : null; + }, + + /** + * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. + * + * @method Phaser.Tilemaps.Tilemap#getObjectLayer + * @since 3.0.0 + * + * @param {string} [name] - The name of the object layer from Tiled. + * + * @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null. + */ + getObjectLayer: function (name) + { + var index = this.getIndex(this.objects, name); + + return (index !== null) ? this.objects[index] : null; + }, + + /** + * Return a list of all valid objectgroup names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getObjectLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap. + */ + getObjectLayerNames: function () + { + if (!this.objects || !Array.isArray(this.objects)) + { + return []; + } + + return this.objects.map(function (object) + { + return object.name; + }); + }, + + /** + * Gets the LayerData index of the given `layer` within this.layers, or null if an invalid + * `layer` is given. + * + * @method Phaser.Tilemaps.Tilemap#getLayerIndex + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a Tilemap Layer. If not given will default to the map's current layer index. + * + * @return {number} The LayerData index within this.layers. + */ + getLayerIndex: function (layer) + { + if (layer === undefined) + { + return this.currentLayerIndex; + } + else if (typeof layer === 'string') + { + return this.getLayerIndexByName(layer); + } + else if (typeof layer === 'number' && layer < this.layers.length) + { + return layer; + } + else if (layer instanceof TilemapLayer) + { + return layer.layerIndex; + } + else + { + return null; + } + }, + + /** + * Gets the index of the LayerData within this.layers that has the given `name`, or null if an + * invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getLayerIndexByName + * @since 3.0.0 + * + * @param {string} name - The name of the layer to get. + * + * @return {number} The LayerData index within this.layers. + */ + getLayerIndexByName: function (name) + { + return this.getIndex(this.layers, name); + }, + + /** + * Gets a tile at the given tile coordinates from the given layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTileAt + * @since 3.0.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {boolean} [nonNull] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + getTileAt: function (tileX, tileY, nonNull, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); + }, + + /** + * Gets a tile at the given world coordinates from the given layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - X position to get the tile from (given in pixels) + * @param {number} worldY - Y position to get the tile from (given in pixels) + * @param {boolean} [nonNull] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); + }, + + /** + * Return a list of all valid tilelayer names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getTileLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap. + */ + getTileLayerNames: function () + { + if (!this.layers || !Array.isArray(this.layers)) + { + return []; + } + + return this.layers.map(function (layer) + { + return layer.name; + }); + }, + + /** + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithin + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithin: function (tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, + * Line, Rectangle or Triangle. The shape should be in world coordinates. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithinShape + * @since 3.0.0 + * + * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithinShape: function (shape, filteringOptions, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); + }, + + /** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); + }, + + /** + * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getTileset + * @since 3.14.0 + * + * @param {string} name - The name of the Tileset to get. + * + * @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found. + */ + getTileset: function (name) + { + var index = this.getIndex(this.tilesets, name); + + return (index !== null) ? this.tilesets[index] : null; + }, + + /** + * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an + * invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getTilesetIndex + * @since 3.0.0 + * + * @param {string} name - The name of the Tileset to get. + * + * @return {number} The Tileset index within this.tilesets. + */ + getTilesetIndex: function (name) + { + return this.getIndex(this.tilesets, name); + }, + + /** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#hasTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ + hasTileAt: function (tileX, tileY, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.HasTileAt(tileX, tileY, layer); + }, + + /** + * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ + hasTileAtWorldXY: function (worldX, worldY, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); + }, + + /** + * The LayerData object that is currently selected in the map. You can set this property using + * any type supported by setLayer. + * + * @name Phaser.Tilemaps.Tilemap#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.0.0 + */ + layer: { + get: function () + { + return this.layers[this.currentLayerIndex]; + }, + + set: function (layer) + { + this.setLayer(layer); + } + }, + + /** + * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index + * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified + * location. If you pass in an index, only the index at the specified location will be changed. + * Collision information will be recalculated at the specified location. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTileAt + * @since 3.0.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid or the coordinates were out of bounds. + */ + putTileAt: function (tile, tileX, tileY, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer); + }, + + /** + * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either + * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the + * specified location. If you pass in an index, only the index at the specified location will be + * changed. Collision information will be recalculated at the specified location. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTileAtWorldXY + * @since 3.0.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer); + }, + + /** + * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified + * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, + * all attributes will be copied over to the specified location. If you pass in an index, only the + * index at the specified location will be changed. Collision information will be recalculated + * within the region tiles were changed. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTilesAt + * @since 3.0.0 + * + * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer); + + return this; + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then + * those will be used for randomly assigning new tile indexes. If an array is not provided, the + * indexes found within the region (excluding -1) will be used for randomly assigning new tile + * indexes. This method only modifies tile indexes and does not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#randomize + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + randomize: function (tileX, tileY, width, height, indexes, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer); + + return this; + }, + + /** + * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting + * faces are used internally for optimizing collisions against tiles. This method is mostly used + * internally to optimize recalculating faces when only one tile has been changed. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#calculateFacesAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + calculateFacesAt: function (tileX, tileY, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.CalculateFacesAt(tileX, tileY, layer); + + return this; + }, + + /** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#calculateFacesWithin + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + calculateFacesWithin: function (tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Removes the given TilemapLayer from this Tilemap without destroying it. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeLayer + * @since 3.17.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be removed. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + removeLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + SpliceOne(this.layers, index); + + for (var i = index; i < this.layers.length; i++) + { + if (this.layers[i].tilemapLayer) + { + this.layers[i].tilemapLayer.layerIndex--; + } + } + + if (this.currentLayerIndex === index) + { + this.currentLayerIndex = 0; + } + + return this; + } + else + { + return null; + } + }, + + /** + * Destroys the given TilemapLayer and removes it from this Tilemap. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#destroyLayer + * @since 3.17.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be destroyed. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + destroyLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + layer = this.layers[index]; + + layer.destroy(); + + SpliceOne(this.layers, index); + + if (this.currentLayerIndex === index) + { + this.currentLayerIndex = 0; + } + + return this; + } + else + { + return null; + } + }, + + /** + * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. + * + * @method Phaser.Tilemaps.Tilemap#removeAllLayers + * @since 3.0.0 + * + * @return {this} This Tilemap object. + */ + removeAllLayers: function () + { + var layers = this.layers; + + for (var i = 0; i < layers.length; i++) + { + if (layers[i].tilemapLayer) + { + layers[i].tilemapLayer.destroy(false); + } + } + + layers.length = 0; + + this.currentLayerIndex = 0; + + return this; + }, + + /** + * Removes the given Tile, or an array of Tiles, from the layer to which they belong, + * and optionally recalculates the collision information. + * + * @method Phaser.Tilemaps.Tilemap#removeTile + * @since 3.17.0 + * + * @param {(Phaser.Tilemaps.Tile|Phaser.Tilemaps.Tile[])} tiles - The Tile to remove, or an array of Tiles. + * @param {number} [replaceIndex=-1] - After removing the Tile, insert a brand new Tile into its location with the given index. Leave as -1 to just remove the tile. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed. + */ + removeTile: function (tiles, replaceIndex, recalculateFaces) + { + if (replaceIndex === undefined) { replaceIndex = -1; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + var removed = []; + + if (!Array.isArray(tiles)) + { + tiles = [ tiles ]; + } + + for (var i = 0; i < tiles.length; i++) + { + var tile = tiles[i]; + + removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); + + if (replaceIndex > -1) + { + this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); + } + } + + return removed; + }, + + /** + * Removes the tile at the given tile coordinates in the specified layer and updates the layers collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns the Tile that was removed, or null if the layer given was invalid. + */ + removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces, layer) + { + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); + }, + + /** + * Removes the tile at the given world coordinates in the specified layer and updates the layers collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) + { + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); + }, + + /** + * Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to + * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles + * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation + * wherever you want on the screen. + * + * If no layer is specified, the maps current layer is used. + * + * **Note:** This method currently only works with orthogonal tilemap layers. + * + * @method Phaser.Tilemaps.Tilemap#renderDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + renderDebug: function (graphics, styleConfig, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + if (this.orientation === ORIENTATION.ORTHOGONAL) + { + TilemapComponents.RenderDebug(graphics, styleConfig, layer); + } + + return this; + }, + + /** + * Draws a debug representation of all layers within this Tilemap to the given Graphics object. + * + * This is helpful when you want to get a quick idea of which of your tiles are colliding and which + * have interesting faces. The tiles are drawn starting at (0, 0) in the Graphics, allowing you to + * place the debug representation wherever you want on the screen. + * + * @method Phaser.Tilemaps.Tilemap#renderDebugFull + * @since 3.17.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * + * @return {this} This Tilemap instance. + */ + renderDebugFull: function (graphics, styleConfig) + { + var layers = this.layers; + + for (var i = 0; i < layers.length; i++) + { + TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); + } + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#replaceByIndex + * @since 3.0.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Sets collision on the given tile or tiles within a layer by index. You can pass in either a + * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if + * collision will be enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollision + * @since 3.0.0 + * + * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollision: function (indexes, collides, recalculateFaces, layer, updateLayer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + if (updateLayer === undefined) { updateLayer = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); + + return this; + }, + + /** + * Sets collision on a range of tiles in a layer whose index is between the specified `start` and + * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set + * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be + * enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionBetween + * @since 3.0.0 + * + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property + * that matches the given properties object, its collision flag will be set. The `collides` + * parameter controls if collision will be enabled (true) or disabled (false). Passing in + * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that + * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can + * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a + * "types" property that matches any of those values, its collision flag will be updated. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionByProperty + * @since 3.0.0 + * + * @param {object} properties - An object with tile properties and corresponding values that should be checked. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionByProperty: function (properties, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on all tiles in the given layer, except for tiles that have an index specified in + * the given array. The `collides` parameter controls if collision will be enabled (true) or + * disabled (false). Tile indexes not currently in the layer are not affected. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion + * @since 3.0.0 + * + * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionByExclusion: function (indexes, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking each tiles collision group data + * (typically defined in Tiled within the tileset collision editor). If any objects are found within + * a tiles collision group, the tiles colliding information will be set. The `collides` parameter + * controls if collision will be enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup + * @since 3.0.0 + * + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionFromCollisionGroup: function (collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all + * tiles on this layer that have the same index. If a callback is already set for the tile index it + * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile + * at a specific location on the map then see `setTileLocationCallback`. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setTileIndexCallback + * @since 3.0.0 + * + * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. All values should be integers. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setTileIndexCallback: function (indexes, callback, callbackContext, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer); + + return this; + }, + + /** + * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to + * remove it. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setTileLocationCallback + * @since 3.0.0 + * + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} [callbackContext] - The context under which the callback is called. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); + + return this; + }, + + /** + * Sets the current layer to the LayerData associated with `layer`. + * + * @method Phaser.Tilemaps.Tilemap#setLayer + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. + * + * @return {this} This Tilemap object. + */ + setLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + this.currentLayerIndex = index; + } + + return this; + }, + + /** + * Sets the base tile size for the map. Note: this does not necessarily match the tileWidth and + * tileHeight for all layers. This also updates the base size on all tiles across all layers. + * + * @method Phaser.Tilemaps.Tilemap#setBaseTileSize + * @since 3.0.0 + * + * @param {number} tileWidth - The width of the tiles the map uses for calculations. + * @param {number} tileHeight - The height of the tiles the map uses for calculations. + * + * @return {this} This Tilemap object. + */ + setBaseTileSize: function (tileWidth, tileHeight) + { + this.tileWidth = tileWidth; + this.tileHeight = tileHeight; + this.widthInPixels = this.width * tileWidth; + this.heightInPixels = this.height * tileHeight; + + // Update the base tile size on all layers & tiles + for (var i = 0; i < this.layers.length; i++) + { + this.layers[i].baseTileWidth = tileWidth; + this.layers[i].baseTileHeight = tileHeight; + + var mapData = this.layers[i].data; + var mapWidth = this.layers[i].width; + var mapHeight = this.layers[i].height; + + for (var row = 0; row < mapHeight; row++) + { + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; + + if (tile !== null) + { + tile.setSize(undefined, undefined, tileWidth, tileHeight); + } + } + } + } + + return this; + }, + + /** + * Sets the tile size for a specific `layer`. Note: this does not necessarily match the maps + * tileWidth and tileHeight for all layers. This will set the tile size for the layer and any + * tiles the layer has. + * + * @method Phaser.Tilemaps.Tilemap#setLayerTileSize + * @since 3.0.0 + * + * @param {number} tileWidth - The width of the tiles (in pixels) in the layer. + * @param {number} tileHeight - The height of the tiles (in pixels) in the layer. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. + * + * @return {this} This Tilemap object. + */ + setLayerTileSize: function (tileWidth, tileHeight, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return this; } + + layer.tileWidth = tileWidth; + layer.tileHeight = tileHeight; + + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + + for (var row = 0; row < mapHeight; row++) + { + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; + + if (tile !== null) + { + tile.setSize(tileWidth, tileHeight); + } + } + } + + return this; + }, + + /** + * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given + * layer. It will only randomize the tiles in that area, so if they're all the same nothing will + * appear to have changed! This method only modifies tile indexes and does not change collision + * information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#shuffle + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + shuffle: function (tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Shuffle(tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision + * information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#swapByIndex + * @since 3.0.0 + * + * @param {number} tileA - First tile index. + * @param {number} tileB - Second tile index. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + swapByIndex: function (indexA, indexB, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldX + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + tileToWorldX: function (tileX, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldX(tileX, camera, layer); + }, + + /** + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldY + * @since 3.0.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + tileToWorldY: function (tileX, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldY(tileX, camera, layer); + }, + + /** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldXY + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid. + */ + tileToWorldXY: function (tileX, tileY, vec2, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. New indexes are drawn from the given + * weightedIndexes array. An example weighted array: + * + * [ + * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 + * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 + * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 + * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 + * ] + * + * The probability of any index being picked is (the indexs weight) / (sum of all weights). This + * method only modifies tile indexes and does not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#weightedRandomize + * @since 3.0.0 + * + * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); + + return this; + }, + + /** + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileX + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + worldToTileX: function (worldX, snapToFloor, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); + }, + + /** + * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileY + * @since 3.0.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + worldToTileY: function (worldY, snapToFloor, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); + }, + + /** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid. + */ + worldToTileXY: function (worldX, worldY, snapToFloor, vec2, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); + }, + + /** + * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any + * TilemapLayers that have been created. + * + * @method Phaser.Tilemaps.Tilemap#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.removeAllLayers(); + + this.tilesets.length = 0; + this.objects.length = 0; + + this.scene = null; + } + +}); + +module.exports = Tilemap; + + +/***/ }), +/* 577 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var GameObject = __webpack_require__(15); +var TilemapComponents = __webpack_require__(247); +var TilemapLayerRender = __webpack_require__(1449); + +/** + * @classdesc + * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination + * with one, or more, Tilesets. + * + * @class TilemapLayer + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.50.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. + * @param {Phaser.Tilemaps.Tilemap} tilemap - The Tilemap this layer is a part of. + * @param {number} layerIndex - The index of the LayerData associated with this layer. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The world x position where the top left of this layer will be placed. + * @param {number} [y=0] - The world y position where the top left of this layer will be placed. + */ +var TilemapLayer = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.ComputedSize, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Origin, + Components.Pipeline, + Components.Transform, + Components.Visible, + Components.ScrollFactor, + TilemapLayerRender + ], + + initialize: + + function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) + { + GameObject.call(this, scene, 'TilemapLayer'); + + /** + * Used internally by physics system to perform fast type checks. + * + * @name Phaser.Tilemaps.TilemapLayer#isTilemap + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.isTilemap = true; + + /** + * The Tilemap that this layer is a part of. + * + * @name Phaser.Tilemaps.TilemapLayer#tilemap + * @type {Phaser.Tilemaps.Tilemap} + * @since 3.50.0 + */ + this.tilemap = tilemap; + + /** + * The index of the LayerData associated with this layer. + * + * @name Phaser.Tilemaps.TilemapLayer#layerIndex + * @type {number} + * @since 3.50.0 + */ + this.layerIndex = layerIndex; + + /** + * The LayerData associated with this layer. LayerData can only be associated with one + * tilemap layer. + * + * @name Phaser.Tilemaps.TilemapLayer#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.50.0 + */ + this.layer = tilemap.layers[layerIndex]; + + // Link the LayerData with this static tilemap layer + this.layer.tilemapLayer = this; + + /** + * An array of `Tileset` objects associated with this layer. + * + * @name Phaser.Tilemaps.TilemapLayer#tileset + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 + */ + this.tileset = []; + + /** + * The total number of tiles drawn by the renderer in the last frame. + * + * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.tilesDrawn = 0; + + /** + * The total number of tiles in this layer. Updated every frame. + * + * @name Phaser.Tilemaps.TilemapLayer#tilesTotal + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.tilesTotal = this.layer.width * this.layer.height; + + /** + * Used internally during rendering. This holds the tiles that are visible within the Camera. + * + * @name Phaser.Tilemaps.TilemapLayer#culledTiles + * @type {Phaser.Tilemaps.Tile[]} + * @since 3.50.0 + */ + this.culledTiles = []; + + /** + * You can control if the camera should cull tiles on this layer before rendering them or not. + * + * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. + * + * However, there are some instances when you may wish to disable this, and toggling this flag allows + * you to do so. Also see `setSkipCull` for a chainable method that does the same thing. + * + * @name Phaser.Tilemaps.TilemapLayer#skipCull + * @type {boolean} + * @since 3.50.0 + */ + this.skipCull = false; + + /** + * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. + * + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX + * @type {number} + * @default 1 + * @since 3.50.0 + */ + this.cullPaddingX = 1; + + /** + * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. + * + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY + * @type {number} + * @default 1 + * @since 3.50.0 + */ + this.cullPaddingY = 1; + + /** + * The callback that is invoked when the tiles are culled. + * + * It will call a different function based on the map orientation: + * + * Orthogonal (the default) is `TilemapComponents.CullTiles` + * Isometric is `TilemapComponents.IsometricCullTiles` + * Hexagonal is `TilemapComponents.HexagonalCullTiles` + * Staggered is `TilemapComponents.StaggeredCullTiles` + * + * However, you can override this to call any function you like. + * + * It will be sent 4 arguments: + * + * 1. The Phaser.Tilemaps.LayerData object for this Layer + * 2. The Camera that is culling the layer. You can check its `dirty` property to see if it has changed since the last cull. + * 3. A reference to the `culledTiles` array, which should be used to store the tiles you want rendered. + * 4. The Render Order constant. + * + * See the `TilemapComponents.CullTiles` source code for details on implementing your own culling system. + * + * @name Phaser.Tilemaps.TilemapLayer#cullCallback + * @type {function} + * @since 3.50.0 + */ + this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); + + /** + * The rendering (draw) order of the tiles in this layer. + * + * The default is 0 which is 'right-down', meaning it will draw the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * This can be changed via the `setRenderOrder` method. + * + * @name Phaser.Tilemaps.TilemapLayer#_renderOrder + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + this._renderOrder = 0; + + /** + * An array holding the mapping between the tile indexes and the tileset they belong to. + * + * @name Phaser.Tilemaps.TilemapLayer#gidMap + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 + */ + this.gidMap = []; + + this.setTilesets(tileset); + this.setAlpha(this.layer.alpha); + this.setPosition(x, y); + this.setOrigin(); + this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height); + + this.initPipeline(); + }, + + /** + * Populates the internal `tileset` array with the Tileset references this Layer requires for rendering. + * + * @method Phaser.Tilemaps.TilemapLayer#setTilesets + * @private + * @since 3.50.0 + * + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + */ + setTilesets: function (tilesets) + { + var gidMap = []; + var setList = []; + var map = this.tilemap; + + if (!Array.isArray(tilesets)) + { + tilesets = [ tilesets ]; + } + + for (var i = 0; i < tilesets.length; i++) + { + var tileset = tilesets[i]; + + if (typeof tileset === 'string') + { + tileset = map.getTileset(tileset); + } + + if (tileset) + { + setList.push(tileset); + + var s = tileset.firstgid; + + for (var t = 0; t < tileset.total; t++) + { + gidMap[s + t] = tileset; + } + } + } + + this.gidMap = gidMap; + this.tileset = setList; + }, + + /** + * Sets the rendering (draw) order of the tiles in this layer. + * + * The default is 'right-down', meaning it will order the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * Setting the render order does not change the tiles or how they are stored in the layer, + * it purely impacts the order in which they are rendered. + * + * You can provide either an integer (0 to 3), or the string version of the order. + * + * @method Phaser.Tilemaps.TilemapLayer#setRenderOrder + * @since 3.50.0 + * + * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. + * + * @return {this} This Tilemap Layer object. + */ + setRenderOrder: function (renderOrder) + { + var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; + + if (typeof renderOrder === 'string') + { + renderOrder = orders.indexOf(renderOrder); + } + + if (renderOrder >= 0 && renderOrder < 4) + { + this._renderOrder = renderOrder; + } + + return this; + }, + + /** + * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting + * faces are used internally for optimizing collisions against tiles. This method is mostly used + * internally to optimize recalculating faces when only one tile has been changed. + * + * @method Phaser.Tilemaps.TilemapLayer#calculateFacesAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate. + * @param {number} tileY - The y coordinate. + * + * @return {this} This Tilemap Layer object. + */ + calculateFacesAt: function (tileX, tileY) + { + TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer); + + return this; + }, + + /** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + calculateFacesWithin: function (tileX, tileY, width, height) + { + TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Creates a Sprite for every object matching the given tile indexes in the layer. You can + * optionally specify if each tile will be replaced with a new tile after the Sprite has been + * created. This is useful if you want to lay down special tiles in a level that are converted to + * Sprites, but want to replace the tile itself with a floor tile or similar once converted. + * + * @method Phaser.Tilemaps.TilemapLayer#createFromTiles + * @since 3.50.0 + * + * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. + * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted + * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a + * one-to-one mapping with the indexes array. + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e. + * scene.make.sprite). + * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when determining the world XY + * + * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. + */ + createFromTiles: function (indexes, replacements, spriteConfig, scene, camera) + { + return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer); + }, + + /** + * Returns the tiles in the given layer that are within the cameras viewport. + * This is used internally during rendering. + * + * @method Phaser.Tilemaps.TilemapLayer#cull + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render. + */ + cull: function (camera) + { + return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder); + }, + + /** + * Copies the tiles in the source rectangular area to a new destination (all specified in tile + * coordinates) within the layer. This copies all tile properties & recalculates collision + * information in the destination region. + * + * @method Phaser.Tilemaps.TilemapLayer#copy + * @since 3.50.0 + * + * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. + * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. + * @param {number} width - The width of the area to copy, in tiles, not pixels. + * @param {number} height - The height of the area to copy, in tiles, not pixels. + * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. + * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) + { + TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the + * specified index. Tiles will be set to collide if the given index is a colliding index. + * Collision information in the region will be recalculated. + * + * @method Phaser.Tilemaps.TilemapLayer#fill + * @since 3.50.0 + * + * @param {number} index - The tile index to fill the area with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + fill: function (index, tileX, tileY, width, height, recalculateFaces) + { + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); + + return this; + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns + * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#filterTiles + * @since 3.50.0 + * + * @param {function} callback - The callback. Each tile in the given area will be passed to this + * callback as the first and only parameter. The callback should return true for tiles that pass the + * filter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ + filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * Searches the entire map layer for the first tile matching the given index, then returns that Tile + * object. If no match is found, it returns null. The search starts from the top-left tile and + * continues horizontally until it hits the end of the row, then it drops down to the next column. + * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to + * the top-left. + * + * @method Phaser.Tilemaps.TilemapLayer#findByIndex + * @since 3.50.0 + * + * @param {number} index - The tile index value to search for. + * @param {number} [skip=0] - The number of times to skip a matching tile before returning. + * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. + * + * @return {Phaser.Tilemaps.Tile} The first matching Tile object. + */ + findByIndex: function (findIndex, skip, reverse) + { + return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer); + }, + + /** + * Find the first tile in the given rectangular area (in tile coordinates) of the layer that + * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns + * true. Similar to Array.prototype.find in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#findTile + * @since 3.50.0 + * + * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location. + */ + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * callback. Similar to Array.prototype.forEach in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#forEachTile + * @since 3.50.0 + * + * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context, or scope, under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {this} This Tilemap Layer object. + */ + forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + + return this; + }, + + /** + * Gets a tile at the given tile coordinates from the given layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTileAt + * @since 3.50.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {boolean} [nonNull=false] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. + * + * @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid. + */ + getTileAt: function (tileX, tileY, nonNull) + { + return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer); + }, + + /** + * Gets a tile at the given world coordinates from the given layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - X position to get the tile from (given in pixels) + * @param {number} worldY - Y position to get the tile from (given in pixels) + * @param {boolean} [nonNull=false] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. + */ + getTileAtWorldXY: function (worldX, worldY, nonNull, camera) + { + return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer); + }, + + /** + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + */ + getTilesWithin: function (tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, + * Line, Rectangle or Triangle. The shape should be in world coordinates. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape + * @since 3.50.0 + * + * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. + */ + getTilesWithinShape: function (shape, filteringOptions, camera) + { + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); + }, + + /** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + */ + getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera) + { + return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer); + }, + + /** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @method Phaser.Tilemaps.TilemapLayer#hasTileAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * + * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + */ + hasTileAt: function (tileX, tileY) + { + return TilemapComponents.HasTileAt(tileX, tileY, this.layer); + }, + + /** + * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + */ + hasTileAtWorldXY: function (worldX, worldY, camera) + { + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); + }, + + /** + * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index + * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified + * location. If you pass in an index, only the index at the specified location will be changed. + * Collision information will be recalculated at the specified location. + * + * @method Phaser.Tilemaps.TilemapLayer#putTileAt + * @since 3.50.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + */ + putTileAt: function (tile, tileX, tileY, recalculateFaces) + { + return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer); + }, + + /** + * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either + * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the + * specified location. If you pass in an index, only the index at the specified location will be + * changed. Collision information will be recalculated at the specified location. + * + * @method Phaser.Tilemaps.TilemapLayer#putTileAtWorldXY + * @since 3.50.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + */ + putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera) + { + return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer); + }, + + /** + * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified + * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, + * all attributes will be copied over to the specified location. If you pass in an index, only the + * index at the specified location will be changed. Collision information will be recalculated + * within the region tiles were changed. + * + * @method Phaser.Tilemaps.TilemapLayer#putTilesAt + * @since 3.50.0 + * + * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces) + { + TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer); + + return this; + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then + * those will be used for randomly assigning new tile indexes. If an array is not provided, the + * indexes found within the region (excluding -1) will be used for randomly assigning new tile + * indexes. This method only modifies tile indexes and does not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#randomize + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. + * + * @return {this} This Tilemap Layer object. + */ + randomize: function (tileX, tileY, width, height, indexes) + { + TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); + + return this; + }, + + /** + * Removes the tile at the given tile coordinates in the specified layer and updates the layers + * collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#removeTileAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile} A Tile object. + */ + removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces) + { + return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer); + }, + + /** + * Removes the tile at the given world coordinates in the specified layer and updates the layers + * collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location. + */ + removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera) + { + return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer); + }, + + /** + * Draws a debug representation of the layer to the given Graphics. This is helpful when you want to + * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles + * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation + * wherever you want on the screen. + * + * @method Phaser.Tilemaps.TilemapLayer#renderDebug + * @since 3.50.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * + * @return {this} This Tilemap Layer object. + */ + renderDebug: function (graphics, styleConfig) + { + TilemapComponents.RenderDebug(graphics, styleConfig, this.layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#replaceByIndex + * @since 3.50.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height) + { + TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * You can control if the Cameras should cull tiles before rendering them or not. + * + * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. + * + * However, there are some instances when you may wish to disable this. + * + * @method Phaser.Tilemaps.TilemapLayer#setSkipCull + * @since 3.50.0 + * + * @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again. + * + * @return {this} This Tilemap Layer object. + */ + setSkipCull: function (value) + { + if (value === undefined) { value = true; } + + this.skipCull = value; + + return this; + }, + + /** + * When a Camera culls the tiles in this layer it does so using its view into the world, building up a + * rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size + * of this 'cull rectangle', especially if you plan on rotating the Camera viewing the layer. Do so + * by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px + * and you set `paddingX` to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale) + * + * @method Phaser.Tilemaps.TilemapLayer#setCullPadding + * @since 3.50.0 + * + * @param {number} [paddingX=1] - The amount of extra horizontal tiles to add to the cull check padding. + * @param {number} [paddingY=1] - The amount of extra vertical tiles to add to the cull check padding. + * + * @return {this} This Tilemap Layer object. + */ + setCullPadding: function (paddingX, paddingY) + { + if (paddingX === undefined) { paddingX = 1; } + if (paddingY === undefined) { paddingY = 1; } + + this.cullPaddingX = paddingX; + this.cullPaddingY = paddingY; + + return this; + }, + + /** + * Sets collision on the given tile or tiles within a layer by index. You can pass in either a + * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if + * collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollision + * @since 3.50.0 + * + * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. + * + * @return {this} This Tilemap Layer object. + */ + setCollision: function (indexes, collides, recalculateFaces, updateLayer) + { + TilemapComponents.SetCollision(indexes, collides, recalculateFaces, this.layer, updateLayer); + + return this; + }, + + /** + * Sets collision on a range of tiles in a layer whose index is between the specified `start` and + * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set + * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be + * enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween + * @since 3.50.0 + * + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionBetween: function (start, stop, collides, recalculateFaces) + { + TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property + * that matches the given properties object, its collision flag will be set. The `collides` + * parameter controls if collision will be enabled (true) or disabled (false). Passing in + * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that + * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can + * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a + * "types" property that matches any of those values, its collision flag will be updated. + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionByProperty + * @since 3.50.0 + * + * @param {object} properties - An object with tile properties and corresponding values that should be checked. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionByProperty: function (properties, collides, recalculateFaces) + { + TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on all tiles in the given layer, except for tiles that have an index specified in + * the given array. The `collides` parameter controls if collision will be enabled (true) or + * disabled (false). Tile indexes not currently in the layer are not affected. + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion + * @since 3.50.0 + * + * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionByExclusion: function (indexes, collides, recalculateFaces) + { + TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking each tiles collision group data + * (typically defined in Tiled within the tileset collision editor). If any objects are found within + * a tiles collision group, the tile's colliding information will be set. The `collides` parameter + * controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup + * @since 3.50.0 + * + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionFromCollisionGroup: function (collides, recalculateFaces) + { + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all + * tiles on this layer that have the same index. If a callback is already set for the tile index it + * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile + * at a specific location on the map then see setTileLocationCallback. + * + * @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback + * @since 3.50.0 + * + * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * + * @return {this} This Tilemap Layer object. + */ + setTileIndexCallback: function (indexes, callback, callbackContext) + { + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer); + + return this; + }, + + /** + * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to + * remove it. + * + * @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {function} [callback] - The callback that will be invoked when the tile is collided with. + * @param {object} [callbackContext] - The context, or scope, under which the callback is invoked. + * + * @return {this} This Tilemap Layer object. + */ + setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext) + { + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer); + + return this; + }, + + /** + * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given + * layer. It will only randomize the tiles in that area, so if they're all the same nothing will + * appear to have changed! This method only modifies tile indexes and does not change collision + * information. + * + * @method Phaser.Tilemaps.TilemapLayer#shuffle + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + shuffle: function (tileX, tileY, width, height) + { + TilemapComponents.Shuffle(tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision + * information. + * + * @method Phaser.Tilemaps.TilemapLayer#swapByIndex + * @since 3.50.0 + * + * @param {number} tileA - First tile index. + * @param {number} tileB - Second tile index. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + swapByIndex: function (indexA, indexB, tileX, tileY, width, height) + { + TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldX + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The Tile X coordinate converted to pixels. + */ + tileToWorldX: function (tileX, camera) + { + return this.tilemap.tileToWorldX(tileX, camera, this); + }, + + /** + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The Tile Y coordinate converted to pixels. + */ + tileToWorldY: function (tileY, camera) + { + return this.tilemap.tileToWorldY(tileY, camera, this); + }, + + /** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Math.Vector2} A Vector2 containing the world coordinates of the Tile. + */ + tileToWorldXY: function (tileX, tileY, point, camera) + { + return this.tilemap.tileToWorldXY(tileX, tileY, point, camera, this); + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. New indexes are drawn from the given + * weightedIndexes array. An example weighted array: + * + * [ + * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 + * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 + * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 + * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 + * ] + * + * The probability of any index being choose is (the index's weight) / (sum of all weights). This + * method only modifies tile indexes and does not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#weightedRandomize + * @since 3.50.0 + * + * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + weightedRandomize: function (tileX, tileY, width, height, weightedIndexes) + { + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); + + return this; + }, + + /** + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileX + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The tile X coordinate based on the world value. + */ + worldToTileX: function (worldX, snapToFloor, camera) + { + return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this); + }, + + /** + * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The tile Y coordinate based on the world value. + */ + worldToTileY: function (worldY, snapToFloor, camera) + { + return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); + }, + + /** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values. + */ + worldToTileXY: function (worldX, worldY, snapToFloor, point, camera) + { + return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this); + }, + + /** + * Destroys this TilemapLayer and removes its link to the associated LayerData. + * + * @method Phaser.Tilemaps.TilemapLayer#destroy + * @since 3.50.0 + * + * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? + */ + destroy: function (removeFromTilemap) + { + if (removeFromTilemap === undefined) { removeFromTilemap = true; } + + if (!this.tilemap) + { + // Abort, we've already been destroyed + return; + } + + // Uninstall this layer only if it is still installed on the LayerData object + if (this.layer.tilemapLayer === this) + { + this.layer.tilemapLayer = undefined; + } + + if (removeFromTilemap) + { + this.tilemap.removeLayer(this); + } + + this.tilemap = undefined; + this.layer = undefined; + this.culledTiles.length = 0; + this.cullCallback = null; + + this.gidMap = []; + this.tileset = []; + + GameObject.prototype.destroy.call(this); + } + +}); + +module.exports = TilemapLayer; + + +/***/ }), +/* 578 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * A Timer Event represents a delayed function call. It's managed by a Scene's {@link Clock} and will call its function after a set amount of time has passed. The Timer Event can optionally repeat - i.e. call its function multiple times before finishing, or loop indefinitely. + * + * Because it's managed by a Clock, a Timer Event is based on game time, will be affected by its Clock's time scale, and will pause if its Clock pauses. + * + * @class TimerEvent + * @memberof Phaser.Time + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Time.TimerEventConfig} config - The configuration for the Timer Event, including its delay and callback. + */ +var TimerEvent = new Class({ + + initialize: + + function TimerEvent (config) + { + /** + * The delay in ms at which this TimerEvent fires. + * + * @name Phaser.Time.TimerEvent#delay + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 + */ + this.delay = 0; + + /** + * The total number of times this TimerEvent will repeat before finishing. + * + * @name Phaser.Time.TimerEvent#repeat + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 + */ + this.repeat = 0; + + /** + * If repeating this contains the current repeat count. + * + * @name Phaser.Time.TimerEvent#repeatCount + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatCount = 0; + + /** + * True if this TimerEvent loops, otherwise false. + * + * @name Phaser.Time.TimerEvent#loop + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.loop = false; + + /** + * The callback that will be called when the TimerEvent occurs. + * + * @name Phaser.Time.TimerEvent#callback + * @type {function} + * @since 3.0.0 + */ + this.callback; + + /** + * The scope in which the callback will be called. + * + * @name Phaser.Time.TimerEvent#callbackScope + * @type {object} + * @since 3.0.0 + */ + this.callbackScope; + + /** + * Additional arguments to be passed to the callback. + * + * @name Phaser.Time.TimerEvent#args + * @type {array} + * @since 3.0.0 + */ + this.args; + + /** + * Scale the time causing this TimerEvent to update. + * + * @name Phaser.Time.TimerEvent#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly) + * + * @name Phaser.Time.TimerEvent#startAt + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.startAt = 0; + + /** + * The time in milliseconds which has elapsed since the Timer Event's creation. + * + * This value is local for the Timer Event and is relative to its Clock. As such, it's influenced by the Clock's time scale and paused state, the Timer Event's initial {@link #startAt} property, and the Timer Event's {@link #timeScale} and {@link #paused} state. + * + * @name Phaser.Time.TimerEvent#elapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.elapsed = 0; + + /** + * Whether or not this timer is paused. + * + * @name Phaser.Time.TimerEvent#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + /** + * Whether the Timer Event's function has been called. + * + * When the Timer Event fires, this property will be set to `true` before the callback function is invoked and will be reset immediately afterward if the Timer Event should repeat. The value of this property does not directly influence whether the Timer Event will be removed from its Clock, but can prevent it from firing. + * + * @name Phaser.Time.TimerEvent#hasDispatched + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.hasDispatched = false; + + this.reset(config); + }, + + /** + * Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object. + * + * @method Phaser.Time.TimerEvent#reset + * @since 3.0.0 + * + * @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event. + * + * @return {Phaser.Time.TimerEvent} This TimerEvent object. + */ + reset: function (config) + { + this.delay = GetFastValue(config, 'delay', 0); + + // Can also be set to -1 for an infinite loop (same as setting loop: true) + this.repeat = GetFastValue(config, 'repeat', 0); + + this.loop = GetFastValue(config, 'loop', false); + + this.callback = GetFastValue(config, 'callback', undefined); + + this.callbackScope = GetFastValue(config, 'callbackScope', this.callback); + + this.args = GetFastValue(config, 'args', []); + + this.timeScale = GetFastValue(config, 'timeScale', 1); + + this.startAt = GetFastValue(config, 'startAt', 0); + + this.paused = GetFastValue(config, 'paused', false); + + this.elapsed = this.startAt; + this.hasDispatched = false; + this.repeatCount = (this.repeat === -1 || this.loop) ? 999999999999 : this.repeat; + + return this; + }, + + /** + * Gets the progress of the current iteration, not factoring in repeats. + * + * @method Phaser.Time.TimerEvent#getProgress + * @since 3.0.0 + * + * @return {number} A number between 0 and 1 representing the current progress. + */ + getProgress: function () + { + return (this.elapsed / this.delay); + }, + + /** + * Gets the progress of the timer overall, factoring in repeats. + * + * @method Phaser.Time.TimerEvent#getOverallProgress + * @since 3.0.0 + * + * @return {number} The overall progress of the Timer Event, between 0 and 1. + */ + getOverallProgress: function () + { + if (this.repeat > 0) + { + var totalDuration = this.delay + (this.delay * this.repeat); + var totalElapsed = this.elapsed + (this.delay * (this.repeat - this.repeatCount)); + + return (totalElapsed / totalDuration); + } + else + { + return this.getProgress(); + } + }, + + /** + * Returns the number of times this Timer Event will repeat before finishing. + * + * This should not be confused with the number of times the Timer Event will fire before finishing. A return value of 0 doesn't indicate that the Timer Event has finished running - it indicates that it will not repeat after the next time it fires. + * + * @method Phaser.Time.TimerEvent#getRepeatCount + * @since 3.0.0 + * + * @return {number} How many times the Timer Event will repeat. + */ + getRepeatCount: function () + { + return this.repeatCount; + }, + + /** + * Returns the local elapsed time for the current iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getElapsed + * @since 3.0.0 + * + * @return {number} The local elapsed time in milliseconds. + */ + getElapsed: function () + { + return this.elapsed; + }, + + /** + * Returns the local elapsed time for the current iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getElapsedSeconds + * @since 3.0.0 + * + * @return {number} The local elapsed time in seconds. + */ + getElapsedSeconds: function () + { + return this.elapsed * 0.001; + }, + + /** + * Returns the time interval until the next iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getRemaining + * @since 3.50.0 + * + * @return {number} The time interval in milliseconds. + */ + getRemaining: function () + { + return this.delay - this.elapsed; + }, + + /** + * Returns the time interval until the next iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getRemainingSeconds + * @since 3.50.0 + * + * @return {number} The time interval in seconds. + */ + getRemainingSeconds: function () + { + return this.getRemaining() * 0.001; + }, + + /** + * Returns the time interval until the last iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getOverallRemaining + * @since 3.50.0 + * + * @return {number} The time interval in milliseconds. + */ + getOverallRemaining: function () + { + return this.delay * (1 + this.repeatCount) - this.elapsed; + }, + + /** + * Returns the time interval until the last iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds + * @since 3.50.0 + * + * @return {number} The time interval in seconds. + */ + getOverallRemainingSeconds: function () + { + return this.getOverallRemaining() * 0.001; + }, + + /** + * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. + * + * @method Phaser.Time.TimerEvent#remove + * @since 3.0.0 + * + * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. + */ + remove: function (dispatchCallback) + { + if (dispatchCallback === undefined) { dispatchCallback = false; } + + this.elapsed = this.delay; + + this.hasDispatched = !dispatchCallback; + + this.repeatCount = 0; + }, + + /** + * Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments. + * + * Normally, this method is only called by the Clock when it shuts down. As such, it doesn't stop the Timer Event. If called manually, the Timer Event will still be updated by the Clock, but it won't do anything when it fires. + * + * @method Phaser.Time.TimerEvent#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.callback = undefined; + this.callbackScope = undefined; + this.args = []; + } + +}); + +module.exports = TimerEvent; + + +/***/ }), +/* 579 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var RESERVED = __webpack_require__(1458); + +/** + * Internal function used by the Tween Builder to return an array of properties + * that the Tween will be operating on. It takes a tween configuration object + * and then checks that none of the `props` entries start with an underscore, or that + * none of the direct properties are on the Reserved list. + * + * @function Phaser.Tweens.Builders.GetProps + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig} config - The configuration object of the Tween to get the properties from. + * + * @return {string[]} An array of all the properties the tween will operate on. + */ +var GetProps = function (config) +{ + var key; + var keys = []; + + // First see if we have a props object + + if (config.hasOwnProperty('props')) + { + for (key in config.props) + { + // Skip any property that starts with an underscore + if (key.substr(0, 1) !== '_') + { + keys.push({ key: key, value: config.props[key] }); + } + } + } + else + { + for (key in config) + { + // Skip any property that is in the ReservedProps list or that starts with an underscore + if (RESERVED.indexOf(key) === -1 && key.substr(0, 1) !== '_') + { + keys.push({ key: key, value: config[key] }); + } + } + } + + return keys; +}; + +module.exports = GetProps; + + +/***/ }), +/* 580 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetValue = __webpack_require__(6); + +/** + * Internal function used by the Timeline Builder. + * + * It returns an array of all tweens in the given timeline config. + * + * @function Phaser.Tweens.Builders.GetTweens + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. + * + * @return {Phaser.Tweens.Tween[]} An array of Tween instances that the Timeline will manage. + */ +var GetTweens = function (config) +{ + var tweens = GetValue(config, 'tweens', null); + + if (tweens === null) + { + return []; + } + else if (typeof tweens === 'function') + { + tweens = tweens.call(); + } + + if (!Array.isArray(tweens)) + { + tweens = [ tweens ]; + } + + return tweens; +}; + +module.exports = GetTweens; + + +/***/ }), +/* 581 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Defaults = __webpack_require__(261); +var GetAdvancedValue = __webpack_require__(13); +var GetBoolean = __webpack_require__(96); +var GetEaseFunction = __webpack_require__(80); +var GetNewValue = __webpack_require__(160); +var GetValue = __webpack_require__(6); +var GetValueOp = __webpack_require__(260); +var Tween = __webpack_require__(262); +var TweenData = __webpack_require__(264); + +/** + * Creates a new Number Tween. + * + * @function Phaser.Tweens.Builders.NumberTweenBuilder + * @since 3.0.0 + * + * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - The owner of the new Tween. + * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - Configuration for the new Tween. + * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. + * + * @return {Phaser.Tweens.Tween} The new tween. + */ +var NumberTweenBuilder = function (parent, config, defaults) +{ + if (defaults === undefined) + { + defaults = Defaults; + } + + // var tween = this.tweens.addCounter({ + // from: 100, + // to: 200, + // ... (normal tween properties) + // }) + // + // Then use it in your game via: + // + // tween.getValue() + + var from = GetValue(config, 'from', 0); + var to = GetValue(config, 'to', 1); + + var targets = [ { value: from } ]; + + var delay = GetNewValue(config, 'delay', defaults.delay); + var duration = GetNewValue(config, 'duration', defaults.duration); + var easeParams = GetValue(config, 'easeParams', defaults.easeParams); + var ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), easeParams); + var hold = GetNewValue(config, 'hold', defaults.hold); + var repeat = GetNewValue(config, 'repeat', defaults.repeat); + var repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); + var yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); + + var data = []; + + var ops = GetValueOp('value', to); + + var tweenData = TweenData( + targets[0], + 0, + 'value', + ops.getEnd, + ops.getStart, + ops.getActive, + ease, + delay, + duration, + yoyo, + hold, + repeat, + repeatDelay, + false, + false + ); + + tweenData.start = from; + tweenData.current = from; + tweenData.to = to; + + data.push(tweenData); + + var tween = new Tween(parent, data, targets); + + tween.offset = GetAdvancedValue(config, 'offset', null); + tween.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); + tween.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); + tween.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); + tween.paused = GetBoolean(config, 'paused', false); + tween.useFrames = GetBoolean(config, 'useFrames', false); + + // Set the Callbacks + var scope = GetValue(config, 'callbackScope', tween); + + // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params + var tweenArray = [ tween, null ]; + + var callbacks = Tween.TYPES; + + for (var i = 0; i < callbacks.length; i++) + { + var type = callbacks[i]; + + var callback = GetValue(config, type, false); + + if (callback) + { + var callbackScope = GetValue(config, type + 'Scope', scope); + var callbackParams = GetValue(config, type + 'Params', []); + + // The null is reset to be the Tween target + tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); + } + } + + return tween; +}; + +module.exports = NumberTweenBuilder; + + +/***/ }), +/* 582 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetEaseFunction = __webpack_require__(80); +var GetValue = __webpack_require__(6); +var MATH_CONST = __webpack_require__(14); + +/** + * Creates a Stagger function to be used by a Tween property. + * + * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. + * + * This is only worth using if the tween has multiple targets. + * + * The following will stagger the delay by 100ms across all targets of the tween, causing them to scale down to 0.2 + * over the duration specified: + * + * ```javascript + * this.tweens.add({ + * targets: [ ... ], + * scale: 0.2, + * ease: 'linear', + * duration: 1000, + * delay: this.tweens.stagger(100) + * }); + * ``` + * + * The following will stagger the delay by 500ms across all targets of the tween using a 10 x 6 grid, staggering + * from the center out, using a cubic ease. + * + * ```javascript + * this.tweens.add({ + * targets: [ ... ], + * scale: 0.2, + * ease: 'linear', + * duration: 1000, + * delay: this.tweens.stagger(500, { grid: [ 10, 6 ], from: 'center', ease: 'cubic.out' }) + * }); + * ``` + * + * @function Phaser.Tweens.Builders.StaggerBuilder + * @since 3.19.0 + * + * @param {(number|number[])} value - The amount to stagger by, or an array containing two elements representing the min and max values to stagger between. + * @param {Phaser.Types.Tweens.StaggerConfig} [config] - A Stagger Configuration object. + * + * @return {function} The stagger function. + */ +var StaggerBuilder = function (value, options) +{ + if (options === undefined) { options = {}; } + + var result; + + var start = GetValue(options, 'start', 0); + var ease = GetValue(options, 'ease', null); + var grid = GetValue(options, 'grid', null); + + var from = GetValue(options, 'from', 0); + + var fromFirst = (from === 'first'); + var fromCenter = (from === 'center'); + var fromLast = (from === 'last'); + var fromValue = (typeof(from) === 'number'); + + var isRange = (Array.isArray(value)); + var value1 = (isRange) ? parseFloat(value[0]) : parseFloat(value); + var value2 = (isRange) ? parseFloat(value[1]) : 0; + var maxValue = Math.max(value1, value2); + + if (isRange) + { + start += value1; + } + + if (grid) + { + // Pre-calc the grid to save doing it for ever tweendata update + var gridWidth = grid[0]; + var gridHeight = grid[1]; + + var fromX = 0; + var fromY = 0; + + var distanceX = 0; + var distanceY = 0; + + var gridValues = []; + + if (fromLast) + { + fromX = gridWidth - 1; + fromY = gridHeight - 1; + } + else if (fromValue) + { + fromX = from % gridWidth; + fromY = Math.floor(from / gridWidth); + } + else if (fromCenter) + { + fromX = (gridWidth - 1) / 2; + fromY = (gridHeight - 1) / 2; + } + + var gridMax = MATH_CONST.MIN_SAFE_INTEGER; + + for (var toY = 0; toY < gridHeight; toY++) + { + gridValues[toY] = []; + + for (var toX = 0; toX < gridWidth; toX++) + { + distanceX = fromX - toX; + distanceY = fromY - toY; + + var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); + + if (dist > gridMax) + { + gridMax = dist; + } + + gridValues[toY][toX] = dist; + } + } + } + + var easeFunction = (ease) ? GetEaseFunction(ease) : null; + + if (grid) + { + result = function (target, key, value, index) + { + var gridSpace = 0; + var toX = index % gridWidth; + var toY = Math.floor(index / gridWidth); + + if (toX >= 0 && toX < gridWidth && toY >= 0 && toY < gridHeight) + { + gridSpace = gridValues[toY][toX]; + } + + var output; + + if (isRange) + { + var diff = (value2 - value1); + + if (easeFunction) + { + output = ((gridSpace / gridMax) * diff) * easeFunction(gridSpace / gridMax); + } + else + { + output = (gridSpace / gridMax) * diff; + } + } + else if (easeFunction) + { + output = (gridSpace * value1) * easeFunction(gridSpace / gridMax); + } + else + { + output = gridSpace * value1; + } + + return output + start; + }; + } + else + { + result = function (target, key, value, index, total) + { + // zero offset + total--; + + var fromIndex; + + if (fromFirst) + { + fromIndex = index; + } + else if (fromCenter) + { + fromIndex = Math.abs((total / 2) - index); + } + else if (fromLast) + { + fromIndex = total - index; + } + else if (fromValue) + { + fromIndex = Math.abs(from - index); + } + + var output; + + if (isRange) + { + var spacing; + + if (fromCenter) + { + spacing = ((value2 - value1) / total) * (fromIndex * 2); + } + else + { + spacing = ((value2 - value1) / total) * fromIndex; + } + + if (easeFunction) + { + output = spacing * easeFunction(fromIndex / total); + } + else + { + output = spacing; + } + } + else if (easeFunction) + { + output = (total * maxValue) * easeFunction(fromIndex / total); + } + else + { + output = fromIndex * value1; + } + + return output + start; + }; + } + + return result; +}; + +module.exports = StaggerBuilder; + + +/***/ }), +/* 583 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clone = __webpack_require__(77); +var Defaults = __webpack_require__(261); +var GetAdvancedValue = __webpack_require__(13); +var GetBoolean = __webpack_require__(96); +var GetEaseFunction = __webpack_require__(80); +var GetNewValue = __webpack_require__(160); +var GetTargets = __webpack_require__(259); +var GetTweens = __webpack_require__(580); +var GetValue = __webpack_require__(6); +var Timeline = __webpack_require__(584); +var TweenBuilder = __webpack_require__(161); + +/** + * Builds a Timeline of Tweens based on a configuration object. + * + * @function Phaser.Tweens.Builders.TimelineBuilder + * @since 3.0.0 + * + * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager to which the Timeline will belong. + * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. + * + * @return {Phaser.Tweens.Timeline} The created Timeline. + */ +var TimelineBuilder = function (manager, config) +{ + var timeline = new Timeline(manager); + + timeline.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); + timeline.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); + timeline.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); + timeline.paused = GetBoolean(config, 'paused', false); + timeline.useFrames = GetBoolean(config, 'useFrames', false); + + // Callbacks + + var scope = GetValue(config, 'callbackScope', timeline); + + var timelineArray = [ timeline ]; + + var onStart = GetValue(config, 'onStart', false); + + // The Start of the Timeline + if (onStart) + { + var onStartScope = GetValue(config, 'onStartScope', scope); + var onStartParams = GetValue(config, 'onStartParams', []); + + timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope); + } + + var onUpdate = GetValue(config, 'onUpdate', false); + + // Every time the Timeline updates (regardless which Tweens are running) + if (onUpdate) + { + var onUpdateScope = GetValue(config, 'onUpdateScope', scope); + var onUpdateParams = GetValue(config, 'onUpdateParams', []); + + timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope); + } + + var onLoop = GetValue(config, 'onLoop', false); + + // Called when the whole Timeline loops + if (onLoop) + { + var onLoopScope = GetValue(config, 'onLoopScope', scope); + var onLoopParams = GetValue(config, 'onLoopParams', []); + + timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope); + } + + var onYoyo = GetValue(config, 'onYoyo', false); + + // Called when a Timeline yoyos + if (onYoyo) + { + var onYoyoScope = GetValue(config, 'onYoyoScope', scope); + var onYoyoParams = GetValue(config, 'onYoyoParams', []); + + timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope); + } + + var onComplete = GetValue(config, 'onComplete', false); + + // Called when the Timeline completes, after the completeDelay, etc. + if (onComplete) + { + var onCompleteScope = GetValue(config, 'onCompleteScope', scope); + var onCompleteParams = GetValue(config, 'onCompleteParams', []); + + timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope); + } + + // Tweens + + var tweens = GetTweens(config); + + if (tweens.length === 0) + { + timeline.paused = true; + + return timeline; + } + + var defaults = Clone(Defaults); + + defaults.targets = GetTargets(config); + + // totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration + + var totalDuration = GetAdvancedValue(config, 'totalDuration', 0); + + if (totalDuration > 0) + { + defaults.duration = Math.floor(totalDuration / tweens.length); + } + else + { + defaults.duration = GetNewValue(config, 'duration', defaults.duration); + } + + defaults.delay = GetNewValue(config, 'delay', defaults.delay); + defaults.easeParams = GetValue(config, 'easeParams', defaults.easeParams); + defaults.ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), defaults.easeParams); + defaults.hold = GetNewValue(config, 'hold', defaults.hold); + defaults.repeat = GetNewValue(config, 'repeat', defaults.repeat); + defaults.repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); + defaults.yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); + defaults.flipX = GetBoolean(config, 'flipX', defaults.flipX); + defaults.flipY = GetBoolean(config, 'flipY', defaults.flipY); + + // Create the Tweens + for (var i = 0; i < tweens.length; i++) + { + timeline.queue(TweenBuilder(timeline, tweens[i], defaults)); + } + + return timeline; +}; + +module.exports = TimelineBuilder; + + +/***/ }), +/* 584 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(263); +var TweenBuilder = __webpack_require__(161); +var TWEEN_CONST = __webpack_require__(97); + +/** + * @classdesc + * A Timeline combines multiple Tweens into one. Its overall behavior is otherwise similar to a single Tween. + * + * The Timeline updates all of its Tweens simultaneously. Its methods allow you to easily build a sequence + * of Tweens (each one starting after the previous one) or run multiple Tweens at once during given parts of the Timeline. + * + * @class Timeline + * @memberof Phaser.Tweens + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager which owns this Timeline. + */ +var Timeline = new Class({ + + Extends: EventEmitter, + + initialize: + + function Timeline (manager) + { + EventEmitter.call(this); + + /** + * The Tween Manager which owns this Timeline. + * + * @name Phaser.Tweens.Timeline#manager + * @type {Phaser.Tweens.TweenManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * A constant value which allows this Timeline to be easily identified as one. + * + * @name Phaser.Tweens.Timeline#isTimeline + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.isTimeline = true; + + /** + * An array of Tween objects, each containing a unique property and target being tweened. + * + * @name Phaser.Tweens.Timeline#data + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.data = []; + + /** + * The cached size of the data array. + * + * @name Phaser.Tweens.Timeline#totalData + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalData = 0; + + /** + * If true then duration, delay, etc values are all frame totals, rather than ms. + * + * @name Phaser.Tweens.Timeline#useFrames + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.useFrames = false; + + /** + * Scales the time applied to this Timeline. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. + * Value isn't used when calculating total duration of the Timeline, it's a run-time delta adjustment only. + * + * @name Phaser.Tweens.Timeline#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * Loop this Timeline? Can be -1 for an infinite loop, or an integer. + * When enabled it will play through ALL Tweens again (use Tween.repeat to loop a single tween) + * + * @name Phaser.Tweens.Timeline#loop + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loop = 0; + + /** + * Time in ms/frames before this Timeline loops. + * + * @name Phaser.Tweens.Timeline#loopDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loopDelay = 0; + + /** + * How many loops are left to run? + * + * @name Phaser.Tweens.Timeline#loopCounter + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loopCounter = 0; + + /** + * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes) + * + * @name Phaser.Tweens.Timeline#completeDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.completeDelay = 0; + + /** + * Countdown timer value, as used by `loopDelay` and `completeDelay`. + * + * @name Phaser.Tweens.Timeline#countdown + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.countdown = 0; + + /** + * The current state of the Timeline. + * + * @name Phaser.Tweens.Timeline#state + * @type {number} + * @since 3.0.0 + */ + this.state = TWEEN_CONST.PENDING_ADD; + + /** + * The state of the Timeline when it was paused (used by Resume) + * + * @name Phaser.Tweens.Timeline#_pausedState + * @type {number} + * @private + * @since 3.0.0 + */ + this._pausedState = TWEEN_CONST.PENDING_ADD; + + /** + * Does the Timeline start off paused? (if so it needs to be started with Timeline.play) + * + * @name Phaser.Tweens.Timeline#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + /** + * Elapsed time in ms/frames of this run through of the Timeline. + * + * @name Phaser.Tweens.Timeline#elapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.elapsed = 0; + + /** + * Total elapsed time in ms/frames of the entire Timeline, including looping. + * + * @name Phaser.Tweens.Timeline#totalElapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalElapsed = 0; + + /** + * Time in ms/frames for the whole Timeline to play through once, excluding loop amounts and loop delays. + * + * @name Phaser.Tweens.Timeline#duration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.duration = 0; + + /** + * Value between 0 and 1. The amount of progress through the Timeline, _excluding loops_. + * + * @name Phaser.Tweens.Timeline#progress + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.progress = 0; + + /** + * Time in ms/frames for all Tweens in this Timeline to complete (including looping) + * + * @name Phaser.Tweens.Timeline#totalDuration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalDuration = 0; + + /** + * Value between 0 and 1. The amount through the entire Timeline, including looping. + * + * @name Phaser.Tweens.Timeline#totalProgress + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalProgress = 0; + + /** + * An object containing the different Tween callback functions. + * + * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * + * `onComplete` When the Timeline finishes playback fully or `Timeline.stop` is called. Never invoked if timeline is set to repeat infinitely. + * `onLoop` When a Timeline loops. + * `onStart` When the Timeline starts playing. + * `onUpdate` When a Timeline updates a child Tween. + * `onYoyo` When a Timeline starts a yoyo. + * + * @name Phaser.Tweens.Timeline#callbacks + * @type {object} + * @since 3.0.0 + */ + this.callbacks = { + onComplete: null, + onLoop: null, + onStart: null, + onUpdate: null, + onYoyo: null + }; + + /** + * The context in which all callbacks are invoked. + * + * @name Phaser.Tweens.Timeline#callbackScope + * @type {any} + * @since 3.0.0 + */ + this.callbackScope; + }, + + /** + * Internal method that will emit a Timeline based Event and invoke the given callback. + * + * @method Phaser.Tweens.Timeline#dispatchTimelineEvent + * @since 3.19.0 + * + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {function} callback - The callback to be invoked. Can be `null` or `undefined` to skip invocation. + */ + dispatchTimelineEvent: function (event, callback) + { + this.emit(event, this); + + if (callback) + { + callback.func.apply(callback.scope, callback.params); + } + }, + + /** + * Sets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. + * + * The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only. + * + * @method Phaser.Tweens.Timeline#setTimeScale + * @since 3.0.0 + * + * @param {number} value - The time scale value to set. + * + * @return {this} This Timeline object. + */ + setTimeScale: function (value) + { + this.timeScale = value; + + return this; + }, + + /** + * Gets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. + * + * @method Phaser.Tweens.Timeline#getTimeScale + * @since 3.0.0 + * + * @return {number} The value of the time scale applied to this Timeline. + */ + getTimeScale: function () + { + return this.timeScale; + }, + + /** + * Check whether or not the Timeline is playing. + * + * @method Phaser.Tweens.Timeline#isPlaying + * @since 3.0.0 + * + * @return {boolean} `true` if this Timeline is active, otherwise `false`. + */ + isPlaying: function () + { + return (this.state === TWEEN_CONST.ACTIVE); + }, + + /** + * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. + * + * @method Phaser.Tweens.Timeline#add + * @since 3.0.0 + * + * @param {(Phaser.Types.Tweens.TweenBuilderConfig|object)} config - The configuration object for the Tween. + * + * @return {this} This Timeline object. + */ + add: function (config) + { + return this.queue(TweenBuilder(this, config)); + }, + + /** + * Adds an existing Tween to this Timeline. + * + * @method Phaser.Tweens.Timeline#queue + * @since 3.0.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to be added to this Timeline. + * + * @return {this} This Timeline object. + */ + queue: function (tween) + { + if (!this.isPlaying()) + { + tween.parent = this; + tween.parentIsTimeline = true; + + this.data.push(tween); + + this.totalData = this.data.length; + } + + return this; + }, + + /** + * Checks whether a Tween has an offset value. + * + * @method Phaser.Tweens.Timeline#hasOffset + * @since 3.0.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to check. + * + * @return {boolean} `true` if the tween has a non-null offset. + */ + hasOffset: function (tween) + { + return (tween.offset !== null); + }, + + /** + * Checks whether the offset value is a number or a directive that is relative to previous tweens. + * + * @method Phaser.Tweens.Timeline#isOffsetAbsolute + * @since 3.0.0 + * + * @param {number} value - The offset value to be evaluated. + * + * @return {boolean} `true` if the result is a number, `false` if it is a directive like " -= 1000". + */ + isOffsetAbsolute: function (value) + { + return (typeof(value) === 'number'); + }, + + /** + * Checks if the offset is a relative value rather than an absolute one. + * If the value is just a number, this returns false. + * + * @method Phaser.Tweens.Timeline#isOffsetRelative + * @since 3.0.0 + * + * @param {string} value - The offset value to be evaluated. + * + * @return {boolean} `true` if the value is relative, i.e " -= 1000". If `false`, the offset is absolute. + */ + isOffsetRelative: function (value) + { + var t = typeof(value); + + if (t === 'string') + { + var op = value[0]; + + if (op === '-' || op === '+') + { + return true; + } + } + + return false; + }, + + /** + * Parses the relative offset value, returning a positive or negative number. + * + * @method Phaser.Tweens.Timeline#getRelativeOffset + * @since 3.0.0 + * + * @param {string} value - The relative offset, in the format of '-=500', for example. The first character determines whether it will be a positive or negative number. Spacing matters here. + * @param {number} base - The value to use as the offset. + * + * @return {number} The parsed offset value. + */ + getRelativeOffset: function (value, base) + { + var op = value[0]; + var num = parseFloat(value.substr(2)); + var result = base; + + switch (op) + { + case '+': + result += num; + break; + + case '-': + result -= num; + break; + } + + // Cannot ever be < 0 + return Math.max(0, result); + }, + + /** + * Calculates the total duration of the timeline. + * + * Computes all tween durations and returns the full duration of the timeline. + * + * The resulting number is stored in the timeline, not as a return value. + * + * @method Phaser.Tweens.Timeline#calcDuration + * @since 3.0.0 + */ + calcDuration: function () + { + var prevEnd = 0; + var totalDuration = 0; + var offsetDuration = 0; + + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + tween.init(); + + if (this.hasOffset(tween)) + { + if (this.isOffsetAbsolute(tween.offset)) + { + // An actual number, so it defines the start point from the beginning of the timeline + tween.calculatedOffset = tween.offset; + + if (tween.offset === 0) + { + offsetDuration = 0; + } + } + else if (this.isOffsetRelative(tween.offset)) + { + // A relative offset (i.e. '-=1000', so starts at 'offset' ms relative to the PREVIOUS Tweens ending time) + tween.calculatedOffset = this.getRelativeOffset(tween.offset, prevEnd); + } + } + else + { + // Sequential + tween.calculatedOffset = offsetDuration; + } + + prevEnd = tween.totalDuration + tween.calculatedOffset; + + totalDuration += tween.totalDuration; + offsetDuration += tween.totalDuration; + } + + // Excludes loop values + this.duration = totalDuration; + + this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; + + if (this.loopCounter > 0) + { + this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter); + } + else + { + this.totalDuration = this.duration + this.completeDelay; + } + }, + + /** + * Initializes the timeline, which means all Tweens get their init() called, and the total duration will be computed. + * Returns a boolean indicating whether the timeline is auto-started or not. + * + * @method Phaser.Tweens.Timeline#init + * @since 3.0.0 + * + * @return {boolean} `true` if the Timeline is started. `false` if it is paused. + */ + init: function () + { + this.calcDuration(); + + this.progress = 0; + this.totalProgress = 0; + + if (this.paused) + { + this.state = TWEEN_CONST.PAUSED; + + return false; + } + else + { + return true; + } + }, + + /** + * Resets all of the timeline's tweens back to their initial states. + * The boolean parameter indicates whether tweens that are looping should reset as well, or not. + * + * @method Phaser.Tweens.Timeline#resetTweens + * @since 3.0.0 + * + * @param {boolean} resetFromLoop - If `true`, resets all looping tweens to their initial values. + */ + resetTweens: function (resetFromLoop) + { + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + tween.play(resetFromLoop); + } + }, + + /** + * Sets a callback for the Timeline. + * + * @method Phaser.Tweens.Timeline#setCallback + * @since 3.0.0 + * + * @param {string} type - The internal type of callback to set. + * @param {function} callback - Timeline allows multiple tweens to be linked together to create a streaming sequence. + * @param {array} [params] - The parameters to pass to the callback. + * @param {object} [scope] - The context scope of the callback. + * + * @return {this} This Timeline object. + */ + setCallback: function (type, callback, params, scope) + { + if (Timeline.TYPES.indexOf(type) !== -1) + { + this.callbacks[type] = { func: callback, scope: scope, params: params }; + } + + return this; + }, + + /** + * Passed a Tween to the Tween Manager and requests it be made active. + * + * @method Phaser.Tweens.Timeline#makeActive + * @since 3.3.0 + * + * @param {Phaser.Tweens.Tween} tween - The tween object to make active. + * + * @return {Phaser.Tweens.TweenManager} The Timeline's Tween Manager reference. + */ + makeActive: function (tween) + { + return this.manager.makeActive(tween); + }, + + /** + * Starts playing the Timeline. + * + * @method Phaser.Tweens.Timeline#play + * @fires Phaser.Tweens.Events#TIMELINE_START + * @since 3.0.0 + */ + play: function () + { + if (this.state === TWEEN_CONST.ACTIVE) + { + return; + } + + if (this.paused) + { + this.paused = false; + + this.manager.makeActive(this); + + return; + } + else + { + this.resetTweens(false); + + this.state = TWEEN_CONST.ACTIVE; + } + + this.dispatchTimelineEvent(Events.TIMELINE_START, this.callbacks.onStart); + }, + + /** + * Updates the Timeline's `state` and fires callbacks and events. + * + * @method Phaser.Tweens.Timeline#nextState + * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE + * @fires Phaser.Tweens.Events#TIMELINE_LOOP + * @since 3.0.0 + * + * @see Phaser.Tweens.Timeline#update + */ + nextState: function () + { + if (this.loopCounter > 0) + { + // Reset the elapsed time + this.elapsed = 0; + this.progress = 0; + + this.loopCounter--; + + this.resetTweens(true); + + if (this.loopDelay > 0) + { + this.countdown = this.loopDelay; + + this.state = TWEEN_CONST.LOOP_DELAY; + } + else + { + this.state = TWEEN_CONST.ACTIVE; + + this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); + } + } + else if (this.completeDelay > 0) + { + this.state = TWEEN_CONST.COMPLETE_DELAY; + + this.countdown = this.completeDelay; + } + else + { + this.state = TWEEN_CONST.PENDING_REMOVE; + + this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); + } + }, + + /** + * Returns 'true' if this Timeline has finished and should be removed from the Tween Manager. + * Otherwise, returns false. + * + * @method Phaser.Tweens.Timeline#update + * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE + * @fires Phaser.Tweens.Events#TIMELINE_UPDATE + * @since 3.0.0 + * + * @param {number} timestamp - 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. + * + * @return {boolean} Returns `true` if this Timeline has finished and should be removed from the Tween Manager. + */ + update: function (timestamp, delta) + { + if (this.state === TWEEN_CONST.PAUSED) + { + return; + } + + if (this.useFrames) + { + delta = 1 * this.manager.timeScale; + } + + delta *= this.timeScale; + + this.elapsed += delta; + this.progress = Math.min(this.elapsed / this.duration, 1); + + this.totalElapsed += delta; + this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); + + switch (this.state) + { + case TWEEN_CONST.ACTIVE: + + var stillRunning = this.totalData; + + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + if (tween.update(timestamp, delta)) + { + stillRunning--; + } + } + + this.dispatchTimelineEvent(Events.TIMELINE_UPDATE, this.callbacks.onUpdate); + + // Anything still running? If not, we're done + if (stillRunning === 0) + { + this.nextState(); + } + + break; + + case TWEEN_CONST.LOOP_DELAY: + + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.state = TWEEN_CONST.ACTIVE; + + this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); + } + + break; + + case TWEEN_CONST.COMPLETE_DELAY: + + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.state = TWEEN_CONST.PENDING_REMOVE; + + this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); + } + + break; + } + + return (this.state === TWEEN_CONST.PENDING_REMOVE); + }, + + /** + * Stops the Timeline immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. + * + * @method Phaser.Tweens.Timeline#stop + * @since 3.0.0 + */ + stop: function () + { + this.state = TWEEN_CONST.PENDING_REMOVE; + }, + + /** + * Pauses the Timeline, retaining its internal state. + * + * Calling this on a Timeline that is already paused has no effect and fires no event. + * + * @method Phaser.Tweens.Timeline#pause + * @fires Phaser.Tweens.Events#TIMELINE_PAUSE + * @since 3.0.0 + * + * @return {this} This Timeline object. + */ + pause: function () + { + if (this.state === TWEEN_CONST.PAUSED) + { + return; + } + + this.paused = true; + + this._pausedState = this.state; + + this.state = TWEEN_CONST.PAUSED; + + this.emit(Events.TIMELINE_PAUSE, this); + + return this; + }, + + /** + * Resumes a paused Timeline from where it was when it was paused. + * + * Calling this on a Timeline that isn't paused has no effect and fires no event. + * + * @method Phaser.Tweens.Timeline#resume + * @fires Phaser.Tweens.Events#TIMELINE_RESUME + * @since 3.0.0 + * + * @return {this} This Timeline object. + */ + resume: function () + { + if (this.state === TWEEN_CONST.PAUSED) + { + this.paused = false; + + this.state = this._pausedState; + + this.emit(Events.TIMELINE_RESUME, this); + } + + return this; + }, + + /** + * Checks if any of the Tweens in this Timeline as operating on the target object. + * + * Returns `false` if no Tweens operate on the target object. + * + * @method Phaser.Tweens.Timeline#hasTarget + * @since 3.0.0 + * + * @param {object} target - The target to check all Tweens against. + * + * @return {boolean} `true` if there is at least a single Tween that operates on the target object, otherwise `false`. + */ + hasTarget: function (target) + { + for (var i = 0; i < this.data.length; i++) + { + if (this.data[i].hasTarget(target)) + { + return true; + } + } + + return false; + }, + + /** + * Stops all the Tweens in the Timeline immediately, whatever stage of progress they are at and flags + * them for removal by the TweenManager. + * + * @method Phaser.Tweens.Timeline#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var i = 0; i < this.data.length; i++) + { + this.data[i].stop(); + } + } + +}); + +Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ]; + +module.exports = Timeline; + + /***/ }), /* 585 */, /* 586 */, @@ -134956,7 +134982,7 @@ module.exports = GetLast; */ var AlignIn = __webpack_require__(283); -var CONST = __webpack_require__(120); +var CONST = __webpack_require__(122); var GetFastValue = __webpack_require__(2); var NOOP = __webpack_require__(1); var Zone = __webpack_require__(127); @@ -135074,7 +135100,7 @@ module.exports = GridAlign; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); // bitmask flag for GameObject.renderMask var _FLAG = 2; // 0010 @@ -136841,7 +136867,7 @@ module.exports = Origin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var GetBoolean = __webpack_require__(96); var GetValue = __webpack_require__(6); var TWEEN_CONST = __webpack_require__(97); @@ -138793,7 +138819,7 @@ module.exports = PlaceOnEllipse; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetPoints = __webpack_require__(167); +var GetPoints = __webpack_require__(168); /** * Positions an array of Game Objects on evenly spaced points of a Line. @@ -138838,8 +138864,8 @@ module.exports = PlaceOnLine; */ var MarchingAnts = __webpack_require__(310); -var RotateLeft = __webpack_require__(174); -var RotateRight = __webpack_require__(175); +var RotateLeft = __webpack_require__(175); +var RotateRight = __webpack_require__(176); /** * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Rectangle. @@ -138993,7 +139019,7 @@ module.exports = PlayAnimation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(165); +var Random = __webpack_require__(166); /** * Takes an array of Game Objects and positions them at random locations within the Circle. @@ -139033,7 +139059,7 @@ module.exports = RandomCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(176); +var Random = __webpack_require__(177); /** * Takes an array of Game Objects and positions them at random locations within the Ellipse. @@ -139073,7 +139099,7 @@ module.exports = RandomEllipse; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(168); +var Random = __webpack_require__(169); /** * Takes an array of Game Objects and positions them at random locations on the Line. @@ -139113,7 +139139,7 @@ module.exports = RandomLine; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(169); +var Random = __webpack_require__(170); /** * Takes an array of Game Objects and positions them at random locations within the Rectangle. @@ -139151,7 +139177,7 @@ module.exports = RandomRectangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(177); +var Random = __webpack_require__(178); /** * Takes an array of Game Objects and positions them at random locations within the Triangle. @@ -139232,7 +139258,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundDistance = __webpack_require__(178); +var RotateAroundDistance = __webpack_require__(179); var DistanceBetween = __webpack_require__(48); /** @@ -139278,7 +139304,7 @@ module.exports = RotateAround; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathRotateAroundDistance = __webpack_require__(178); +var MathRotateAroundDistance = __webpack_require__(179); /** * Rotates an array of Game Objects around a point by the given angle and distance. @@ -140338,7 +140364,7 @@ module.exports = Shuffle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathSmootherStep = __webpack_require__(179); +var MathSmootherStep = __webpack_require__(180); /** * Smootherstep is a sigmoid-like interpolation and clamping function. @@ -140396,7 +140422,7 @@ module.exports = SmootherStep; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathSmoothStep = __webpack_require__(180); +var MathSmoothStep = __webpack_require__(181); /** * Smoothstep is a sigmoid-like interpolation and clamping function. @@ -140554,7 +140580,7 @@ module.exports = ToggleVisible; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Wrap = __webpack_require__(64); +var Wrap = __webpack_require__(66); /** * Wrap each item's coordinates within a rectangle's area. @@ -140608,10 +140634,10 @@ module.exports = WrapInRectangle; module.exports = { - Animation: __webpack_require__(181), + Animation: __webpack_require__(182), AnimationFrame: __webpack_require__(313), AnimationManager: __webpack_require__(315), - AnimationState: __webpack_require__(161), + AnimationState: __webpack_require__(162), Events: __webpack_require__(130) }; @@ -141955,7 +141981,7 @@ module.exports = { BaseCamera: __webpack_require__(131), CameraManager: __webpack_require__(775), Effects: __webpack_require__(327), - Events: __webpack_require__(34) + Events: __webpack_require__(35) }; @@ -142438,9 +142464,9 @@ module.exports = 'camerazoomstart'; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -142826,9 +142852,9 @@ module.exports = Fade; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -143177,10 +143203,10 @@ module.exports = Flash; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var EaseMap = __webpack_require__(132); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Vector2 = __webpack_require__(3); /** @@ -144661,9 +144687,9 @@ module.exports = Stepped; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Vector2 = __webpack_require__(3); /** @@ -144980,9 +145006,9 @@ module.exports = Shake; * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var EaseMap = __webpack_require__(132); /** @@ -145413,10 +145439,10 @@ module.exports = RotateTo; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var EaseMap = __webpack_require__(132); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -147275,10 +147301,10 @@ module.exports = { Config: __webpack_require__(340), CreateRenderer: __webpack_require__(360), - DebugHeader: __webpack_require__(362), + DebugHeader: __webpack_require__(378), Events: __webpack_require__(22), - TimeStep: __webpack_require__(363), - VisibilityHandler: __webpack_require__(365) + TimeStep: __webpack_require__(379), + VisibilityHandler: __webpack_require__(381) }; @@ -147890,8 +147916,8 @@ module.exports = { Reverse: __webpack_require__(815), RotateTo: __webpack_require__(816), ShortestBetween: __webpack_require__(817), - Wrap: __webpack_require__(264), - WrapDegrees: __webpack_require__(265) + Wrap: __webpack_require__(265), + WrapDegrees: __webpack_require__(266) }; @@ -148419,7 +148445,7 @@ module.exports = { module.exports = { Ceil: __webpack_require__(825), - Equal: __webpack_require__(121), + Equal: __webpack_require__(123), Floor: __webpack_require__(826), GreaterThan: __webpack_require__(348), LessThan: __webpack_require__(349) @@ -148565,7 +148591,7 @@ module.exports = BezierInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CatmullRom = __webpack_require__(190); +var CatmullRom = __webpack_require__(191); /** * A Catmull-Rom interpolation method. @@ -148669,7 +148695,7 @@ module.exports = LinearInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SmootherStep = __webpack_require__(179); +var SmootherStep = __webpack_require__(180); /** * A Smoother Step interpolation method. @@ -149430,9 +149456,9 @@ module.exports = Difference; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Matrix4 = __webpack_require__(65); +var Matrix4 = __webpack_require__(67); var NOOP = __webpack_require__(1); var tempMatrix = new Matrix4(); @@ -150307,8 +150333,8 @@ module.exports = Within; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Vector3 = __webpack_require__(36); -var Matrix4 = __webpack_require__(65); +var Vector3 = __webpack_require__(37); +var Matrix4 = __webpack_require__(67); var Quaternion = __webpack_require__(359); var tmpMat4 = new Matrix4(); @@ -151166,7 +151192,7 @@ module.exports = [ module.exports = { - GenerateTexture: __webpack_require__(366), + GenerateTexture: __webpack_require__(382), Palettes: __webpack_require__(885) }; @@ -151188,7 +151214,7 @@ module.exports = { module.exports = { - ARNE16: __webpack_require__(367), + ARNE16: __webpack_require__(383), C64: __webpack_require__(886), CGA: __webpack_require__(887), JMP: __webpack_require__(888), @@ -151365,14 +151391,14 @@ module.exports = { module.exports = { Path: __webpack_require__(891), - MoveTo: __webpack_require__(371), + MoveTo: __webpack_require__(387), - CubicBezier: __webpack_require__(368), - Curve: __webpack_require__(89), - Ellipse: __webpack_require__(369), - Line: __webpack_require__(370), - QuadraticBezier: __webpack_require__(372), - Spline: __webpack_require__(373) + CubicBezier: __webpack_require__(384), + Curve: __webpack_require__(90), + Ellipse: __webpack_require__(385), + Line: __webpack_require__(386), + QuadraticBezier: __webpack_require__(388), + Spline: __webpack_require__(389) }; @@ -151389,14 +151415,14 @@ module.exports = { // Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) var Class = __webpack_require__(0); -var CubicBezierCurve = __webpack_require__(368); -var EllipseCurve = __webpack_require__(369); +var CubicBezierCurve = __webpack_require__(384); +var EllipseCurve = __webpack_require__(385); var GameObjectFactory = __webpack_require__(5); -var LineCurve = __webpack_require__(370); -var MovePathTo = __webpack_require__(371); -var QuadraticBezierCurve = __webpack_require__(372); +var LineCurve = __webpack_require__(386); +var MovePathTo = __webpack_require__(387); +var QuadraticBezierCurve = __webpack_require__(388); var Rectangle = __webpack_require__(10); -var SplineCurve = __webpack_require__(373); +var SplineCurve = __webpack_require__(389); var Vector2 = __webpack_require__(3); var MATH_CONST = __webpack_require__(14); @@ -152432,13 +152458,13 @@ module.exports = DataManagerPlugin; module.exports = { Align: __webpack_require__(895), - BaseShader: __webpack_require__(374), + BaseShader: __webpack_require__(390), Bounds: __webpack_require__(898), Canvas: __webpack_require__(902), - Color: __webpack_require__(375), - ColorMatrix: __webpack_require__(266), + Color: __webpack_require__(391), + ColorMatrix: __webpack_require__(195), Masks: __webpack_require__(912), - RGB: __webpack_require__(195) + RGB: __webpack_require__(197) }; @@ -152453,8 +152479,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(120); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(122); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Display.Align @@ -152694,7 +152720,7 @@ module.exports = { CanvasInterpolation: __webpack_require__(361), CanvasPool: __webpack_require__(31), - Smoothing: __webpack_require__(188), + Smoothing: __webpack_require__(189), TouchAction: __webpack_require__(903), UserSelect: __webpack_require__(904) @@ -152930,8 +152956,8 @@ module.exports = ColorToRGBA; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); -var HueToComponent = __webpack_require__(377); +var Color = __webpack_require__(36); +var HueToComponent = __webpack_require__(393); /** * Converts HSL (hue, saturation and lightness) values to a Phaser Color object. @@ -152980,7 +153006,7 @@ module.exports = HSLToColor; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HSVToRGB = __webpack_require__(184); +var HSVToRGB = __webpack_require__(185); /** * Get HSV color wheel values in an array which will be 360 elements in size. @@ -153129,8 +153155,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Between = __webpack_require__(191); -var Color = __webpack_require__(35); +var Between = __webpack_require__(192); +var Color = __webpack_require__(36); /** * Creates a new Color object where the r, g, and b values have been set to random values @@ -153165,7 +153191,7 @@ module.exports = RandomRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ComponentToHex = __webpack_require__(376); +var ComponentToHex = __webpack_require__(392); /** * Converts the color values into an HTML compatible color string, prefixed with either `#` or `0x`. @@ -153237,14 +153263,14 @@ module.exports = { var Dom = { - AddToDOM: __webpack_require__(139), - DOMContentLoaded: __webpack_require__(378), - GetInnerHeight: __webpack_require__(379), - GetScreenOrientation: __webpack_require__(380), - GetTarget: __webpack_require__(385), - ParseXML: __webpack_require__(386), - RemoveFromDOM: __webpack_require__(197), - RequestAnimationFrame: __webpack_require__(364) + AddToDOM: __webpack_require__(140), + DOMContentLoaded: __webpack_require__(394), + GetInnerHeight: __webpack_require__(395), + GetScreenOrientation: __webpack_require__(396), + GetTarget: __webpack_require__(401), + ParseXML: __webpack_require__(402), + RemoveFromDOM: __webpack_require__(199), + RequestAnimationFrame: __webpack_require__(380) }; @@ -153462,7 +153488,7 @@ module.exports = EventEmitter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var AnimationManager = __webpack_require__(315); var CacheManager = __webpack_require__(319); var CanvasPool = __webpack_require__(31); @@ -153471,24 +153497,24 @@ var Config = __webpack_require__(340); var CreateDOMContainer = __webpack_require__(917); var CreateRenderer = __webpack_require__(360); var DataManager = __webpack_require__(98); -var DebugHeader = __webpack_require__(362); +var DebugHeader = __webpack_require__(378); var Device = __webpack_require__(341); -var DOMContentLoaded = __webpack_require__(378); +var DOMContentLoaded = __webpack_require__(394); var EventEmitter = __webpack_require__(9); var Events = __webpack_require__(22); -var InputManager = __webpack_require__(387); +var InputManager = __webpack_require__(403); var PluginCache = __webpack_require__(24); -var PluginManager = __webpack_require__(392); -var ScaleManager = __webpack_require__(393); -var SceneManager = __webpack_require__(395); +var PluginManager = __webpack_require__(408); +var ScaleManager = __webpack_require__(409); +var SceneManager = __webpack_require__(411); var TextureEvents = __webpack_require__(103); -var TextureManager = __webpack_require__(400); -var TimeStep = __webpack_require__(363); -var VisibilityHandler = __webpack_require__(365); +var TextureManager = __webpack_require__(416); +var TimeStep = __webpack_require__(379); +var VisibilityHandler = __webpack_require__(381); if (true) { - var SoundManagerCreator = __webpack_require__(404); + var SoundManagerCreator = __webpack_require__(420); } if (false) @@ -154165,7 +154191,7 @@ module.exports = Game; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var CreateDOMContainer = function (game) { @@ -157667,52 +157693,52 @@ var GameObjects = { UpdateList: __webpack_require__(1034), Components: __webpack_require__(11), - GetCalcMatrix: __webpack_require__(18), + GetCalcMatrix: __webpack_require__(19), BuildGameObject: __webpack_require__(28), - BuildGameObjectAnimation: __webpack_require__(417), + BuildGameObjectAnimation: __webpack_require__(433), GameObject: __webpack_require__(15), - BitmapText: __webpack_require__(146), - Blitter: __webpack_require__(208), - Bob: __webpack_require__(418), - Container: __webpack_require__(209), - DOMElement: __webpack_require__(420), - DynamicBitmapText: __webpack_require__(210), - Extern: __webpack_require__(422), - Graphics: __webpack_require__(211), - Group: __webpack_require__(108), + BitmapText: __webpack_require__(147), + Blitter: __webpack_require__(210), + Bob: __webpack_require__(434), + Container: __webpack_require__(211), + DOMElement: __webpack_require__(436), + DynamicBitmapText: __webpack_require__(212), + Extern: __webpack_require__(438), + Graphics: __webpack_require__(213), + Group: __webpack_require__(110), Image: __webpack_require__(124), - Layer: __webpack_require__(214), + Layer: __webpack_require__(216), Particles: __webpack_require__(1068), - PathFollower: __webpack_require__(435), - RenderTexture: __webpack_require__(216), + PathFollower: __webpack_require__(451), + RenderTexture: __webpack_require__(218), RetroFont: __webpack_require__(1076), - Rope: __webpack_require__(218), + Rope: __webpack_require__(220), Sprite: __webpack_require__(73), - Text: __webpack_require__(219), - GetTextSize: __webpack_require__(436), - MeasureText: __webpack_require__(438), - TextStyle: __webpack_require__(437), + Text: __webpack_require__(221), + GetTextSize: __webpack_require__(452), + MeasureText: __webpack_require__(454), + TextStyle: __webpack_require__(453), - TileSprite: __webpack_require__(220), + TileSprite: __webpack_require__(222), Zone: __webpack_require__(127), - Video: __webpack_require__(221), + Video: __webpack_require__(223), // Shapes Shape: __webpack_require__(32), - Arc: __webpack_require__(439), - Curve: __webpack_require__(440), - Ellipse: __webpack_require__(441), - Grid: __webpack_require__(442), - IsoBox: __webpack_require__(443), - IsoTriangle: __webpack_require__(444), - Line: __webpack_require__(445), - Polygon: __webpack_require__(446), - Rectangle: __webpack_require__(451), - Star: __webpack_require__(452), - Triangle: __webpack_require__(453), + Arc: __webpack_require__(455), + Curve: __webpack_require__(456), + Ellipse: __webpack_require__(457), + Grid: __webpack_require__(458), + IsoBox: __webpack_require__(459), + IsoTriangle: __webpack_require__(460), + Line: __webpack_require__(461), + Polygon: __webpack_require__(462), + Rectangle: __webpack_require__(467), + Star: __webpack_require__(468), + Triangle: __webpack_require__(469), // Game Object Factories @@ -157775,9 +157801,9 @@ var GameObjects = { // WebGL only Game Objects if (true) { - GameObjects.Shader = __webpack_require__(224); - GameObjects.Mesh = __webpack_require__(225); - GameObjects.PointLight = __webpack_require__(148); + GameObjects.Shader = __webpack_require__(226); + GameObjects.Mesh = __webpack_require__(227); + GameObjects.PointLight = __webpack_require__(149); GameObjects.Factories.Shader = __webpack_require__(1178); GameObjects.Factories.Mesh = __webpack_require__(1179); @@ -157787,8 +157813,8 @@ if (true) GameObjects.Creators.Mesh = __webpack_require__(1182); GameObjects.Creators.PointLight = __webpack_require__(1183); - GameObjects.Light = __webpack_require__(459); - GameObjects.LightsManager = __webpack_require__(460); + GameObjects.Light = __webpack_require__(475); + GameObjects.LightsManager = __webpack_require__(476); GameObjects.LightsPlugin = __webpack_require__(1184); } @@ -157806,7 +157832,7 @@ module.exports = GameObjects; */ var Class = __webpack_require__(0); -var List = __webpack_require__(105); +var List = __webpack_require__(107); var PluginCache = __webpack_require__(24); var GameObjectEvents = __webpack_require__(75); var SceneEvents = __webpack_require__(21); @@ -158082,16 +158108,16 @@ module.exports = DisplayList; module.exports = { - CheckMatrix: __webpack_require__(204), + CheckMatrix: __webpack_require__(206), MatrixToString: __webpack_require__(1010), ReverseColumns: __webpack_require__(1011), ReverseRows: __webpack_require__(1012), Rotate180: __webpack_require__(1013), RotateLeft: __webpack_require__(1014), - RotateMatrix: __webpack_require__(145), + RotateMatrix: __webpack_require__(146), RotateRight: __webpack_require__(1015), Translate: __webpack_require__(1016), - TransposeMatrix: __webpack_require__(413) + TransposeMatrix: __webpack_require__(429) }; @@ -158106,8 +158132,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Pad = __webpack_require__(182); -var CheckMatrix = __webpack_require__(204); +var Pad = __webpack_require__(183); +var CheckMatrix = __webpack_require__(206); /** * Generates a string (which you can pass to console.log) from the given Array Matrix. @@ -158296,7 +158322,7 @@ module.exports = ReverseRows; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix 180 degrees. @@ -158343,7 +158369,7 @@ module.exports = Rotate180; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix to the left (or 90 degrees) @@ -158390,7 +158416,7 @@ module.exports = RotateLeft; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix to the left (or -90 degrees) @@ -158437,8 +158463,8 @@ module.exports = RotateRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateLeft = __webpack_require__(174); -var RotateRight = __webpack_require__(175); +var RotateLeft = __webpack_require__(175); +var RotateRight = __webpack_require__(176); /** * Translates the given Array Matrix by shifting each column and row the @@ -159503,7 +159529,7 @@ module.exports = Swap; */ var Class = __webpack_require__(0); -var ProcessQueue = __webpack_require__(206); +var ProcessQueue = __webpack_require__(208); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); @@ -160382,7 +160408,7 @@ module.exports = GetBitmapTextSize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ParseXMLBitmapFont = __webpack_require__(207); +var ParseXMLBitmapFont = __webpack_require__(209); /** * Parse an XML Bitmap Font from an Atlas. @@ -160468,7 +160494,7 @@ module.exports = { */ var BatchChar = __webpack_require__(1041); -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -161429,12 +161455,12 @@ var renderCanvas = __webpack_require__(1); if (true) { - renderWebGL = __webpack_require__(421); + renderWebGL = __webpack_require__(437); } if (true) { - renderCanvas = __webpack_require__(421); + renderCanvas = __webpack_require__(437); } module.exports = { @@ -161528,7 +161554,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var TransformMatrix = __webpack_require__(25); var Utils = __webpack_require__(12); @@ -162055,7 +162081,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -162109,12 +162135,12 @@ if (true) renderWebGL = __webpack_require__(1058); // Needed for Graphics.generateTexture - renderCanvas = __webpack_require__(426); + renderCanvas = __webpack_require__(442); } if (true) { - renderCanvas = __webpack_require__(426); + renderCanvas = __webpack_require__(442); } module.exports = { @@ -162135,8 +162161,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Commands = __webpack_require__(212); -var GetCalcMatrix = __webpack_require__(18); +var Commands = __webpack_require__(214); +var GetCalcMatrix = __webpack_require__(19); var TransformMatrix = __webpack_require__(25); var Utils = __webpack_require__(12); @@ -162924,11 +162950,11 @@ module.exports = LayerCanvasRenderer; module.exports = { - EmitterOp: __webpack_require__(427), - GravityWell: __webpack_require__(428), - Particle: __webpack_require__(429), - ParticleEmitter: __webpack_require__(430), - ParticleEmitterManager: __webpack_require__(215), + EmitterOp: __webpack_require__(443), + GravityWell: __webpack_require__(444), + Particle: __webpack_require__(445), + ParticleEmitter: __webpack_require__(446), + ParticleEmitterManager: __webpack_require__(217), Zones: __webpack_require__(1072) }; @@ -163275,9 +163301,9 @@ module.exports = ParticleManagerCanvasRenderer; module.exports = { - DeathZone: __webpack_require__(431), - EdgeZone: __webpack_require__(432), - RandomZone: __webpack_require__(434) + DeathZone: __webpack_require__(447), + EdgeZone: __webpack_require__(448), + RandomZone: __webpack_require__(450) }; @@ -163430,7 +163456,7 @@ module.exports = RenderTextureCanvasRenderer; */ var RETRO_FONT_CONST = __webpack_require__(1077); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.GameObjects.RetroFont @@ -163734,7 +163760,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -164288,8 +164314,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); -var FillPathWebGL = __webpack_require__(109); +var GetCalcMatrix = __webpack_require__(19); +var FillPathWebGL = __webpack_require__(111); var StrokePathWebGL = __webpack_require__(81); /** @@ -164347,9 +164373,9 @@ module.exports = ArcWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -164453,8 +164479,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -164513,7 +164539,7 @@ module.exports = CurveWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -164630,8 +164656,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -164690,7 +164716,7 @@ module.exports = EllipseWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -164804,7 +164830,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -165004,7 +165030,7 @@ module.exports = GridWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -165222,7 +165248,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -165487,7 +165513,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -165785,7 +165811,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -165860,7 +165886,7 @@ module.exports = LineWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -165947,8 +165973,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -166007,7 +166033,7 @@ module.exports = PolygonWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -166121,7 +166147,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); var Utils = __webpack_require__(12); @@ -166193,7 +166219,7 @@ module.exports = RectangleWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -166296,8 +166322,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -166356,7 +166382,7 @@ module.exports = StarWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -166470,7 +166496,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); var Utils = __webpack_require__(12); @@ -166553,7 +166579,7 @@ module.exports = TriangleWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -166626,7 +166652,7 @@ module.exports = TriangleCanvasRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(208); +var Blitter = __webpack_require__(210); var GameObjectFactory = __webpack_require__(5); /** @@ -166669,7 +166695,7 @@ GameObjectFactory.register('blitter', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Container = __webpack_require__(209); +var Container = __webpack_require__(211); var GameObjectFactory = __webpack_require__(5); /** @@ -166702,7 +166728,7 @@ GameObjectFactory.register('container', function (x, y, children) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DOMElement = __webpack_require__(420); +var DOMElement = __webpack_require__(436); var GameObjectFactory = __webpack_require__(5); /** @@ -166791,7 +166817,7 @@ GameObjectFactory.register('dom', function (x, y, element, style, innerText) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DynamicBitmapText = __webpack_require__(210); +var DynamicBitmapText = __webpack_require__(212); var GameObjectFactory = __webpack_require__(5); /** @@ -166860,7 +166886,7 @@ GameObjectFactory.register('dynamicBitmapText', function (x, y, font, text, size * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extern = __webpack_require__(422); +var Extern = __webpack_require__(438); var GameObjectFactory = __webpack_require__(5); /** @@ -166901,7 +166927,7 @@ GameObjectFactory.register('extern', function () * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Graphics = __webpack_require__(211); +var Graphics = __webpack_require__(213); var GameObjectFactory = __webpack_require__(5); /** @@ -166940,7 +166966,7 @@ GameObjectFactory.register('graphics', function (config) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Group = __webpack_require__(108); +var Group = __webpack_require__(110); var GameObjectFactory = __webpack_require__(5); /** @@ -167014,7 +167040,7 @@ GameObjectFactory.register('image', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Layer = __webpack_require__(214); +var Layer = __webpack_require__(216); var GameObjectFactory = __webpack_require__(5); /** @@ -167046,7 +167072,7 @@ GameObjectFactory.register('layer', function (children) */ var GameObjectFactory = __webpack_require__(5); -var ParticleEmitterManager = __webpack_require__(215); +var ParticleEmitterManager = __webpack_require__(217); /** * Creates a new Particle Emitter Manager Game Object and adds it to the Scene. @@ -167079,7 +167105,7 @@ GameObjectFactory.register('particles', function (key, frame, emitters) */ var GameObjectFactory = __webpack_require__(5); -var PathFollower = __webpack_require__(435); +var PathFollower = __webpack_require__(451); /** * Creates a new PathFollower Game Object and adds it to the Scene. @@ -167127,7 +167153,7 @@ GameObjectFactory.register('follower', function (path, x, y, key, frame) */ var GameObjectFactory = __webpack_require__(5); -var RenderTexture = __webpack_require__(216); +var RenderTexture = __webpack_require__(218); /** * Creates a new Render Texture Game Object and adds it to the Scene. @@ -167166,7 +167192,7 @@ GameObjectFactory.register('renderTexture', function (x, y, width, height, key, * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Rope = __webpack_require__(218); +var Rope = __webpack_require__(220); var GameObjectFactory = __webpack_require__(5); /** @@ -167254,7 +167280,7 @@ GameObjectFactory.register('sprite', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var GameObjectFactory = __webpack_require__(5); /** @@ -167318,7 +167344,7 @@ GameObjectFactory.register('bitmapText', function (x, y, font, text, size, align * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Text = __webpack_require__(219); +var Text = __webpack_require__(221); var GameObjectFactory = __webpack_require__(5); /** @@ -167383,7 +167409,7 @@ GameObjectFactory.register('text', function (x, y, text, style) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TileSprite = __webpack_require__(220); +var TileSprite = __webpack_require__(222); var GameObjectFactory = __webpack_require__(5); /** @@ -167469,7 +167495,7 @@ GameObjectFactory.register('zone', function (x, y, width, height) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Video = __webpack_require__(221); +var Video = __webpack_require__(223); var GameObjectFactory = __webpack_require__(5); /** @@ -167502,7 +167528,7 @@ GameObjectFactory.register('video', function (x, y, key) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Arc = __webpack_require__(439); +var Arc = __webpack_require__(455); var GameObjectFactory = __webpack_require__(5); /** @@ -167576,7 +167602,7 @@ GameObjectFactory.register('circle', function (x, y, radius, fillColor, fillAlph */ var GameObjectFactory = __webpack_require__(5); -var Curve = __webpack_require__(440); +var Curve = __webpack_require__(456); /** * Creates a new Curve Shape Game Object and adds it to the Scene. @@ -167625,7 +167651,7 @@ GameObjectFactory.register('curve', function (x, y, curve, fillColor, fillAlpha) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(441); +var Ellipse = __webpack_require__(457); var GameObjectFactory = __webpack_require__(5); /** @@ -167678,7 +167704,7 @@ GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, */ var GameObjectFactory = __webpack_require__(5); -var Grid = __webpack_require__(442); +var Grid = __webpack_require__(458); /** * Creates a new Grid Shape Game Object and adds it to the Scene. @@ -167733,7 +167759,7 @@ GameObjectFactory.register('grid', function (x, y, width, height, cellWidth, cel */ var GameObjectFactory = __webpack_require__(5); -var IsoBox = __webpack_require__(443); +var IsoBox = __webpack_require__(459); /** * Creates a new IsoBox Shape Game Object and adds it to the Scene. @@ -167784,7 +167810,7 @@ GameObjectFactory.register('isobox', function (x, y, size, height, fillTop, fill */ var GameObjectFactory = __webpack_require__(5); -var IsoTriangle = __webpack_require__(444); +var IsoTriangle = __webpack_require__(460); /** * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. @@ -167837,7 +167863,7 @@ GameObjectFactory.register('isotriangle', function (x, y, size, height, reversed */ var GameObjectFactory = __webpack_require__(5); -var Line = __webpack_require__(445); +var Line = __webpack_require__(461); /** * Creates a new Line Shape Game Object and adds it to the Scene. @@ -167888,7 +167914,7 @@ GameObjectFactory.register('line', function (x, y, x1, y1, x2, y2, strokeColor, */ var GameObjectFactory = __webpack_require__(5); -var Polygon = __webpack_require__(446); +var Polygon = __webpack_require__(462); /** * Creates a new Polygon Shape Game Object and adds it to the Scene. @@ -167941,7 +167967,7 @@ GameObjectFactory.register('polygon', function (x, y, points, fillColor, fillAlp */ var GameObjectFactory = __webpack_require__(5); -var Rectangle = __webpack_require__(451); +var Rectangle = __webpack_require__(467); /** * Creates a new Rectangle Shape Game Object and adds it to the Scene. @@ -167985,7 +168011,7 @@ GameObjectFactory.register('rectangle', function (x, y, width, height, fillColor * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Star = __webpack_require__(452); +var Star = __webpack_require__(468); var GameObjectFactory = __webpack_require__(5); /** @@ -168038,7 +168064,7 @@ GameObjectFactory.register('star', function (x, y, points, innerRadius, outerRad */ var GameObjectFactory = __webpack_require__(5); -var Triangle = __webpack_require__(453); +var Triangle = __webpack_require__(469); /** * Creates a new Triangle Shape Game Object and adds it to the Scene. @@ -168088,7 +168114,7 @@ GameObjectFactory.register('triangle', function (x, y, x1, y1, x2, y2, x3, y3, f * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(208); +var Blitter = __webpack_require__(210); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -168140,7 +168166,7 @@ GameObjectCreator.register('blitter', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var Container = __webpack_require__(209); +var Container = __webpack_require__(211); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -168188,7 +168214,7 @@ GameObjectCreator.register('container', function (config, addToScene) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(210); +var BitmapText = __webpack_require__(212); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -168240,7 +168266,7 @@ GameObjectCreator.register('dynamicBitmapText', function (config, addToScene) */ var GameObjectCreator = __webpack_require__(16); -var Graphics = __webpack_require__(211); +var Graphics = __webpack_require__(213); /** * Creates a new Graphics Game Object and returns it. @@ -168288,7 +168314,7 @@ GameObjectCreator.register('graphics', function (config, addToScene) */ var GameObjectCreator = __webpack_require__(16); -var Group = __webpack_require__(108); +var Group = __webpack_require__(110); /** * Creates a new Group Game Object and returns it. @@ -168371,7 +168397,7 @@ GameObjectCreator.register('image', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var Layer = __webpack_require__(214); +var Layer = __webpack_require__(216); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -168420,7 +168446,7 @@ GameObjectCreator.register('layer', function (config, addToScene) var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetFastValue = __webpack_require__(2); -var ParticleEmitterManager = __webpack_require__(215); +var ParticleEmitterManager = __webpack_require__(217); /** * Creates a new Particle Emitter Manager Game Object and returns it. @@ -168479,7 +168505,7 @@ GameObjectCreator.register('particles', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var RenderTexture = __webpack_require__(216); +var RenderTexture = __webpack_require__(218); /** * Creates a new Render Texture Game Object and returns it. @@ -168532,7 +168558,7 @@ var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetValue = __webpack_require__(6); -var Rope = __webpack_require__(218); +var Rope = __webpack_require__(220); /** * Creates a new Rope Game Object and returns it. @@ -168589,7 +168615,7 @@ GameObjectCreator.register('rope', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var BuildGameObjectAnimation = __webpack_require__(417); +var BuildGameObjectAnimation = __webpack_require__(433); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var Sprite = __webpack_require__(73); @@ -168641,7 +168667,7 @@ GameObjectCreator.register('sprite', function (config, addToScene) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -168697,7 +168723,7 @@ GameObjectCreator.register('bitmapText', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Text = __webpack_require__(219); +var Text = __webpack_require__(221); /** * Creates a new Text Game Object and returns it. @@ -168784,7 +168810,7 @@ GameObjectCreator.register('text', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var TileSprite = __webpack_require__(220); +var TileSprite = __webpack_require__(222); /** * Creates a new TileSprite Game Object and returns it. @@ -168875,7 +168901,7 @@ GameObjectCreator.register('zone', function (config) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Video = __webpack_require__(221); +var Video = __webpack_require__(223); /** * Creates a new Video Game Object and returns it. @@ -168957,7 +168983,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -169076,7 +169102,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -169240,7 +169266,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -169306,7 +169332,7 @@ module.exports = PointLightWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Shader = __webpack_require__(224); +var Shader = __webpack_require__(226); var GameObjectFactory = __webpack_require__(5); /** @@ -169347,7 +169373,7 @@ if (true) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Mesh = __webpack_require__(225); +var Mesh = __webpack_require__(227); var GameObjectFactory = __webpack_require__(5); /** @@ -169393,7 +169419,7 @@ if (true) */ var GameObjectFactory = __webpack_require__(5); -var PointLight = __webpack_require__(148); +var PointLight = __webpack_require__(149); /** * Creates a new Point Light Game Object and adds it to the Scene. @@ -169455,7 +169481,7 @@ GameObjectFactory.register('pointlight', function (x, y, color, radius, intensit var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Shader = __webpack_require__(224); +var Shader = __webpack_require__(226); /** * Creates a new Shader Game Object and returns it. @@ -169509,7 +169535,7 @@ var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetValue = __webpack_require__(6); -var Mesh = __webpack_require__(225); +var Mesh = __webpack_require__(227); /** * Creates a new Mesh Game Object and returns it. @@ -169564,7 +169590,7 @@ GameObjectCreator.register('mesh', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var PointLight = __webpack_require__(148); +var PointLight = __webpack_require__(149); /** * Creates a new Point Light Game Object and returns it. @@ -169612,7 +169638,7 @@ GameObjectCreator.register('pointlight', function (config, addToScene) */ var Class = __webpack_require__(0); -var LightsManager = __webpack_require__(460); +var LightsManager = __webpack_require__(476); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); @@ -169729,13 +169755,13 @@ module.exports = LightsPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); Circle.Area = __webpack_require__(1186); Circle.Circumference = __webpack_require__(296); -Circle.CircumferencePoint = __webpack_require__(164); +Circle.CircumferencePoint = __webpack_require__(165); Circle.Clone = __webpack_require__(1187); -Circle.Contains = __webpack_require__(62); +Circle.Contains = __webpack_require__(63); Circle.ContainsPoint = __webpack_require__(1188); Circle.ContainsRect = __webpack_require__(1189); Circle.CopyFrom = __webpack_require__(1190); @@ -169745,7 +169771,7 @@ Circle.GetPoint = __webpack_require__(294); Circle.GetPoints = __webpack_require__(295); Circle.Offset = __webpack_require__(1193); Circle.OffsetPoint = __webpack_require__(1194); -Circle.Random = __webpack_require__(165); +Circle.Random = __webpack_require__(166); module.exports = Circle; @@ -169788,7 +169814,7 @@ module.exports = Area; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); /** * Creates a new Circle instance based on the values contained in the given source. @@ -169818,7 +169844,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); /** * Check to see if the Circle contains the given Point object. @@ -169849,7 +169875,7 @@ module.exports = ContainsPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); /** * Check to see if the Circle contains all four points of the given Rectangle object. @@ -170060,23 +170086,23 @@ module.exports = OffsetPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); Ellipse.Area = __webpack_require__(1196); -Ellipse.Circumference = __webpack_require__(425); -Ellipse.CircumferencePoint = __webpack_require__(213); +Ellipse.Circumference = __webpack_require__(441); +Ellipse.CircumferencePoint = __webpack_require__(215); Ellipse.Clone = __webpack_require__(1197); -Ellipse.Contains = __webpack_require__(107); +Ellipse.Contains = __webpack_require__(109); Ellipse.ContainsPoint = __webpack_require__(1198); Ellipse.ContainsRect = __webpack_require__(1199); Ellipse.CopyFrom = __webpack_require__(1200); Ellipse.Equals = __webpack_require__(1201); Ellipse.GetBounds = __webpack_require__(1202); -Ellipse.GetPoint = __webpack_require__(423); -Ellipse.GetPoints = __webpack_require__(424); +Ellipse.GetPoint = __webpack_require__(439); +Ellipse.GetPoints = __webpack_require__(440); Ellipse.Offset = __webpack_require__(1203); Ellipse.OffsetPoint = __webpack_require__(1204); -Ellipse.Random = __webpack_require__(176); +Ellipse.Random = __webpack_require__(177); module.exports = Ellipse; @@ -170125,7 +170151,7 @@ module.exports = Area; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); /** * Creates a new Ellipse instance based on the values contained in the given source. @@ -170155,7 +170181,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(107); +var Contains = __webpack_require__(109); /** * Check to see if the Ellipse contains the given Point object. @@ -170186,7 +170212,7 @@ module.exports = ContainsPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(107); +var Contains = __webpack_require__(109); /** * Check to see if the Ellipse contains all four points of the given Rectangle object. @@ -170400,7 +170426,7 @@ module.exports = OffsetPoint; */ var Point = __webpack_require__(4); -var CircleToCircle = __webpack_require__(226); +var CircleToCircle = __webpack_require__(228); /** * Checks if two Circles intersect and returns the intersection points as a Point object array. @@ -170493,8 +170519,8 @@ module.exports = GetCircleToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToCircle = __webpack_require__(227); -var CircleToRectangle = __webpack_require__(149); +var GetLineToCircle = __webpack_require__(229); +var CircleToRectangle = __webpack_require__(150); /** * Checks for intersection between a circle and a rectangle, @@ -170543,7 +170569,7 @@ module.exports = GetCircleToRectangle; */ var Vector4 = __webpack_require__(138); -var GetLineToPolygon = __webpack_require__(465); +var GetLineToPolygon = __webpack_require__(481); var Line = __webpack_require__(45); // Temp calculation segment @@ -170645,7 +170671,7 @@ module.exports = GetRaysFromPointToPolygon; */ var Rectangle = __webpack_require__(10); -var RectangleToRectangle = __webpack_require__(112); +var RectangleToRectangle = __webpack_require__(114); /** * Checks if two Rectangle shapes intersect and returns the area of this intersection as Rectangle object. @@ -170694,8 +170720,8 @@ module.exports = GetRectangleIntersection; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToRectangle = __webpack_require__(229); -var RectangleToRectangle = __webpack_require__(112); +var GetLineToRectangle = __webpack_require__(231); +var RectangleToRectangle = __webpack_require__(114); /** * Checks if two Rectangles intersect and returns the intersection points as a Point object array. @@ -170745,8 +170771,8 @@ module.exports = GetRectangleToRectangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RectangleToTriangle = __webpack_require__(467); -var GetLineToRectangle = __webpack_require__(229); +var RectangleToTriangle = __webpack_require__(483); +var GetLineToRectangle = __webpack_require__(231); /** * Checks for intersection between Rectangle shape and Triangle shape, @@ -170793,8 +170819,8 @@ module.exports = GetRectangleToTriangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToCircle = __webpack_require__(227); -var TriangleToCircle = __webpack_require__(469); +var GetLineToCircle = __webpack_require__(229); +var TriangleToCircle = __webpack_require__(485); /** * Checks if a Triangle and a Circle intersect, and returns the intersection points as a Point object array. @@ -170842,8 +170868,8 @@ module.exports = GetTriangleToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TriangleToTriangle = __webpack_require__(472); -var GetTriangleToLine = __webpack_require__(470); +var TriangleToTriangle = __webpack_require__(488); +var GetTriangleToLine = __webpack_require__(486); /** * Checks if two Triangles intersect, and returns the intersection points as a Point object array. @@ -170890,7 +170916,7 @@ module.exports = GetTriangleToTriangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PointToLine = __webpack_require__(474); +var PointToLine = __webpack_require__(490); /** * Checks if a Point is located on the given line segment. @@ -170973,7 +170999,7 @@ module.exports = RectangleToValues; var Line = __webpack_require__(45); -Line.Angle = __webpack_require__(92); +Line.Angle = __webpack_require__(93); Line.BresenhamPoints = __webpack_require__(311); Line.CenterOn = __webpack_require__(1216); Line.Clone = __webpack_require__(1217); @@ -170985,20 +171011,20 @@ Line.GetMidPoint = __webpack_require__(1222); Line.GetNearestPoint = __webpack_require__(1223); Line.GetNormal = __webpack_require__(1224); Line.GetPoint = __webpack_require__(301); -Line.GetPoints = __webpack_require__(167); +Line.GetPoints = __webpack_require__(168); Line.GetShortestDistance = __webpack_require__(1225); Line.Height = __webpack_require__(1226); -Line.Length = __webpack_require__(63); -Line.NormalAngle = __webpack_require__(475); +Line.Length = __webpack_require__(64); +Line.NormalAngle = __webpack_require__(491); Line.NormalX = __webpack_require__(1227); Line.NormalY = __webpack_require__(1228); Line.Offset = __webpack_require__(1229); Line.PerpSlope = __webpack_require__(1230); -Line.Random = __webpack_require__(168); +Line.Random = __webpack_require__(169); Line.ReflectAngle = __webpack_require__(1231); Line.Rotate = __webpack_require__(1232); Line.RotateAroundPoint = __webpack_require__(1233); -Line.RotateAroundXY = __webpack_require__(231); +Line.RotateAroundXY = __webpack_require__(233); Line.SetToAngle = __webpack_require__(1234); Line.Slope = __webpack_require__(1235); Line.Width = __webpack_require__(1236); @@ -171151,7 +171177,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); /** * Extends the start and end points of a Line by the given amounts. @@ -171423,7 +171449,7 @@ module.exports = GetNearestPoint; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); var Point = __webpack_require__(4); /** @@ -171542,7 +171568,7 @@ module.exports = Height; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); /** * Returns the x component of the normal vector of the given line. @@ -171573,7 +171599,7 @@ module.exports = NormalX; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); /** * The Y value of the normal of the given line. @@ -171670,8 +171696,8 @@ module.exports = PerpSlope; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Angle = __webpack_require__(92); -var NormalAngle = __webpack_require__(475); +var Angle = __webpack_require__(93); +var NormalAngle = __webpack_require__(491); /** * Calculate the reflected angle between two lines. @@ -171704,7 +171730,7 @@ module.exports = ReflectAngle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(231); +var RotateAroundXY = __webpack_require__(233); /** * Rotate a line around its midpoint by the given angle in radians. @@ -171740,7 +171766,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(231); +var RotateAroundXY = __webpack_require__(233); /** * Rotate a line around a point by the given angle in radians. @@ -171876,14 +171902,14 @@ module.exports = Width; var Mesh = { - Face: __webpack_require__(111), + Face: __webpack_require__(113), GenerateGridVerts: __webpack_require__(1238), - GenerateObjVerts: __webpack_require__(458), - GenerateVerts: __webpack_require__(457), - ParseObj: __webpack_require__(476), - ParseObjMaterial: __webpack_require__(477), + GenerateObjVerts: __webpack_require__(474), + GenerateVerts: __webpack_require__(473), + ParseObj: __webpack_require__(492), + ParseObjMaterial: __webpack_require__(493), RotateFace: __webpack_require__(1239), - Vertex: __webpack_require__(113) + Vertex: __webpack_require__(115) }; @@ -171900,11 +171926,11 @@ module.exports = Mesh; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Face = __webpack_require__(111); +var Face = __webpack_require__(113); var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(65); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); +var Matrix4 = __webpack_require__(67); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); var tempPosition = new Vector3(); var tempRotation = new Vector3(); @@ -172215,8 +172241,8 @@ Point.CopyFrom = __webpack_require__(1243); Point.Equals = __webpack_require__(1244); Point.Floor = __webpack_require__(1245); Point.GetCentroid = __webpack_require__(1246); -Point.GetMagnitude = __webpack_require__(478); -Point.GetMagnitudeSq = __webpack_require__(479); +Point.GetMagnitude = __webpack_require__(494); +Point.GetMagnitudeSq = __webpack_require__(495); Point.GetRectangleFromPoints = __webpack_require__(1247); Point.Interpolate = __webpack_require__(1248); Point.Invert = __webpack_require__(1249); @@ -172629,7 +172655,7 @@ module.exports = Negative; */ var Point = __webpack_require__(4); -var GetMagnitudeSq = __webpack_require__(479); +var GetMagnitudeSq = __webpack_require__(495); /** * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the @@ -172720,7 +172746,7 @@ module.exports = ProjectUnit; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetMagnitude = __webpack_require__(478); +var GetMagnitude = __webpack_require__(494); /** * Changes the magnitude (length) of a two-dimensional vector without changing its direction. @@ -172764,19 +172790,19 @@ module.exports = SetMagnitude; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Polygon = __webpack_require__(222); +var Polygon = __webpack_require__(224); Polygon.Clone = __webpack_require__(1255); -Polygon.Contains = __webpack_require__(223); +Polygon.Contains = __webpack_require__(225); Polygon.ContainsPoint = __webpack_require__(1256); -Polygon.Earcut = __webpack_require__(67); -Polygon.GetAABB = __webpack_require__(447); +Polygon.Earcut = __webpack_require__(68); +Polygon.GetAABB = __webpack_require__(463); Polygon.GetNumberArray = __webpack_require__(1257); -Polygon.GetPoints = __webpack_require__(448); -Polygon.Perimeter = __webpack_require__(449); +Polygon.GetPoints = __webpack_require__(464); +Polygon.Perimeter = __webpack_require__(465); Polygon.Reverse = __webpack_require__(1258); Polygon.Simplify = __webpack_require__(1259); -Polygon.Smooth = __webpack_require__(450); +Polygon.Smooth = __webpack_require__(466); Polygon.Translate = __webpack_require__(1260); module.exports = Polygon; @@ -172792,7 +172818,7 @@ module.exports = Polygon; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Polygon = __webpack_require__(222); +var Polygon = __webpack_require__(224); /** * Create a new polygon which is a copy of the specified polygon @@ -172822,7 +172848,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(223); +var Contains = __webpack_require__(225); /** * Checks the given Point again the Polygon to see if the Point lays within its vertices. @@ -173395,7 +173421,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetAspectRatio = __webpack_require__(232); +var GetAspectRatio = __webpack_require__(234); /** * Adjusts the target rectangle, changing its width, height and position, @@ -173448,7 +173474,7 @@ module.exports = FitInside; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetAspectRatio = __webpack_require__(232); +var GetAspectRatio = __webpack_require__(234); /** * Adjusts the target rectangle, changing its width, height and position, @@ -173690,7 +173716,7 @@ module.exports = GetSize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CenterOn = __webpack_require__(186); +var CenterOn = __webpack_require__(187); /** @@ -173733,7 +173759,7 @@ module.exports = Inflate; */ var Rectangle = __webpack_require__(10); -var Intersects = __webpack_require__(112); +var Intersects = __webpack_require__(114); /** * Takes two Rectangles and first checks to see if they intersect. @@ -174027,7 +174053,7 @@ module.exports = Overlaps; */ var Point = __webpack_require__(4); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); /** * Returns a Point from the perimeter of a Rectangle based on the given angle. @@ -174083,8 +174109,8 @@ module.exports = PerimeterPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Between = __webpack_require__(191); -var ContainsRect = __webpack_require__(481); +var Between = __webpack_require__(192); +var ContainsRect = __webpack_require__(497); var Point = __webpack_require__(4); /** @@ -174229,25 +174255,25 @@ Triangle.BuildEquilateral = __webpack_require__(1289); Triangle.BuildFromPolygon = __webpack_require__(1290); Triangle.BuildRight = __webpack_require__(1291); Triangle.CenterOn = __webpack_require__(1292); -Triangle.Centroid = __webpack_require__(482); +Triangle.Centroid = __webpack_require__(498); Triangle.CircumCenter = __webpack_require__(1293); Triangle.CircumCircle = __webpack_require__(1294); Triangle.Clone = __webpack_require__(1295); -Triangle.Contains = __webpack_require__(110); -Triangle.ContainsArray = __webpack_require__(230); +Triangle.Contains = __webpack_require__(112); +Triangle.ContainsArray = __webpack_require__(232); Triangle.ContainsPoint = __webpack_require__(1296); Triangle.CopyFrom = __webpack_require__(1297); -Triangle.Decompose = __webpack_require__(473); +Triangle.Decompose = __webpack_require__(489); Triangle.Equals = __webpack_require__(1298); -Triangle.GetPoint = __webpack_require__(454); -Triangle.GetPoints = __webpack_require__(455); -Triangle.InCenter = __webpack_require__(484); +Triangle.GetPoint = __webpack_require__(470); +Triangle.GetPoints = __webpack_require__(471); +Triangle.InCenter = __webpack_require__(500); Triangle.Perimeter = __webpack_require__(1299); -Triangle.Offset = __webpack_require__(483); -Triangle.Random = __webpack_require__(177); +Triangle.Offset = __webpack_require__(499); +Triangle.Random = __webpack_require__(178); Triangle.Rotate = __webpack_require__(1300); Triangle.RotateAroundPoint = __webpack_require__(1301); -Triangle.RotateAroundXY = __webpack_require__(233); +Triangle.RotateAroundXY = __webpack_require__(235); module.exports = Triangle; @@ -174345,7 +174371,7 @@ module.exports = BuildEquilateral; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var EarCut = __webpack_require__(67); +var EarCut = __webpack_require__(68); var Triangle = __webpack_require__(82); /** @@ -174470,8 +174496,8 @@ module.exports = BuildRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Centroid = __webpack_require__(482); -var Offset = __webpack_require__(483); +var Centroid = __webpack_require__(498); +var Offset = __webpack_require__(499); /** * @callback CenterFunction @@ -174599,7 +174625,7 @@ module.exports = CircumCenter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); // Adapted from https://gist.github.com/mutoo/5617691 @@ -174712,7 +174738,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(110); +var Contains = __webpack_require__(112); /** * Tests if a triangle contains a point. @@ -174810,7 +174836,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); /** * Gets the length of the perimeter of the given triangle. @@ -174845,8 +174871,8 @@ module.exports = Perimeter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(233); -var InCenter = __webpack_require__(484); +var RotateAroundXY = __webpack_require__(235); +var InCenter = __webpack_require__(500); /** * Rotates a Triangle about its incenter, which is the point at which its three angle bisectors meet. @@ -174881,7 +174907,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(233); +var RotateAroundXY = __webpack_require__(235); /** * Rotates a Triangle at a certain angle about a given Point or object with public `x` and `y` properties. @@ -174915,8 +174941,8 @@ module.exports = RotateAroundPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(198); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(200); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Input @@ -174924,16 +174950,16 @@ var Extend = __webpack_require__(19); var Input = { - CreatePixelPerfectHandler: __webpack_require__(485), - CreateInteractiveObject: __webpack_require__(486), + CreatePixelPerfectHandler: __webpack_require__(501), + CreateInteractiveObject: __webpack_require__(502), Events: __webpack_require__(49), Gamepad: __webpack_require__(1303), - InputManager: __webpack_require__(387), + InputManager: __webpack_require__(403), InputPlugin: __webpack_require__(1315), - InputPluginCache: __webpack_require__(150), + InputPluginCache: __webpack_require__(151), Keyboard: __webpack_require__(1316), Mouse: __webpack_require__(1330), - Pointer: __webpack_require__(390), + Pointer: __webpack_require__(406), Touch: __webpack_require__(1331) }; @@ -174960,10 +174986,10 @@ module.exports = Input; module.exports = { - Axis: __webpack_require__(487), - Button: __webpack_require__(488), - Events: __webpack_require__(234), - Gamepad: __webpack_require__(489), + Axis: __webpack_require__(503), + Button: __webpack_require__(504), + Events: __webpack_require__(236), + Gamepad: __webpack_require__(505), GamepadPlugin: __webpack_require__(1310), Configs: __webpack_require__(1311) @@ -175161,10 +175187,10 @@ module.exports = 'up'; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(234); -var Gamepad = __webpack_require__(489); +var Events = __webpack_require__(236); +var Gamepad = __webpack_require__(505); var GetValue = __webpack_require__(6); -var InputPluginCache = __webpack_require__(150); +var InputPluginCache = __webpack_require__(151); var InputEvents = __webpack_require__(49); /** @@ -175968,27 +175994,27 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); -var CircleContains = __webpack_require__(62); +var Circle = __webpack_require__(62); +var CircleContains = __webpack_require__(63); var Class = __webpack_require__(0); -var CONST = __webpack_require__(198); -var CreateInteractiveObject = __webpack_require__(486); -var CreatePixelPerfectHandler = __webpack_require__(485); +var CONST = __webpack_require__(200); +var CreateInteractiveObject = __webpack_require__(502); +var CreatePixelPerfectHandler = __webpack_require__(501); var DistanceBetween = __webpack_require__(48); -var Ellipse = __webpack_require__(106); -var EllipseContains = __webpack_require__(107); +var Ellipse = __webpack_require__(108); +var EllipseContains = __webpack_require__(109); var Events = __webpack_require__(49); var EventEmitter = __webpack_require__(9); var GetFastValue = __webpack_require__(2); var GEOM_CONST = __webpack_require__(55); -var InputPluginCache = __webpack_require__(150); +var InputPluginCache = __webpack_require__(151); var IsPlainObject = __webpack_require__(7); var PluginCache = __webpack_require__(24); var Rectangle = __webpack_require__(10); var RectangleContains = __webpack_require__(56); var SceneEvents = __webpack_require__(21); var Triangle = __webpack_require__(82); -var TriangleContains = __webpack_require__(110); +var TriangleContains = __webpack_require__(112); /** * @classdesc @@ -179156,19 +179182,19 @@ module.exports = InputPlugin; module.exports = { - Events: __webpack_require__(151), + Events: __webpack_require__(152), - KeyboardManager: __webpack_require__(388), + KeyboardManager: __webpack_require__(404), KeyboardPlugin: __webpack_require__(1324), - Key: __webpack_require__(490), - KeyCodes: __webpack_require__(140), + Key: __webpack_require__(506), + KeyCodes: __webpack_require__(141), - KeyCombo: __webpack_require__(491), + KeyCombo: __webpack_require__(507), - AdvanceKeyCombo: __webpack_require__(493), - ProcessKeyCombo: __webpack_require__(492), - ResetKeyCombo: __webpack_require__(494), + AdvanceKeyCombo: __webpack_require__(509), + ProcessKeyCombo: __webpack_require__(508), + ResetKeyCombo: __webpack_require__(510), JustDown: __webpack_require__(1326), JustUp: __webpack_require__(1327), @@ -179428,14 +179454,14 @@ module.exports = 'up'; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(151); +var Events = __webpack_require__(152); var GameEvents = __webpack_require__(22); var GetValue = __webpack_require__(6); var InputEvents = __webpack_require__(49); -var InputPluginCache = __webpack_require__(150); -var Key = __webpack_require__(490); -var KeyCodes = __webpack_require__(140); -var KeyCombo = __webpack_require__(491); +var InputPluginCache = __webpack_require__(151); +var Key = __webpack_require__(506); +var KeyCodes = __webpack_require__(141); +var KeyCombo = __webpack_require__(507); var KeyMap = __webpack_require__(1325); var SceneEvents = __webpack_require__(21); var SnapFloor = __webpack_require__(76); @@ -180361,7 +180387,7 @@ module.exports = KeyboardPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var KeyCodes = __webpack_require__(140); +var KeyCodes = __webpack_require__(141); var KeyMap = {}; @@ -180542,7 +180568,7 @@ module.exports = UpDuration; /* eslint-disable */ module.exports = { - MouseManager: __webpack_require__(389) + MouseManager: __webpack_require__(405) }; /* eslint-enable */ @@ -180565,7 +180591,7 @@ module.exports = { /* eslint-disable */ module.exports = { - TouchManager: __webpack_require__(391) + TouchManager: __webpack_require__(407) }; /* eslint-enable */ @@ -180582,7 +180608,7 @@ module.exports = { */ var CONST = __webpack_require__(20); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Loader @@ -180590,18 +180616,18 @@ var Extend = __webpack_require__(19); var Loader = { - Events: __webpack_require__(90), + Events: __webpack_require__(91), FileTypes: __webpack_require__(1333), File: __webpack_require__(23), FileTypesManager: __webpack_require__(8), - GetURL: __webpack_require__(152), + GetURL: __webpack_require__(153), LoaderPlugin: __webpack_require__(1359), - MergeXHRSettings: __webpack_require__(235), + MergeXHRSettings: __webpack_require__(237), MultiFile: __webpack_require__(47), - XHRLoader: __webpack_require__(495), - XHRSettings: __webpack_require__(153) + XHRLoader: __webpack_require__(511), + XHRSettings: __webpack_require__(154) }; @@ -180631,17 +180657,17 @@ module.exports = { AsepriteFile: __webpack_require__(1335), AtlasJSONFile: __webpack_require__(1336), AtlasXMLFile: __webpack_require__(1337), - AudioFile: __webpack_require__(496), + AudioFile: __webpack_require__(512), AudioSpriteFile: __webpack_require__(1338), BinaryFile: __webpack_require__(1339), BitmapFontFile: __webpack_require__(1340), CSSFile: __webpack_require__(1341), GLSLFile: __webpack_require__(1342), - HTML5AudioFile: __webpack_require__(497), + HTML5AudioFile: __webpack_require__(513), HTMLFile: __webpack_require__(1343), HTMLTextureFile: __webpack_require__(1344), - ImageFile: __webpack_require__(69), - JSONFile: __webpack_require__(58), + ImageFile: __webpack_require__(70), + JSONFile: __webpack_require__(59), MultiAtlasFile: __webpack_require__(1345), MultiScriptFile: __webpack_require__(1346), OBJFile: __webpack_require__(1347), @@ -180649,16 +180675,16 @@ module.exports = { PluginFile: __webpack_require__(1349), SceneFile: __webpack_require__(1350), ScenePluginFile: __webpack_require__(1351), - ScriptFile: __webpack_require__(498), + ScriptFile: __webpack_require__(514), SpriteSheetFile: __webpack_require__(1352), SVGFile: __webpack_require__(1353), - TextFile: __webpack_require__(237), + TextFile: __webpack_require__(239), TilemapCSVFile: __webpack_require__(1354), TilemapImpactFile: __webpack_require__(1355), TilemapJSONFile: __webpack_require__(1356), UnityAtlasFile: __webpack_require__(1357), VideoFile: __webpack_require__(1358), - XMLFile: __webpack_require__(236) + XMLFile: __webpack_require__(238) }; @@ -180675,8 +180701,8 @@ module.exports = { var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var LoaderEvents = __webpack_require__(90); +var JSONFile = __webpack_require__(59); +var LoaderEvents = __webpack_require__(91); /** * @classdesc @@ -180877,9 +180903,9 @@ module.exports = AnimationJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -181147,9 +181173,9 @@ module.exports = AsepriteFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -181394,10 +181420,10 @@ module.exports = AtlasJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var XMLFile = __webpack_require__(236); +var XMLFile = __webpack_require__(238); /** * @classdesc @@ -181632,12 +181658,12 @@ module.exports = AtlasXMLFile; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AudioFile = __webpack_require__(496); +var AudioFile = __webpack_require__(512); var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -182107,11 +182133,11 @@ module.exports = BinaryFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ParseXMLBitmapFont = __webpack_require__(207); -var XMLFile = __webpack_require__(236); +var ParseXMLBitmapFont = __webpack_require__(209); +var XMLFile = __webpack_require__(238); /** * @classdesc @@ -182524,7 +182550,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var Shader = __webpack_require__(374); +var Shader = __webpack_require__(390); /** * @classdesc @@ -183365,9 +183391,9 @@ module.exports = HTMLTextureFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -183700,7 +183726,7 @@ var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ScriptFile = __webpack_require__(498); +var ScriptFile = __webpack_require__(514); /** * @classdesc @@ -183917,9 +183943,9 @@ var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ParseObj = __webpack_require__(476); -var ParseObjMaterial = __webpack_require__(477); -var TextFile = __webpack_require__(237); +var ParseObj = __webpack_require__(492); +var ParseObjMaterial = __webpack_require__(493); +var TextFile = __webpack_require__(239); /** * @classdesc @@ -184169,7 +184195,7 @@ module.exports = OBJFile; var Class = __webpack_require__(0); var CONST = __webpack_require__(20); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); /** * @classdesc @@ -185024,7 +185050,7 @@ module.exports = ScenePluginFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); /** * @classdesc @@ -185558,7 +185584,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var TILEMAP_FORMATS = __webpack_require__(37); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -185749,8 +185775,8 @@ module.exports = TilemapCSVFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var TILEMAP_FORMATS = __webpack_require__(37); +var JSONFile = __webpack_require__(59); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -185905,8 +185931,8 @@ module.exports = TilemapImpactFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var TILEMAP_FORMATS = __webpack_require__(37); +var JSONFile = __webpack_require__(59); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -186062,10 +186088,10 @@ module.exports = TilemapJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var TextFile = __webpack_require__(237); +var TextFile = __webpack_require__(239); /** * @classdesc @@ -186303,7 +186329,7 @@ var Class = __webpack_require__(0); var CONST = __webpack_require__(20); var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); -var GetURL = __webpack_require__(152); +var GetURL = __webpack_require__(153); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); @@ -186695,14 +186721,14 @@ module.exports = VideoFile; var Class = __webpack_require__(0); var CONST = __webpack_require__(20); -var CustomSet = __webpack_require__(147); +var CustomSet = __webpack_require__(148); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(90); +var Events = __webpack_require__(91); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var XHRSettings = __webpack_require__(153); +var XHRSettings = __webpack_require__(154); /** * @classdesc @@ -187776,8 +187802,8 @@ module.exports = LoaderPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(60); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Physics.Arcade @@ -187786,22 +187812,22 @@ var Extend = __webpack_require__(19); var Arcade = { ArcadePhysics: __webpack_require__(1361), - Body: __webpack_require__(505), - Collider: __webpack_require__(506), - Components: __webpack_require__(238), - Events: __webpack_require__(240), - Factory: __webpack_require__(499), - GetOverlapX: __webpack_require__(241), - GetOverlapY: __webpack_require__(242), - SeparateX: __webpack_require__(515), - SeparateY: __webpack_require__(516), - Group: __webpack_require__(502), - Image: __webpack_require__(500), - Sprite: __webpack_require__(154), - StaticBody: __webpack_require__(517), - StaticGroup: __webpack_require__(503), + Body: __webpack_require__(521), + Collider: __webpack_require__(522), + Components: __webpack_require__(240), + Events: __webpack_require__(242), + Factory: __webpack_require__(515), + GetOverlapX: __webpack_require__(243), + GetOverlapY: __webpack_require__(244), + SeparateX: __webpack_require__(531), + SeparateY: __webpack_require__(532), + Group: __webpack_require__(518), + Image: __webpack_require__(516), + Sprite: __webpack_require__(155), + StaticBody: __webpack_require__(533), + StaticGroup: __webpack_require__(519), Tilemap: __webpack_require__(1385), - World: __webpack_require__(504) + World: __webpack_require__(520) }; @@ -187822,18 +187848,18 @@ module.exports = Arcade; */ var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var DistanceBetween = __webpack_require__(48); var DistanceSquared = __webpack_require__(347); -var Factory = __webpack_require__(499); +var Factory = __webpack_require__(515); var GetFastValue = __webpack_require__(2); -var Merge = __webpack_require__(142); -var OverlapCirc = __webpack_require__(501); -var OverlapRect = __webpack_require__(239); +var Merge = __webpack_require__(143); +var OverlapCirc = __webpack_require__(517); +var OverlapRect = __webpack_require__(241); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); var Vector2 = __webpack_require__(3); -var World = __webpack_require__(504); +var World = __webpack_require__(520); /** * @classdesc @@ -190764,13 +190790,13 @@ module.exports = { var Tilemap = { - ProcessTileCallbacks: __webpack_require__(508), - ProcessTileSeparationX: __webpack_require__(512), - ProcessTileSeparationY: __webpack_require__(514), - SeparateTile: __webpack_require__(510), - TileCheckX: __webpack_require__(511), - TileCheckY: __webpack_require__(513), - TileIntersectsBody: __webpack_require__(243) + ProcessTileCallbacks: __webpack_require__(524), + ProcessTileSeparationX: __webpack_require__(528), + ProcessTileSeparationY: __webpack_require__(530), + SeparateTile: __webpack_require__(526), + TileCheckX: __webpack_require__(527), + TileCheckY: __webpack_require__(529), + TileIntersectsBody: __webpack_require__(245) }; @@ -190804,10 +190830,10 @@ module.exports = Tilemap; module.exports = { - BasePlugin: __webpack_require__(520), - DefaultPlugins: __webpack_require__(193), + BasePlugin: __webpack_require__(536), + DefaultPlugins: __webpack_require__(194), PluginCache: __webpack_require__(24), - PluginManager: __webpack_require__(392), + PluginManager: __webpack_require__(408), ScenePlugin: __webpack_require__(1398) }; @@ -190823,7 +190849,7 @@ module.exports = { * @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License} */ -var BasePlugin = __webpack_require__(520); +var BasePlugin = __webpack_require__(536); var Class = __webpack_require__(0); var SceneEvents = __webpack_require__(21); @@ -190951,8 +190977,675 @@ module.exports = ScenePlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var CONST = __webpack_require__(196); +/** + * @namespace Phaser.Renderer + */ + +/** + * @namespace Phaser.Types.Renderer + */ + +module.exports = { + + Canvas: __webpack_require__(1400), + Events: __webpack_require__(88), + Snapshot: __webpack_require__(1401), + WebGL: __webpack_require__(1402) + +}; + + +/***/ }), +/* 1400 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Canvas + */ + +module.exports = { + + CanvasRenderer: __webpack_require__(362), + GetBlendModes: __webpack_require__(364), + SetTransform: __webpack_require__(30) + +}; + + +/***/ }), +/* 1401 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Snapshot + */ + +module.exports = { + + Canvas: __webpack_require__(363), + WebGL: __webpack_require__(377) + +}; + + +/***/ }), +/* 1402 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WEBGL_CONST = __webpack_require__(104); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Renderer.WebGL + */ + +var WebGL = { + + PipelineManager: __webpack_require__(366), + Pipelines: __webpack_require__(1403), + RenderTarget: __webpack_require__(139), + Utils: __webpack_require__(12), + WebGLPipeline: __webpack_require__(57), + WebGLRenderer: __webpack_require__(365), + WebGLShader: __webpack_require__(369) + +}; + +// Merge in the consts + +WebGL = Extend(false, WebGL, WEBGL_CONST); + +// Export it + +module.exports = WebGL; + + +/***/ }), +/* 1403 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(65); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Renderer.WebGL.Pipelines + */ + +var Pipelines = { + + BitmapMaskPipeline: __webpack_require__(367), + Events: __webpack_require__(368), + GraphicsPipeline: __webpack_require__(370), + LightPipeline: __webpack_require__(371), + MultiPipeline: __webpack_require__(105), + PointLightPipeline: __webpack_require__(372), + PostFXPipeline: __webpack_require__(1404), + RopePipeline: __webpack_require__(373), + SinglePipeline: __webpack_require__(374), + UtilityPipeline: __webpack_require__(375) + +}; + +// Merge in the consts + +Pipelines = Extend(false, Pipelines, CONST); + +// Export it + +module.exports = Pipelines; + + +/***/ }), +/* 1404 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var ColorMatrix = __webpack_require__(195); +var GetFastValue = __webpack_require__(2); +var ShaderSourceFS = __webpack_require__(1405); +var ShaderSourceVS = __webpack_require__(376); +var WebGLPipeline = __webpack_require__(57); + +/** + * @classdesc + * The Post FX Pipeline is a special kind of pipeline specifically for handling post + * processing effects. Where-as a standard Pipeline allows you to control the process + * of rendering Game Objects by configuring the shaders and attributes used to draw them, + * a Post FX Pipeline is designed to allow you to apply processing _after_ the Game Object/s + * have been rendered. Typical examples of post processing effects are bloom filters, + * blurs, light effects and color manipulation. + * + * The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad + * in it. Game Objects can have a Post Pipeline set on them. Those objects are then rendered + * using their standard pipeline, but are redirected to the Render Targets owned by the + * post pipeline, which can then apply their own shaders and effects, before passing them + * back to the main renderer. + * + * Please see the Phaser 3 examples for further details on this extensive subject. + * + * The default fragment shader it uses can be found in `shaders/src/PostFX.frag`. + * The default vertex shader it uses can be found in `shaders/src/Quad.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * + * The vertices array layout is: + * + * -1, 1 B----C 1, 1 + * 0, 1 | /| 1, 1 + * | / | + * | / | + * |/ | + * -1, -1 A----D 1, -1 + * 0, 0 1, 0 + * + * A = -1, -1 (pos) and 0, 0 (uv) + * B = -1, 1 (pos) and 0, 1 (uv) + * C = 1, 1 (pos) and 1, 1 (uv) + * D = 1, -1 (pos) and 1, 0 (uv) + * + * First tri: A, B, C + * Second tri: A, C, D + * + * Array index: + * + * 0 = Tri 1 - Vert A - x pos + * 1 = Tri 1 - Vert A - y pos + * 2 = Tri 1 - Vert A - uv u + * 3 = Tri 1 - Vert A - uv v + * + * 4 = Tri 1 - Vert B - x pos + * 5 = Tri 1 - Vert B - y pos + * 6 = Tri 1 - Vert B - uv u + * 7 = Tri 1 - Vert B - uv v + * + * 8 = Tri 1 - Vert C - x pos + * 9 = Tri 1 - Vert C - y pos + * 10 = Tri 1 - Vert C - uv u + * 11 = Tri 1 - Vert C - uv v + * + * 12 = Tri 2 - Vert A - x pos + * 13 = Tri 2 - Vert A - y pos + * 14 = Tri 2 - Vert A - uv u + * 15 = Tri 2 - Vert A - uv v + * + * 16 = Tri 2 - Vert C - x pos + * 17 = Tri 2 - Vert C - y pos + * 18 = Tri 2 - Vert C - uv u + * 19 = Tri 2 - Vert C - uv v + * + * 20 = Tri 2 - Vert D - x pos + * 21 = Tri 2 - Vert D - y pos + * 22 = Tri 2 - Vert D - uv u + * 23 = Tri 2 - Vert D - uv v + * + * @class PostFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var PostFXPipeline = new Class({ + + Extends: WebGLPipeline, + + initialize: + + function PostFXPipeline (config) + { + config.renderTarget = GetFastValue(config, 'renderTarget', 1); + config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS); + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inTexCoord', + size: 2 + } + ]); + config.batchSize = 1; + config.vertices = [ + -1, -1, 0, 0, + -1, 1, 0, 1, + 1, 1, 1, 1, + -1, -1, 0, 0, + 1, 1, 1, 1, + 1, -1, 1, 0 + ]; + + WebGLPipeline.call(this, config); + + this.isPostFX = true; + + /** + * If this post-pipeline belongs to a Game Object or Camera, this contains a reference to it. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.50.0 + */ + this.gameObject; + + /** + * A Color Matrix instance belonging to this pipeline. + * + * Used during calls to the `drawFrame` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#colorMatrix + * @type {Phaser.Display.ColorMatrix} + * @since 3.50.0 + */ + this.colorMatrix = new ColorMatrix(); + + /** + * A reference to the Full Frame 1 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is the full size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.fullFrame1; + + /** + * A reference to the Full Frame 2 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is the full size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.fullFrame2; + + /** + * A reference to the Half Frame 1 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is half the size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.halfFrame1; + + /** + * A reference to the Half Frame 2 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is half the size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.halfFrame2; + + if (this.renderer.isBooted) + { + this.manager = this.renderer.pipelines; + + this.boot(); + } + }, + + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + var utility = this.manager.UTILITY_PIPELINE; + + this.fullFrame1 = utility.fullFrame1; + this.fullFrame2 = utility.fullFrame2; + this.halfFrame1 = utility.halfFrame1; + this.halfFrame2 = utility.halfFrame2; + + this.set1i('uMainSampler', 0); + }, + + onDraw: function (renderTarget) + { + this.bindAndDraw(renderTarget); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * You can optionally set the brightness factor of the copy. + * + * The difference between this method and `drawFrame` is that this method + * uses a faster copy shader, where only the brightness can be modified. + * If you need color level manipulation, see `drawFrame` instead. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [brightness=1] - The brightness value applied to the frame copy. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + copyFrame: function (source, target, brightness, clear, clearAlpha) + { + this.manager.copyFrame(source, target, brightness, clear, clearAlpha); + }, + + /** + * Pops the framebuffer from the renderers FBO stack and sets that as the active target, + * then draws the `source` Render Target to it. It then resets the renderer textures. + * + * This should be done when you need to draw the _final_ results of a pipeline to the game + * canvas, or the next framebuffer in line on the FBO stack. You should only call this once + * in the `onDraw` handler and it should be the final thing called. Be careful not to call + * this if you need to actually use the pipeline shader, instead of the copy shader. In + * those cases, use the `bindAndDraw` method. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyToGame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + */ + copyToGame: function (source) + { + this.manager.copyToGame(source); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target, using the + * given Color Matrix. + * + * The difference between this method and `copyFrame` is that this method + * uses a color matrix shader, where you have full control over the luminance + * values used during the copy. If you don't need this, you can use the faster + * `copyFrame` method instead. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#drawFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + drawFrame: function (source, target, clearAlpha) + { + this.manager.drawFrame(source, target, clearAlpha, this.colorMatrix); + }, + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using a linear blend effect, which is controlled by the `strength` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFrames + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [strength=1] - The strength of the blend. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + blendFrames: function (source1, source2, target, strength, clearAlpha) + { + this.manager.blendFrames(source1, source2, target, strength, clearAlpha); + }, + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using an additive blend effect, which is controlled by the `strength` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFramesAdditive + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [strength=1] - The strength of the blend. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) + { + this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha); + }, + + /** + * Clears the given Render Target. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#clearFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + clearFrame: function (target, clearAlpha) + { + this.manager.clearFrame(target, clearAlpha); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * The difference with this copy is that no resizing takes place. If the `source` + * Render Target is larger than the `target` then only a portion the same size as + * the `target` dimensions is copied across. + * + * You can optionally set the brightness factor of the copy. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blitFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + * @param {number} [brightness=1] - The brightness value applied to the frame copy. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + * @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode? + */ + blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) + { + this.manager.blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); + }, + + /** + * Binds the `source` Render Target and then copies a section of it to the `target` Render Target. + * + * This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't + * require the use of any shaders. Remember the coordinates are given in standard WebGL format, + * where x and y specify the lower-left corner of the section, not the top-left. Also, the + * copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes + * place. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrameRect + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + * @param {number} x - The x coordinate of the lower left corner where to start copying. + * @param {number} y - The y coordinate of the lower left corner where to start copying. + * @param {number} width - The width of the texture. + * @param {number} height - The height of the texture. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) + { + this.manager.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); + }, + + /** + * Binds this pipeline and draws the `source` Render Target to the `target` Render Target. + * + * If no `target` is specified, it will pop the framebuffer from the Renderers FBO stack + * and use that instead, which should be done when you need to draw the final results of + * this pipeline to the game canvas. + * + * You can optionally set the shader to be used for the draw here, if this is a multi-shader + * pipeline. By default `currentShader` will be used. If you need to set a shader but not + * a target, just pass `null` as the `target` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bindAndDraw + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to draw to. If not set, it will pop the fbo from the stack. + * @param {boolean} [clear=true] - Clear the target before copying? Only used if `target` parameter is set. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to use during the draw. + */ + bindAndDraw: function (source, target, clear, clearAlpha, currentShader) + { + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } + + var gl = this.gl; + var renderer = this.renderer; + + this.bind(currentShader); + + this.set1i('uMainSampler', 0); + + if (target) + { + gl.viewport(0, 0, target.width, target.height); + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); + + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } + + gl.clear(gl.COLOR_BUFFER_BIT); + } + } + else + { + renderer.popFramebuffer(false, false, false); + + if (!renderer.currentFramebuffer) + { + gl.viewport(0, 0, renderer.width, renderer.height); + } + } + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); + + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); + + if (!target) + { + renderer.resetTextures(); + } + else + { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + } + +}); + +module.exports = PostFXPipeline; + + +/***/ }), +/* 1405 */ +/***/ (function(module, exports) { + +module.exports = [ + '#define SHADER_NAME PHASER_POSTFX_FS', + '', + 'precision mediump float;', + '', + 'uniform sampler2D uMainSampler;', + '', + 'varying vec2 outTexCoord;', + '', + 'void main ()', + '{', + ' gl_FragColor = texture2D(uMainSampler, outTexCoord);', + '}', + '' +].join('\n'); + + +/***/ }), +/* 1406 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Extend = __webpack_require__(17); +var CONST = __webpack_require__(198); /** * @namespace Phaser.Scale @@ -190980,12 +191673,12 @@ var CONST = __webpack_require__(196); var Scale = { - Center: __webpack_require__(381), + Center: __webpack_require__(397), Events: __webpack_require__(101), - Orientation: __webpack_require__(382), - ScaleManager: __webpack_require__(393), - ScaleModes: __webpack_require__(383), - Zoom: __webpack_require__(384) + Orientation: __webpack_require__(398), + ScaleManager: __webpack_require__(409), + ScaleModes: __webpack_require__(399), + Zoom: __webpack_require__(400) }; @@ -190998,7 +191691,7 @@ module.exports = Scale; /***/ }), -/* 1400 */ +/* 1407 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -191007,8 +191700,8 @@ module.exports = Scale; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(141); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(142); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Scenes @@ -191017,12 +191710,12 @@ var Extend = __webpack_require__(19); var Scene = { Events: __webpack_require__(21), - GetPhysicsPlugins: __webpack_require__(397), - GetScenePlugins: __webpack_require__(398), - SceneManager: __webpack_require__(395), - ScenePlugin: __webpack_require__(1401), - Settings: __webpack_require__(399), - Systems: __webpack_require__(199) + GetPhysicsPlugins: __webpack_require__(413), + GetScenePlugins: __webpack_require__(414), + SceneManager: __webpack_require__(411), + ScenePlugin: __webpack_require__(1408), + Settings: __webpack_require__(415), + Systems: __webpack_require__(201) }; @@ -191033,7 +191726,7 @@ module.exports = Scene; /***/ }), -/* 1401 */ +/* 1408 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -191042,7 +191735,7 @@ module.exports = Scene; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Events = __webpack_require__(21); var GetFastValue = __webpack_require__(2); @@ -192043,7 +192736,7 @@ module.exports = ScenePlugin; /***/ }), -/* 1402 */ +/* 1409 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192058,19 +192751,19 @@ module.exports = ScenePlugin; module.exports = { - Events: __webpack_require__(416), - List: __webpack_require__(105), + Events: __webpack_require__(432), + List: __webpack_require__(107), Map: __webpack_require__(99), - ProcessQueue: __webpack_require__(206), - RTree: __webpack_require__(509), - Set: __webpack_require__(147), - Size: __webpack_require__(394) + ProcessQueue: __webpack_require__(208), + RTree: __webpack_require__(525), + Set: __webpack_require__(148), + Size: __webpack_require__(410) }; /***/ }), -/* 1403 */ +/* 1410 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192079,8 +192772,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var FilterMode = __webpack_require__(1404); +var Extend = __webpack_require__(17); +var FilterMode = __webpack_require__(1411); /** * @namespace Phaser.Textures @@ -192106,14 +192799,14 @@ var FilterMode = __webpack_require__(1404); var Textures = { - CanvasTexture: __webpack_require__(401), + CanvasTexture: __webpack_require__(417), Events: __webpack_require__(103), FilterMode: FilterMode, - Frame: __webpack_require__(104), - Parsers: __webpack_require__(403), - Texture: __webpack_require__(201), - TextureManager: __webpack_require__(400), - TextureSource: __webpack_require__(402) + Frame: __webpack_require__(106), + Parsers: __webpack_require__(419), + Texture: __webpack_require__(203), + TextureManager: __webpack_require__(416), + TextureSource: __webpack_require__(418) }; @@ -192123,7 +192816,7 @@ module.exports = Textures; /***/ }), -/* 1404 */ +/* 1411 */ /***/ (function(module, exports) { /** @@ -192167,7 +192860,7 @@ module.exports = CONST; /***/ }), -/* 1405 */ +/* 1412 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192176,8 +192869,8 @@ module.exports = CONST; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var CONST = __webpack_require__(1406); +var Extend = __webpack_require__(17); +var CONST = __webpack_require__(1413); /** * @namespace Phaser.Tilemaps @@ -192190,23 +192883,23 @@ var CONST = __webpack_require__(1406); var Tilemaps = { - Components: __webpack_require__(245), - Parsers: __webpack_require__(1439), + Components: __webpack_require__(247), + Parsers: __webpack_require__(1446), - Formats: __webpack_require__(37), - ImageCollection: __webpack_require__(556), - ParseToTilemap: __webpack_require__(256), + Formats: __webpack_require__(38), + ImageCollection: __webpack_require__(572), + ParseToTilemap: __webpack_require__(258), Tile: __webpack_require__(83), - Tilemap: __webpack_require__(560), - TilemapCreator: __webpack_require__(1445), - TilemapFactory: __webpack_require__(1446), - Tileset: __webpack_require__(119), - TilemapLayer: __webpack_require__(561), + Tilemap: __webpack_require__(576), + TilemapCreator: __webpack_require__(1452), + TilemapFactory: __webpack_require__(1453), + Tileset: __webpack_require__(121), + TilemapLayer: __webpack_require__(577), Orientation: __webpack_require__(29), - LayerData: __webpack_require__(117), - MapData: __webpack_require__(118), - ObjectLayer: __webpack_require__(552) + LayerData: __webpack_require__(119), + MapData: __webpack_require__(120), + ObjectLayer: __webpack_require__(568) }; @@ -192216,7 +192909,7 @@ module.exports = Tilemaps; /***/ }), -/* 1406 */ +/* 1413 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192235,7 +192928,7 @@ module.exports = CONST; /***/ }), -/* 1407 */ +/* 1414 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192245,7 +192938,7 @@ module.exports = CONST; */ var GetTilesWithin = __webpack_require__(26); -var CalculateFacesWithin = __webpack_require__(60); +var CalculateFacesWithin = __webpack_require__(61); /** * Copies the tiles in the source rectangular area to a new destination (all specified in tile @@ -192301,7 +192994,7 @@ module.exports = Copy; /***/ }), -/* 1408 */ +/* 1415 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192311,7 +193004,7 @@ module.exports = Copy; */ var GetTilesWithin = __webpack_require__(26); -var ReplaceByIndex = __webpack_require__(522); +var ReplaceByIndex = __webpack_require__(538); /** * Creates a Sprite for every object matching the given tile indexes in the layer. You can @@ -192388,7 +193081,7 @@ module.exports = CreateFromTiles; /***/ }), -/* 1409 */ +/* 1416 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192398,8 +193091,8 @@ module.exports = CreateFromTiles; */ var GetTilesWithin = __webpack_require__(26); -var CalculateFacesWithin = __webpack_require__(60); -var SetTileCollision = __webpack_require__(71); +var CalculateFacesWithin = __webpack_require__(61); +var SetTileCollision = __webpack_require__(72); /** * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the @@ -192441,7 +193134,7 @@ module.exports = Fill; /***/ }), -/* 1410 */ +/* 1417 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192484,7 +193177,7 @@ module.exports = FilterTiles; /***/ }), -/* 1411 */ +/* 1418 */ /***/ (function(module, exports) { /** @@ -192570,7 +193263,7 @@ module.exports = FindByIndex; /***/ }), -/* 1412 */ +/* 1419 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192621,7 +193314,7 @@ module.exports = FindTile; /***/ }), -/* 1413 */ +/* 1420 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192667,7 +193360,7 @@ module.exports = ForEachTile; /***/ }), -/* 1414 */ +/* 1421 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192677,11 +193370,11 @@ module.exports = ForEachTile; */ var CONST = __webpack_require__(29); -var CullTiles = __webpack_require__(524); -var HexagonalCullTiles = __webpack_require__(525); -var IsometricCullTiles = __webpack_require__(527); +var CullTiles = __webpack_require__(540); +var HexagonalCullTiles = __webpack_require__(541); +var IsometricCullTiles = __webpack_require__(543); var NOOP = __webpack_require__(1); -var StaggeredCullTiles = __webpack_require__(528); +var StaggeredCullTiles = __webpack_require__(544); /** * Gets the correct function to use to cull tiles, based on the map orientation. @@ -192721,7 +193414,7 @@ module.exports = GetCullTilesFunction; /***/ }), -/* 1415 */ +/* 1422 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192730,7 +193423,7 @@ module.exports = GetCullTilesFunction; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTileAt = __webpack_require__(155); +var GetTileAt = __webpack_require__(156); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -192760,7 +193453,7 @@ module.exports = GetTileAtWorldXY; /***/ }), -/* 1416 */ +/* 1423 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192769,9 +193462,9 @@ module.exports = GetTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Geom = __webpack_require__(461); +var Geom = __webpack_require__(477); var GetTilesWithin = __webpack_require__(26); -var Intersects = __webpack_require__(462); +var Intersects = __webpack_require__(478); var NOOP = __webpack_require__(1); var Vector2 = __webpack_require__(3); @@ -192875,7 +193568,7 @@ module.exports = GetTilesWithinShape; /***/ }), -/* 1417 */ +/* 1424 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192886,7 +193579,7 @@ module.exports = GetTilesWithinShape; var CONST = __webpack_require__(29); var NOOP = __webpack_require__(1); -var TileToWorldX = __webpack_require__(247); +var TileToWorldX = __webpack_require__(249); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -192914,7 +193607,7 @@ module.exports = GetTileToWorldXFunction; /***/ }), -/* 1418 */ +/* 1425 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192924,11 +193617,11 @@ module.exports = GetTileToWorldXFunction; */ var CONST = __webpack_require__(29); -var HexagonalTileToWorldXY = __webpack_require__(530); -var IsometricTileToWorldXY = __webpack_require__(531); +var HexagonalTileToWorldXY = __webpack_require__(546); +var IsometricTileToWorldXY = __webpack_require__(547); var NOOP = __webpack_require__(1); -var StaggeredTileToWorldXY = __webpack_require__(532); -var TileToWorldXY = __webpack_require__(533); +var StaggeredTileToWorldXY = __webpack_require__(548); +var TileToWorldXY = __webpack_require__(549); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -192968,7 +193661,7 @@ module.exports = GetTileToWorldXYFunction; /***/ }), -/* 1419 */ +/* 1426 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -192978,10 +193671,10 @@ module.exports = GetTileToWorldXYFunction; */ var CONST = __webpack_require__(29); -var HexagonalTileToWorldY = __webpack_require__(534); +var HexagonalTileToWorldY = __webpack_require__(550); var NOOP = __webpack_require__(1); -var StaggeredTileToWorldY = __webpack_require__(535); -var TileToWorldY = __webpack_require__(248); +var StaggeredTileToWorldY = __webpack_require__(551); +var TileToWorldY = __webpack_require__(250); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -193017,7 +193710,7 @@ module.exports = GetTileToWorldYFunction; /***/ }), -/* 1420 */ +/* 1427 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193028,7 +193721,7 @@ module.exports = GetTileToWorldYFunction; var CONST = __webpack_require__(29); var NOOP = __webpack_require__(1); -var WorldToTileX = __webpack_require__(249); +var WorldToTileX = __webpack_require__(251); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -193056,7 +193749,7 @@ module.exports = GetWorldToTileXFunction; /***/ }), -/* 1421 */ +/* 1428 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193066,11 +193759,11 @@ module.exports = GetWorldToTileXFunction; */ var CONST = __webpack_require__(29); -var HexagonalWorldToTileXY = __webpack_require__(536); -var IsometricWorldToTileXY = __webpack_require__(537); +var HexagonalWorldToTileXY = __webpack_require__(552); +var IsometricWorldToTileXY = __webpack_require__(553); var NOOP = __webpack_require__(1); -var StaggeredWorldToTileXY = __webpack_require__(538); -var WorldToTileXY = __webpack_require__(539); +var StaggeredWorldToTileXY = __webpack_require__(554); +var WorldToTileXY = __webpack_require__(555); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -193110,7 +193803,7 @@ module.exports = GetWorldToTileXYFunction; /***/ }), -/* 1422 */ +/* 1429 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193120,10 +193813,10 @@ module.exports = GetWorldToTileXYFunction; */ var CONST = __webpack_require__(29); -var HexagonalWorldToTileY = __webpack_require__(540); +var HexagonalWorldToTileY = __webpack_require__(556); var NOOP = __webpack_require__(1); -var StaggeredWorldToTileY = __webpack_require__(541); -var WorldToTileY = __webpack_require__(250); +var StaggeredWorldToTileY = __webpack_require__(557); +var WorldToTileY = __webpack_require__(252); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -193159,7 +193852,7 @@ module.exports = GetWorldToTileYFunction; /***/ }), -/* 1423 */ +/* 1430 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193168,7 +193861,7 @@ module.exports = GetWorldToTileYFunction; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HasTileAt = __webpack_require__(542); +var HasTileAt = __webpack_require__(558); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -193201,7 +193894,7 @@ module.exports = HasTileAtWorldXY; /***/ }), -/* 1424 */ +/* 1431 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193210,7 +193903,7 @@ module.exports = HasTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PutTileAt = __webpack_require__(251); +var PutTileAt = __webpack_require__(253); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -193244,7 +193937,7 @@ module.exports = PutTileAtWorldXY; /***/ }), -/* 1425 */ +/* 1432 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193253,8 +193946,8 @@ module.exports = PutTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CalculateFacesWithin = __webpack_require__(60); -var PutTileAt = __webpack_require__(251); +var CalculateFacesWithin = __webpack_require__(61); +var PutTileAt = __webpack_require__(253); /** * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified @@ -193311,7 +194004,7 @@ module.exports = PutTilesAt; /***/ }), -/* 1426 */ +/* 1433 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193321,7 +194014,7 @@ module.exports = PutTilesAt; */ var GetTilesWithin = __webpack_require__(26); -var GetRandom = __webpack_require__(205); +var GetRandom = __webpack_require__(207); /** * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the @@ -193369,7 +194062,7 @@ module.exports = Randomize; /***/ }), -/* 1427 */ +/* 1434 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193378,7 +194071,7 @@ module.exports = Randomize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RemoveTileAt = __webpack_require__(543); +var RemoveTileAt = __webpack_require__(559); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -193410,7 +194103,7 @@ module.exports = RemoveTileAtWorldXY; /***/ }), -/* 1428 */ +/* 1435 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193420,7 +194113,7 @@ module.exports = RemoveTileAtWorldXY; */ var GetTilesWithin = __webpack_require__(26); -var Color = __webpack_require__(375); +var Color = __webpack_require__(391); var defaultTileColor = new Color(105, 210, 231, 150); var defaultCollidingTileColor = new Color(243, 134, 48, 200); @@ -193492,7 +194185,7 @@ module.exports = RenderDebug; /***/ }), -/* 1429 */ +/* 1436 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193501,9 +194194,9 @@ module.exports = RenderDebug; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on the given tile or tiles within a layer by index. You can pass in either a @@ -193563,7 +194256,7 @@ module.exports = SetCollision; /***/ }), -/* 1430 */ +/* 1437 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193572,9 +194265,9 @@ module.exports = SetCollision; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on a range of tiles in a layer whose index is between the specified `start` and @@ -193639,7 +194332,7 @@ module.exports = SetCollisionBetween; /***/ }), -/* 1431 */ +/* 1438 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193648,9 +194341,9 @@ module.exports = SetCollisionBetween; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on all tiles in the given layer, except for tiles that have an index specified in @@ -193700,7 +194393,7 @@ module.exports = SetCollisionByExclusion; /***/ }), -/* 1432 */ +/* 1439 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193709,8 +194402,8 @@ module.exports = SetCollisionByExclusion; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); var HasValue = __webpack_require__(125); /** @@ -193775,7 +194468,7 @@ module.exports = SetCollisionByProperty; /***/ }), -/* 1433 */ +/* 1440 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193784,8 +194477,8 @@ module.exports = SetCollisionByProperty; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); /** * Sets collision on the tiles within a layer by checking each tile's collision group data @@ -193834,7 +194527,7 @@ module.exports = SetCollisionFromCollisionGroup; /***/ }), -/* 1434 */ +/* 1441 */ /***/ (function(module, exports) { /** @@ -193880,7 +194573,7 @@ module.exports = SetTileIndexCallback; /***/ }), -/* 1435 */ +/* 1442 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193921,7 +194614,7 @@ module.exports = SetTileLocationCallback; /***/ }), -/* 1436 */ +/* 1443 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -193966,7 +194659,7 @@ module.exports = Shuffle; /***/ }), -/* 1437 */ +/* 1444 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194017,7 +194710,7 @@ module.exports = SwapByIndex; /***/ }), -/* 1438 */ +/* 1445 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194100,7 +194793,7 @@ module.exports = WeightedRandomize; /***/ }), -/* 1439 */ +/* 1446 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194115,19 +194808,19 @@ module.exports = WeightedRandomize; module.exports = { - FromOrientationString: __webpack_require__(252), - Parse: __webpack_require__(544), - Parse2DArray: __webpack_require__(253), - ParseCSV: __webpack_require__(545), + FromOrientationString: __webpack_require__(254), + Parse: __webpack_require__(560), + Parse2DArray: __webpack_require__(255), + ParseCSV: __webpack_require__(561), - Impact: __webpack_require__(1440), - Tiled: __webpack_require__(1441) + Impact: __webpack_require__(1447), + Tiled: __webpack_require__(1448) }; /***/ }), -/* 1440 */ +/* 1447 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194142,15 +194835,15 @@ module.exports = { module.exports = { - ParseTileLayers: __webpack_require__(558), - ParseTilesets: __webpack_require__(559), - ParseWeltmeister: __webpack_require__(557) + ParseTileLayers: __webpack_require__(574), + ParseTilesets: __webpack_require__(575), + ParseWeltmeister: __webpack_require__(573) }; /***/ }), -/* 1441 */ +/* 1448 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194165,23 +194858,23 @@ module.exports = { module.exports = { - AssignTileProperties: __webpack_require__(547), - Base64Decode: __webpack_require__(554), - BuildTilesetIndex: __webpack_require__(548), - CreateGroupLayer: __webpack_require__(158), - ParseGID: __webpack_require__(255), - ParseImageLayers: __webpack_require__(549), - ParseJSONTiled: __webpack_require__(546), - ParseObject: __webpack_require__(254), - ParseObjectLayers: __webpack_require__(550), - ParseTileLayers: __webpack_require__(553), - ParseTilesets: __webpack_require__(555) + AssignTileProperties: __webpack_require__(563), + Base64Decode: __webpack_require__(570), + BuildTilesetIndex: __webpack_require__(564), + CreateGroupLayer: __webpack_require__(159), + ParseGID: __webpack_require__(257), + ParseImageLayers: __webpack_require__(565), + ParseJSONTiled: __webpack_require__(562), + ParseObject: __webpack_require__(256), + ParseObjectLayers: __webpack_require__(566), + ParseTileLayers: __webpack_require__(569), + ParseTilesets: __webpack_require__(571) }; /***/ }), -/* 1442 */ +/* 1449 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194195,12 +194888,12 @@ var renderCanvas = __webpack_require__(1); if (true) { - renderWebGL = __webpack_require__(1443); + renderWebGL = __webpack_require__(1450); } if (true) { - renderCanvas = __webpack_require__(1444); + renderCanvas = __webpack_require__(1451); } module.exports = { @@ -194212,7 +194905,7 @@ module.exports = { /***/ }), -/* 1443 */ +/* 1450 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194325,7 +195018,7 @@ module.exports = TilemapLayerWebGLRenderer; /***/ }), -/* 1444 */ +/* 1451 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194463,7 +195156,7 @@ module.exports = TilemapLayerCanvasRenderer; /***/ }), -/* 1445 */ +/* 1452 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194473,7 +195166,7 @@ module.exports = TilemapLayerCanvasRenderer; */ var GameObjectCreator = __webpack_require__(16); -var ParseToTilemap = __webpack_require__(256); +var ParseToTilemap = __webpack_require__(258); /** * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. @@ -194507,7 +195200,7 @@ GameObjectCreator.register('tilemap', function (config) /***/ }), -/* 1446 */ +/* 1453 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194517,7 +195210,7 @@ GameObjectCreator.register('tilemap', function (config) */ var GameObjectFactory = __webpack_require__(5); -var ParseToTilemap = __webpack_require__(256); +var ParseToTilemap = __webpack_require__(258); /** * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. @@ -194573,7 +195266,7 @@ GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, widt /***/ }), -/* 1447 */ +/* 1454 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194588,14 +195281,14 @@ GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, widt module.exports = { - Clock: __webpack_require__(1448), - TimerEvent: __webpack_require__(562) + Clock: __webpack_require__(1455), + TimerEvent: __webpack_require__(578) }; /***/ }), -/* 1448 */ +/* 1455 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -194607,8 +195300,8 @@ module.exports = { var Class = __webpack_require__(0); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var TimerEvent = __webpack_require__(562); -var Remove = __webpack_require__(88); +var TimerEvent = __webpack_require__(578); +var Remove = __webpack_require__(89); /** * @classdesc @@ -195051,7 +195744,7 @@ module.exports = Clock; /***/ }), -/* 1449 */ +/* 1456 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -195061,7 +195754,7 @@ module.exports = Clock; */ var CONST = __webpack_require__(97); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Tweens @@ -195069,13 +195762,13 @@ var Extend = __webpack_require__(19); var Tweens = { - Builders: __webpack_require__(1450), - Events: __webpack_require__(261), + Builders: __webpack_require__(1457), + Events: __webpack_require__(263), - TweenManager: __webpack_require__(1466), - Tween: __webpack_require__(260), - TweenData: __webpack_require__(262), - Timeline: __webpack_require__(568) + TweenManager: __webpack_require__(1473), + Tween: __webpack_require__(262), + TweenData: __webpack_require__(264), + Timeline: __webpack_require__(584) }; @@ -195086,7 +195779,7 @@ module.exports = Tweens; /***/ }), -/* 1450 */ +/* 1457 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -195103,21 +195796,21 @@ module.exports = { GetBoolean: __webpack_require__(96), GetEaseFunction: __webpack_require__(80), - GetNewValue: __webpack_require__(159), - GetProps: __webpack_require__(563), - GetTargets: __webpack_require__(257), - GetTweens: __webpack_require__(564), - GetValueOp: __webpack_require__(258), - NumberTweenBuilder: __webpack_require__(565), - StaggerBuilder: __webpack_require__(566), - TimelineBuilder: __webpack_require__(567), - TweenBuilder: __webpack_require__(160) + GetNewValue: __webpack_require__(160), + GetProps: __webpack_require__(579), + GetTargets: __webpack_require__(259), + GetTweens: __webpack_require__(580), + GetValueOp: __webpack_require__(260), + NumberTweenBuilder: __webpack_require__(581), + StaggerBuilder: __webpack_require__(582), + TimelineBuilder: __webpack_require__(583), + TweenBuilder: __webpack_require__(161) }; /***/ }), -/* 1451 */ +/* 1458 */ /***/ (function(module, exports) { /** @@ -195195,7 +195888,7 @@ module.exports = [ /***/ }), -/* 1452 */ +/* 1459 */ /***/ (function(module, exports) { /** @@ -195231,7 +195924,7 @@ module.exports = 'complete'; /***/ }), -/* 1453 */ +/* 1460 */ /***/ (function(module, exports) { /** @@ -195268,7 +195961,7 @@ module.exports = 'loop'; /***/ }), -/* 1454 */ +/* 1461 */ /***/ (function(module, exports) { /** @@ -195305,7 +195998,7 @@ module.exports = 'pause'; /***/ }), -/* 1455 */ +/* 1462 */ /***/ (function(module, exports) { /** @@ -195342,7 +196035,7 @@ module.exports = 'resume'; /***/ }), -/* 1456 */ +/* 1463 */ /***/ (function(module, exports) { /** @@ -195378,7 +196071,7 @@ module.exports = 'start'; /***/ }), -/* 1457 */ +/* 1464 */ /***/ (function(module, exports) { /** @@ -195415,7 +196108,7 @@ module.exports = 'update'; /***/ }), -/* 1458 */ +/* 1465 */ /***/ (function(module, exports) { /** @@ -195455,7 +196148,7 @@ module.exports = 'active'; /***/ }), -/* 1459 */ +/* 1466 */ /***/ (function(module, exports) { /** @@ -195496,7 +196189,7 @@ module.exports = 'complete'; /***/ }), -/* 1460 */ +/* 1467 */ /***/ (function(module, exports) { /** @@ -195540,7 +196233,7 @@ module.exports = 'loop'; /***/ }), -/* 1461 */ +/* 1468 */ /***/ (function(module, exports) { /** @@ -195585,7 +196278,7 @@ module.exports = 'repeat'; /***/ }), -/* 1462 */ +/* 1469 */ /***/ (function(module, exports) { /** @@ -195625,7 +196318,7 @@ module.exports = 'start'; /***/ }), -/* 1463 */ +/* 1470 */ /***/ (function(module, exports) { /** @@ -195661,7 +196354,7 @@ module.exports = 'stop'; /***/ }), -/* 1464 */ +/* 1471 */ /***/ (function(module, exports) { /** @@ -195704,7 +196397,7 @@ module.exports = 'update'; /***/ }), -/* 1465 */ +/* 1472 */ /***/ (function(module, exports) { /** @@ -195750,7 +196443,7 @@ module.exports = 'yoyo'; /***/ }), -/* 1466 */ +/* 1473 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -195759,15 +196452,15 @@ module.exports = 'yoyo'; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(88); +var ArrayRemove = __webpack_require__(89); var Class = __webpack_require__(0); -var NumberTweenBuilder = __webpack_require__(565); +var NumberTweenBuilder = __webpack_require__(581); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var StaggerBuilder = __webpack_require__(566); -var TimelineBuilder = __webpack_require__(567); +var StaggerBuilder = __webpack_require__(582); +var TimelineBuilder = __webpack_require__(583); var TWEEN_CONST = __webpack_require__(97); -var TweenBuilder = __webpack_require__(160); +var TweenBuilder = __webpack_require__(161); /** * @classdesc @@ -196539,7 +197232,7 @@ module.exports = TweenManager; /***/ }), -/* 1467 */ +/* 1474 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196554,17 +197247,17 @@ module.exports = TweenManager; module.exports = { - Array: __webpack_require__(203), - Base64: __webpack_require__(1468), - Objects: __webpack_require__(1470), - String: __webpack_require__(1474), + Array: __webpack_require__(205), + Base64: __webpack_require__(1475), + Objects: __webpack_require__(1477), + String: __webpack_require__(1481), NOOP: __webpack_require__(1) }; /***/ }), -/* 1468 */ +/* 1475 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196579,14 +197272,14 @@ module.exports = { module.exports = { - ArrayBufferToBase64: __webpack_require__(1469), - Base64ToArrayBuffer: __webpack_require__(411) + ArrayBufferToBase64: __webpack_require__(1476), + Base64ToArrayBuffer: __webpack_require__(427) }; /***/ }), -/* 1469 */ +/* 1476 */ /***/ (function(module, exports) { /** @@ -196644,7 +197337,7 @@ module.exports = ArrayBufferToBase64; /***/ }), -/* 1470 */ +/* 1477 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196660,26 +197353,26 @@ module.exports = ArrayBufferToBase64; module.exports = { Clone: __webpack_require__(77), - DeepCopy: __webpack_require__(171), - Extend: __webpack_require__(19), + DeepCopy: __webpack_require__(172), + Extend: __webpack_require__(17), GetAdvancedValue: __webpack_require__(13), GetFastValue: __webpack_require__(2), - GetMinMaxValue: __webpack_require__(1471), + GetMinMaxValue: __webpack_require__(1478), GetValue: __webpack_require__(6), - HasAll: __webpack_require__(1472), - HasAny: __webpack_require__(433), + HasAll: __webpack_require__(1479), + HasAny: __webpack_require__(449), HasValue: __webpack_require__(125), IsPlainObject: __webpack_require__(7), - Merge: __webpack_require__(142), - MergeRight: __webpack_require__(1473), - Pick: __webpack_require__(551), - SetValue: __webpack_require__(456) + Merge: __webpack_require__(143), + MergeRight: __webpack_require__(1480), + Pick: __webpack_require__(567), + SetValue: __webpack_require__(472) }; /***/ }), -/* 1471 */ +/* 1478 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196689,7 +197382,7 @@ module.exports = { */ var GetValue = __webpack_require__(6); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); /** * Retrieves and clamps a numerical value from an object. @@ -196718,7 +197411,7 @@ module.exports = GetMinMaxValue; /***/ }), -/* 1472 */ +/* 1479 */ /***/ (function(module, exports) { /** @@ -196755,7 +197448,7 @@ module.exports = HasAll; /***/ }), -/* 1473 */ +/* 1480 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196798,7 +197491,7 @@ module.exports = MergeRight; /***/ }), -/* 1474 */ +/* 1481 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196813,18 +197506,18 @@ module.exports = MergeRight; module.exports = { - Format: __webpack_require__(1475), - Pad: __webpack_require__(182), - RemoveAt: __webpack_require__(1476), - Reverse: __webpack_require__(1477), - UppercaseFirst: __webpack_require__(200), - UUID: __webpack_require__(217) + Format: __webpack_require__(1482), + Pad: __webpack_require__(183), + RemoveAt: __webpack_require__(1483), + Reverse: __webpack_require__(1484), + UppercaseFirst: __webpack_require__(202), + UUID: __webpack_require__(219) }; /***/ }), -/* 1475 */ +/* 1482 */ /***/ (function(module, exports) { /** @@ -196859,7 +197552,7 @@ module.exports = Format; /***/ }), -/* 1476 */ +/* 1483 */ /***/ (function(module, exports) { /** @@ -196895,7 +197588,7 @@ module.exports = RemoveAt; /***/ }), -/* 1477 */ +/* 1484 */ /***/ (function(module, exports) { /** @@ -196924,7 +197617,7 @@ module.exports = Reverse; /***/ }), -/* 1478 */ +/* 1485 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -196940,33 +197633,26 @@ module.exports = Reverse; module.exports = { - SoundManagerCreator: __webpack_require__(404), + SoundManagerCreator: __webpack_require__(420), - Events: __webpack_require__(68), + Events: __webpack_require__(69), - BaseSound: __webpack_require__(144), - BaseSoundManager: __webpack_require__(143), + BaseSound: __webpack_require__(145), + BaseSoundManager: __webpack_require__(144), - WebAudioSound: __webpack_require__(412), - WebAudioSoundManager: __webpack_require__(410), + WebAudioSound: __webpack_require__(428), + WebAudioSoundManager: __webpack_require__(426), - HTML5AudioSound: __webpack_require__(407), - HTML5AudioSoundManager: __webpack_require__(405), + HTML5AudioSound: __webpack_require__(423), + HTML5AudioSoundManager: __webpack_require__(421), - NoAudioSound: __webpack_require__(409), - NoAudioSoundManager: __webpack_require__(408) + NoAudioSound: __webpack_require__(425), + NoAudioSoundManager: __webpack_require__(424) }; /***/ }), -/* 1479 */, -/* 1480 */, -/* 1481 */, -/* 1482 */, -/* 1483 */, -/* 1484 */, -/* 1485 */, /* 1486 */, /* 1487 */, /* 1488 */, @@ -197026,23 +197712,17 @@ module.exports = { __webpack_require__(590); var CONST = __webpack_require__(39); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser */ -/** - * The root types namespace. - * - * @namespace Phaser.Types - * @since 3.17.0 - */ - var Phaser = { Actions: __webpack_require__(269), Animations: __webpack_require__(699), + BlendModes: __webpack_require__(33), Cache: __webpack_require__(711), Cameras: __webpack_require__(714), Core: __webpack_require__(803), @@ -197055,34 +197735,51 @@ var Phaser = { Events: __webpack_require__(914), Game: __webpack_require__(916), GameObjects: __webpack_require__(1007), - Geom: __webpack_require__(461), + Geom: __webpack_require__(477), Input: __webpack_require__(1302), Loader: __webpack_require__(1332), - Math: __webpack_require__(189), + Math: __webpack_require__(190), Physics: { Arcade: __webpack_require__(1360) }, Plugins: __webpack_require__(1397), - Scale: __webpack_require__(1399), - Scene: __webpack_require__(396), - Scenes: __webpack_require__(1400), - Structs: __webpack_require__(1402), - Textures: __webpack_require__(1403), - Tilemaps: __webpack_require__(1405), - Time: __webpack_require__(1447), - Tweens: __webpack_require__(1449), - Utils: __webpack_require__(1467) + Renderer: __webpack_require__(1399), + Scale: __webpack_require__(1406), + ScaleModes: __webpack_require__(164), + Scene: __webpack_require__(412), + Scenes: __webpack_require__(1407), + Structs: __webpack_require__(1409), + Textures: __webpack_require__(1410), + Tilemaps: __webpack_require__(1412), + Time: __webpack_require__(1454), + Tweens: __webpack_require__(1456), + Utils: __webpack_require__(1474) }; +// Merge in the optional plugins and WebGL only features + +if (true) +{ + Phaser.Sound = __webpack_require__(1485); +} + +if (false) +{} + +if (false) +{} + // Merge in the consts Phaser = Extend(false, Phaser, CONST); -if (true) -{ - Phaser.Sound = __webpack_require__(1478); -} +/** + * The root types namespace. + * + * @namespace Phaser.Types + * @since 3.17.0 + */ // Export it diff --git a/dist/phaser-arcade-physics.min.js b/dist/phaser-arcade-physics.min.js index 778c41fd5..e4a376113 100644 --- a/dist/phaser-arcade-physics.min.js +++ b/dist/phaser-arcade-physics.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("Phaser",[],e):"object"==typeof exports?exports.Phaser=e():t.Phaser=e()}(window,function(){return n={},s.m=i=[function(t,e){function r(t,e,i,n){for(var s in e)if(e.hasOwnProperty(s)){var r=(u=e,l=s,f=d=void 0,f=(c=i)?u[l]:Object.getOwnPropertyDescriptor(u,l),!c&&f.value&&"object"==typeof f.value&&(f=f.value),!(!f||!((d=f).get&&"function"==typeof d.get||d.set&&"function"==typeof d.set))&&(void 0===f.enumerable&&(f.enumerable=!0),void 0===f.configurable&&(f.configurable=!0),f));if(!1!==r){if(o=(n||t).prototype,a=s,h=void 0,(h=Object.getOwnPropertyDescriptor(o,a))&&(h.value&&"object"==typeof h.value&&(h=h.value),!1===h.configurable)){if(p.ignoreFinals)continue;throw new Error("cannot override final property '"+s+"', set Class.ignoreFinals = true to skip")}Object.defineProperty(t.prototype,s,r)}else t.prototype[s]=e[s]}var o,a,h,u,l,c,d,f}function o(t,e){if(e){Array.isArray(e)||(e=[e]);for(var i=0;i=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=l},function(t,e,i){t.exports={Alpha:i(605),AlphaSingle:i(297),BlendMode:i(298),ComputedSize:i(606),Crop:i(607),Depth:i(299),Flip:i(608),GetBounds:i(609),Mask:i(303),Origin:i(630),PathFollower:i(631),Pipeline:i(170),ScrollFactor:i(306),Size:i(632),Texture:i(633),TextureCrop:i(634),Tint:i(635),ToJSON:i(172),Transform:i(307),TransformMatrix:i(25),Visible:i(308)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var u=[],l=e;lthis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=u},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e){t.exports=function(t,e,i,n){var s=i||e.strokeColor,r=n||e.strokeAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(20),u=i(23),s=i(8),l=i(2),c=i(6),d=i(7),r=new n({Extends:u,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=l(r=e,"key"),i=l(r,"url"),n=l(r,"xhrSettings"),o=l(r,"extension",o),s=l(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};u.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(36),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,u,l,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=u,v[10]=l,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,E=n*h-s*a,b=u*p-l*f,S=u*g-c*f,A=u*v-d*f,_=l*g-c*p,C=l*v-d*p,M=c*v-d*g,R=m*M-y*C+x*_+T*A-w*S+E*b;return R?(R=1/R,this.setValues((o*M-a*C+h*_)*R,(n*C-i*M-s*_)*R,(p*E-g*w+v*T)*R,(c*w-l*E-d*T)*R,(a*A-r*M-h*S)*R,(e*M-n*A+s*S)*R,(g*x-f*E-v*y)*R,(u*E-c*x+d*y)*R,(r*C-o*A+h*b)*R,(i*A-e*C-s*b)*R,(f*w-p*x+v*m)*R,(l*x-u*w-d*m)*R,(o*S-r*_-a*b)*R,(e*_-i*S+n*b)*R,(p*y-f*T-g*m)*R,(u*T-l*y+c*m)*R)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-l*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-l*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+l*(n*h-s*a)),-(r*(c*v-d*g)-u*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-u*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+u*(n*h-s*a),r*(l*v-d*p)-u*(o*v-h*p)+f*(o*d-h*l),-(e*(l*v-d*p)-u*(i*v-s*p)+f*(i*d-s*l)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*l)-r*(i*d-s*l)+u*(i*h-s*o)),-(r*(l*g-c*p)-u*(o*g-a*p)+f*(o*c-a*l)),e*(l*g-c*p)-u*(i*g-n*p)+f*(i*c-n*l),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*l)-r*(i*c-n*l)+u*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(l*v-d*p)+(e*h-s*r)*(l*g-c*p)+(i*a-n*o)*(u*v-d*f)-(i*h-s*o)*(u*g-c*f)+(n*h-s*a)*(u*p-l*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],u=e[7],l=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],E=y[3];return e[0]=x*i+T*o+w*l+E*p,e[1]=x*n+T*a+w*c+E*g,e[2]=x*s+T*h+w*d+E*v,e[3]=x*r+T*u+w*f+E*m,x=y[4],T=y[5],w=y[6],E=y[7],e[4]=x*i+T*o+w*l+E*p,e[5]=x*n+T*a+w*c+E*g,e[6]=x*s+T*h+w*d+E*v,e[7]=x*r+T*u+w*f+E*m,x=y[8],T=y[9],w=y[10],E=y[11],e[8]=x*i+T*o+w*l+E*p,e[9]=x*n+T*a+w*c+E*g,e[10]=x*s+T*h+w*d+E*v,e[11]=x*r+T*u+w*f+E*m,x=y[12],T=y[13],w=y[14],E=y[15],e[12]=x*i+T*o+w*l+E*p,e[13]=x*n+T*a+w*c+E*g,e[14]=x*s+T*h+w*d+E*v,e[15]=x*r+T*u+w*f+E*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],u=i[5],l=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],E=n[8],b=n[12],S=n[1],A=n[5],_=n[9],C=n[13],M=n[2],R=n[6],P=n[10],O=n[14],L=n[3],D=n[7],F=n[11],k=n[15];return this.setValues(s*T+r*S+o*M+a*L,h*T+u*S+l*M+c*L,d*T+f*S+p*M+g*L,v*T+m*S+y*M+x*L,s*w+r*A+o*R+a*D,h*w+u*A+l*R+c*D,d*w+f*A+p*R+g*D,v*w+m*A+y*R+x*D,s*E+r*_+o*P+a*F,h*E+u*_+l*P+c*F,d*E+f*_+p*P+g*F,v*E+m*_+y*P+x*F,s*b+r*C+o*O+a*k,h*b+u*C+l*O+c*k,d*b+f*C+p*O+g*k,v*b+m*C+y*O+x*k)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,u=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,u*o+i,u*a-n*r,0,h*a-n*o,u*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),u=1-h,l=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],E=i[12],b=i[13],S=i[14],A=i[15],_=n*n*u+h,C=s*n*u+r*a,M=r*n*u-s*a,R=n*s*u-r*a,P=s*s*u+h,O=r*s*u+n*a,L=n*r*u+s*a,D=s*r*u-n*a,F=r*r*u+h;return this.setValues(l*_+p*C+y*M,c*_+g*C+x*M,d*_+v*C+T*M,f*_+m*C+w*M,l*R+p*P+y*O,c*R+g*P+x*O,d*R+v*P+T*O,f*R+m*P+w*O,l*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,E,b,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],u=e[9],l=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+u*i,e[6]=o*n+l*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=u*n-r*i,e[10]=l*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],u=e[9],l=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-u*i,e[2]=o*n-l*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+u*n,e[10]=o*i+l*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],u=e[5],l=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+u*i,e[2]=o*n+l*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=u*n-r*i,e[6]=l*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,u=i*o,l=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),l+m,c-v,0,l-m,1-(u+p),f+g,0,c+v,f-g,1-(u+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,u=e*o,l=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),u+v,l-g,0,u-v,1-(h+f),d+p,0,l+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return l.subVectors(t,e),0===l.getLengthSquared()&&(l.z=1),l.normalize(),o.crossVectors(i,l),0===o.getLengthSquared()&&(1===Math.abs(i.z)?l.x+=1e-4:l.z+=1e-4,l.normalize(),o.crossVectors(i,l)),o.normalize(),a.crossVectors(l,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=l.x,n[9]=l.y,n[10]=l.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,u=e.x,l=e.y,c=e.z;if(Math.abs(n-u)<1e-6&&Math.abs(s-l)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-u,f=s-l,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),u.zero();var n=this.val,s=h.val,r=u.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(u),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),u.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(u),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],u=i[5],l=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],E=n[2],b=n[3],S=n[4],A=n[5],_=n[6],C=n[7],M=n[8],R=n[9],P=n[10],O=n[11],L=n[12],D=n[13],F=n[14],k=n[15];return e.setValues(T*s+w*h+E*d+b*v,w*r+w*u+E*f+b*m,E*o+w*l+E*p+b*y,b*a+w*c+E*g+b*x,S*s+A*h+_*d+C*v,S*r+A*u+_*f+C*m,S*o+A*l+_*p+C*y,S*a+A*c+_*g+C*x,M*s+R*h+P*d+O*v,M*r+R*u+P*f+O*m,M*o+R*l+P*p+O*y,M*a+R*c+P*g+O*x,L*s+D*h+F*d+k*v,L*r+D*u+F*f+k*m,L*o+D*l+F*p+k*y,L*a+D*c+F*g+k*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),u=Math.cos(t.y),l=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*u,m=a*u;return i||(l=u*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(u,p,g,0,0,a,o,0,h,v,m,0,l,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,u=new r,o=new s,a=new s,l=new s;t.exports=r},function(t,e,i){var n=i(0),y=i(171),s=i(9),v=i(575),x=i(2),m=i(65),T=i(94),w=i(162),E=i(12),b=i(576),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=l[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=l.length-1;0<=d;d--)l[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=l&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==u;);return i}(t,e))&&(i=b(e,t),v(e,e.next),v(i,i.next))}}(u[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,l=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(u,l,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,u=h.next;else if((t=h)===u){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!l(s,r)&&c(s,n,n.next,r)&&E(s,r)&&E(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(E(t,e)&&E(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||l(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function u(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=l},function(t,e,i){var n=i(29),s=i(0),r=i(11),o=i(480),a=new s({Mixins:[r.Alpha,r.Flip,r.Visible],initialize:function(t,e,i,n,s,r,o,a){this.layer=t,this.index=e,this.x=i,this.y=n,this.width=s,this.height=r,this.right,this.bottom,this.baseWidth=void 0!==o?o:s,this.baseHeight=void 0!==a?a:r,this.pixelX=0,this.pixelY=0,this.updatePixelXY(),this.properties={},this.rotation=0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceLeft=!1,this.faceRight=!1,this.faceTop=!1,this.faceBottom=!1,this.collisionCallback=void 0,(this.collisionCallbackContext=this).tint=16777215,this.physics={}},containsPoint:function(t,e){return!(tthis.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){var h=i(74);t.exports=function(t,e,i,n){if(void 0===n&&(n=t),!Array.isArray(e))return-1!==(o=t.indexOf(e))?(h(t,o),i&&i.call(n,e),e):null;for(var s=e.length-1,r=[];0<=s;){var o,a=e[s];-1!==(o=t.indexOf(a))&&(h(t,o),r.push(a),i&&i.call(n,a)),s--}return r}},function(t,e,i){var n=i(0),s=i(194),r=i(10),o=i(3),a=new n({initialize:function(t){this.type=t,this.defaultDivisions=5,this.arcLengthDivisions=100,this.cacheArcLengths=[],this.needsUpdate=!0,this.active=!0,this._tmpVec2A=new o,this._tmpVec2B=new o},draw:function(t,e){return void 0===e&&(e=32),t.strokePoints(this.getPoints(e))},getBounds:function(t,e){t=t||new r,void 0===e&&(e=16);var i=this.getLength();ih||a.y>u)?(l=Math.max(a.x,e),c=Math.max(a.y,i),E=d=Math.min(a.r,h)-l,b=f=Math.min(a.b,u)-c,T=r?p+(v-(l-a.x)-d):p+(l-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=l,i=c,n=d,s=f):b=E=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+E)/A),t.v1=Math.min(1,(w+b)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=E,t.ch=b,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(203),n=i(0),r=i(1),o=i(79),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),l=i(36),s=new n({Extends:l,initialize:function(t,e,i,n,s,r,o,a,h,u){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===u&&(u=0),l.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=u,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],u=s*a[1]+r*a[5]+o*a[9]+a[13],l=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-u/c*i,this.vz=n<=0?l/c:-l/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,u=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),u=Math.round(u)),this.tx=h,this.ty=u,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},,,function(t,e){t.exports=function(t,e,i){return 0<=t&&t=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},function(t,e,i){var n=i(0),s=i(94),r=new n({initialize:function(t,e,i,n,s,r,o){void 0===n&&(n=1),void 0===s&&(s=0),void 0===r&&(r=!0),void 0===o&&(o=!1),this.renderer=t,this.framebuffer=null,this.texture=null,this.width=0,this.height=0,this.scale=n,this.minFilter=s,this.autoClear=r,this.autoResize=!1,this.resize(e,i),o&&this.setAutoResize(!0)},setAutoResize:function(t){return t&&!this.autoResize?(this.renderer.on(s.RESIZE,this.resize,this),this.autoResize=!0):!t&&this.autoResize&&(this.renderer.off(s.RESIZE,this.resize,this),this.autoResize=!1),this},resize:function(t,e){var i,n=t*this.scale,s=e*this.scale;return n===this.width&&s===this.height||((i=this.renderer).deleteFramebuffer(this.framebuffer),i.deleteTexture(this.texture),t*=this.scale,e*=this.scale,this.texture=i.createTextureFromSource(null,t,e,this.minFilter),this.framebuffer=i.createFramebuffer(t,e,this.texture,!1),this.width=t,this.height=e),this},bind:function(t,e,i){var n;void 0===t&&(t=!1),t&&this.renderer.flush(),e&&i&&this.resize(e,i),this.renderer.pushFramebuffer(this.framebuffer,!1,!1,!1),t&&this.adjustViewport(),this.autoClear&&((n=this.renderer.gl).clearColor(0,0,0,0),n.clear(n.COLOR_BUFFER_BIT))},adjustViewport:function(){var t=this.renderer.gl;t.viewport(0,0,this.width,this.height),t.disable(t.SCISSOR_TEST)},clear:function(){var t=this.renderer,e=t.gl;t.pushFramebuffer(this.framebuffer),e.disable(e.SCISSOR_TEST),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT),t.popFramebuffer(),t.resetScissor()},unbind:function(t){void 0===t&&(t=!1);var e=this.renderer;return t&&e.flush(),e.popFramebuffer()},destroy:function(){var t=this.renderer;t.deleteFramebuffer(this.framebuffer),t.deleteTexture(this.texture),t.off(s.RESIZE,this.resize,this),this.renderer=null,this.framebuffer=null,this.texture=null}});t.exports=r},,function(t,e,i){var n=i(4);t.exports=function(t,e,i){return void 0===i&&(i=new n),i.x=t.x+t.radius*Math.cos(e),i.y=t.y+t.radius*Math.sin(e),i}},function(t,e,i){var a=i(4);t.exports=function(t,e){void 0===e&&(e=new a);var i=2*Math.PI*Math.random(),n=Math.random()+Math.random(),s=1=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(321),s=i(185),r=i(325),o=i(326);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(100);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(35),s=i(324);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(102),r=i(134),o=i(31),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var u,l,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(u=this.pipeline).manager.set(u),l=y.width,c=y.height,d=h.width/l,f=h.height/c,u.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},,function(t,e,i){t.exports={CalculateFacesAt:i(246),CalculateFacesWithin:i(60),CheckIsoBounds:i(521),Copy:i(1407),CreateFromTiles:i(1408),CullBounds:i(523),CullTiles:i(524),Fill:i(1409),FilterTiles:i(1410),FindByIndex:i(1411),FindTile:i(1412),ForEachTile:i(1413),GetCullTilesFunction:i(1414),GetTileAt:i(155),GetTileAtWorldXY:i(1415),GetTilesWithin:i(26),GetTilesWithinShape:i(1416),GetTilesWithinWorldXY:i(507),GetTileToWorldXFunction:i(1417),GetTileToWorldXYFunction:i(1418),GetTileToWorldYFunction:i(1419),GetWorldToTileXFunction:i(1420),GetWorldToTileXYFunction:i(1421),GetWorldToTileYFunction:i(1422),HasTileAt:i(542),HasTileAtWorldXY:i(1423),HexagonalCullBounds:i(526),HexagonalCullTiles:i(525),HexagonalTileToWorldXY:i(530),HexagonalTileToWorldY:i(534),HexagonalWorldToTileXY:i(536),HexagonalWorldToTileY:i(540),IsInLayerBounds:i(116),IsometricCullTiles:i(527),IsometricTileToWorldXY:i(531),IsometricWorldToTileXY:i(537),PutTileAt:i(251),PutTileAtWorldXY:i(1424),PutTilesAt:i(1425),Randomize:i(1426),RemoveTileAt:i(543),RemoveTileAtWorldXY:i(1427),RenderDebug:i(1428),ReplaceByIndex:i(522),RunCull:i(156),SetCollision:i(1429),SetCollisionBetween:i(1430),SetCollisionByExclusion:i(1431),SetCollisionByProperty:i(1432),SetCollisionFromCollisionGroup:i(1433),SetLayerCollisionIndex:i(157),SetTileCollision:i(71),SetTileIndexCallback:i(1434),SetTileLocationCallback:i(1435),Shuffle:i(1436),StaggeredCullBounds:i(529),StaggeredCullTiles:i(528),StaggeredTileToWorldXY:i(532),StaggeredTileToWorldY:i(535),StaggeredWorldToTileXY:i(538),StaggeredWorldToTileY:i(541),SwapByIndex:i(1437),TileToWorldX:i(247),TileToWorldXY:i(533),TileToWorldY:i(248),WeightedRandomize:i(1438),WorldToTileX:i(249),WorldToTileXY:i(539),WorldToTileY:i(250)}},function(t,e,i){var u=i(155);t.exports=function(t,e,i){var n=u(t,e,!0,i),s=u(t,e-1,!0,i),r=u(t,e+1,!0,i),o=u(t-1,e,!0,i),a=u(t+1,e,!0,i),h=n&&n.collides;return h&&(n.faceTop=!0,n.faceBottom=!0,n.faceLeft=!0,n.faceRight=!0),s&&s.collides&&(h&&(n.faceTop=!1),s.faceBottom=!h),r&&r.collides&&(h&&(n.faceBottom=!1),r.faceTop=!h),o&&o.collides&&(h&&(n.faceLeft=!1),o.faceRight=!h),a&&a.collides&&(h&&(n.faceRight=!1),a.faceLeft=!h),n&&!n.collides&&n.resetFaces(),n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileWidth,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.x+e.scrollX*(1-s.scrollFactorX),n*=s.scaleX),r+t*n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileHeight,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.y+e.scrollY*(1-s.scrollFactorY),n*=s.scaleY),r+t*n}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileWidth,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.x+i.scrollX*(1-r.scrollFactorX),s*=r.scaleX),e?Math.floor(t/s):t/s}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileHeight,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.y+i.scrollY*(1-r.scrollFactorY),s*=r.scaleY),e?Math.floor(t/s):t/s}},function(t,e,i){var l=i(83),c=i(116),d=i(246),f=i(71);t.exports=function(t,e,i,n,s){if(void 0===n&&(n=!0),!c(e,i,s))return null;var r,o=s.data[i][e],a=o&&o.collides;t instanceof l?(null===s.data[i][e]&&(s.data[i][e]=new l(s,t.index,e,i,s.tileWidth,s.tileHeight)),s.data[i][e].copy(t)):(r=t,null===s.data[i][e]?s.data[i][e]=new l(s,r,e,i,s.tileWidth,s.tileHeight):s.data[i][e].index=r);var h=s.data[i][e],u=-1!==s.collideIndexes.indexOf(h.index);return f(h,u),n&&a!==h.collides&&d(e,i,s),h}},function(t,e,i){var n=i(29);t.exports=function(t){return"isometric"===(t=t.toLowerCase())?n.ISOMETRIC:"staggered"===t?n.STAGGERED:"hexagonal"===t?n.HEXAGONAL:n.ORTHOGONAL}},function(t,e,i){var p=i(37),g=i(117),v=i(118),m=i(83);t.exports=function(t,e,i,n,s){for(var r=new g({tileWidth:i,tileHeight:n}),o=new v({name:t,tileWidth:i,tileHeight:n,format:p.ARRAY_2D,layers:[r]}),a=[],h=e.length,u=0,l=0;lt&&(t=s.totalDuration),s.delay=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),u=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(181),s=i(0),r=i(99),o=i(9),a=i(130),h=i(22),T=i(2),d=i(6),f=i(182),p=i(316),u=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1u.right&&(l=b(l,l+(d-u.right),this.lerp.x)),fu.bottom&&(c=b(c,c+(f-u.bottom),this.lerp.y))):(l=b(l,d-o,this.lerp.x),c=b(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(l=this.clampX(l),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),l=Math.round(l),c=Math.round(c));var g=(this.scrollX=l)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(E.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=l(i,0,1),n=l(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,u=t.y-r;return this.midPoint.set(h,u),this.scrollX=h-o,this.scrollY=u-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=u},function(t,e,i){var o=i(35);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,u=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(35);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(35);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(737),Flash:i(738),Pan:i(739),Shake:i(772),RotateTo:i(773),Zoom:i(774)}},function(t,e,i){t.exports={In:i(740),Out:i(741),InOut:i(742)}},function(t,e,i){t.exports={In:i(743),Out:i(744),InOut:i(745)}},function(t,e,i){t.exports={In:i(746),Out:i(747),InOut:i(748)}},function(t,e,i){t.exports={In:i(749),Out:i(750),InOut:i(751)}},function(t,e,i){t.exports={In:i(752),Out:i(753),InOut:i(754)}},function(t,e,i){t.exports={In:i(755),Out:i(756),InOut:i(757)}},function(t,e,i){t.exports=i(758)},function(t,e,i){t.exports={In:i(759),Out:i(760),InOut:i(761)}},function(t,e,i){t.exports={In:i(762),Out:i(763),InOut:i(764)}},function(t,e,i){t.exports={In:i(765),Out:i(766),InOut:i(767)}},function(t,e,i){t.exports={In:i(768),Out:i(769),InOut:i(770)}},function(t,e,i){t.exports=i(771)},function(t,e,i){var n=i(0),h=i(39),u=i(341),l=i(2),c=i(6),d=i(7),f=i(189),p=i(1),g=i(193),v=i(183),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",u.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=u.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=l(r,"global",[]),this.installScenePlugins=l(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(102),browser:i(134),features:i(187),input:i(805),audio:i(806),video:i(807),fullscreen:i(808),canvasFeatures:i(342)}},function(t,e,i){var n,s,r,o=i(31),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(361),u=a(31),l=a(39),c=a(187);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===l.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==l.HEADLESS)if(e.renderType===l.CANVAS||e.renderType!==l.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=l.CANVAS}else e.renderType=l.WEBGL;e.antialias||u.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=u.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==l.HEADLESS&&(i=a(569),n=a(572),e.renderType===l.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var u=i(39);t.exports=function(t){var e,i,n,s,r,o,a,h=t.config;h.hideBanner||(e="WebGL",h.renderType===u.CANVAS?e="Canvas":h.renderType===u.HEADLESS&&(e="Headless"),i=h.audio,a=(n=t.device.audio).webAudio&&!i.disableWebAudio?"Web Audio":i.noAudio||!n.webAudio&&!n.audioData?"No Audio":"HTML5 Audio",t.device.browser.ie?window.console&&console.log("Phaser v"+u.VERSION+" / https://phaser.io"):(r=[s=""],Array.isArray(h.bannerBackgroundColor)?(h.bannerBackgroundColor.forEach(function(t){s=s.concat("%c "),r.push("background: "+t),o=t}),r[r.length-1]="color: "+h.bannerTextColor+"; background: "+o):(s=s.concat("%c "),r.push("color: "+h.bannerTextColor+"; background: "+h.bannerBackgroundColor)),r.push("background: #fff"),h.gameTitle&&(s=s.concat(h.gameTitle),h.gameVersion&&(s=s.concat(" v"+h.gameVersion)),h.hidePhaser||(s=s.concat(" / "))),h.hidePhaser||(s=s.concat("Phaser v"+u.VERSION+" ("+e+" | "+a+")")),s=s.concat(" %c "+h.gameURL),r[0]=s,console.log.apply(console,r)))}},function(t,e,i){var n=i(0),s=i(6),r=i(1),o=i(364),a=new n({initialize:function(t,e){this.game=t,this.raf=new o,this.started=!1,this.running=!1,this.minFps=s(e,"min",5),this.targetFps=s(e,"target",60),this._min=1e3/this.minFps,this._target=1e3/this.targetFps,this.actualFps=this.targetFps,this.nextFpsUpdate=0,this.framesThisSecond=0,this.callback=r,this.forceSetTimeOut=s(e,"forceSetTimeOut",!1),this.time=0,this.startTime=0,this.lastTime=0,this.frame=0,this.inFocus=!0,this._pauseTime=0,this._coolDown=0,this.delta=0,this.deltaIndex=0,this.deltaHistory=[],this.deltaSmoothingMax=s(e,"deltaHistory",10),this.panicMax=s(e,"panicMax",120),this.rawDelta=0,this.now=0,this.smoothStep=s(e,"smoothStep",!0)},blur:function(){this.inFocus=!1},focus:function(){this.inFocus=!0,this.resetDelta()},pause:function(){this._pauseTime=window.performance.now()},resume:function(){this.resetDelta(),this.startTime+=this.time-this._pauseTime},resetDelta:function(){var t=window.performance.now();this.time=t,this.lastTime=t,this.nextFpsUpdate=t+1e3;for(var e=this.framesThisSecond=0;ethis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(22);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(367),y=i(31),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),u=x(t,"postRender",null),l=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,l,c),a=o=!1),o&&(i.width=l,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,l,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],u=i[s>i.length-3?i.length-1:s+2];return e.set(l(r,o.x,a.x,h.x,u.x),l(r,o.y,a.y,h.y,u.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===l.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===l.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(17),s=i(0),r=i(76),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,u[a++]=(15&i)<<4|n>>2,u[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(144),s=i(0),r=i(68),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=t.context.createStereoPanner(),this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+u+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],l=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+l+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(135),r=i(80),o=i(2),a=i(64),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=l(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1094),r=i(67),o=i(10),a=i(32),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(l(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&u(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(55),s=i(19)(!1,s={Circle:i(1185),Ellipse:i(1195),Intersects:i(462),Line:i(1215),Mesh:i(1237),Point:i(1240),Polygon:i(1254),Rectangle:i(480),Triangle:i(1287)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(226),CircleToRectangle:i(149),GetCircleToCircle:i(1205),GetCircleToRectangle:i(1206),GetLineToCircle:i(227),GetLineToLine:i(463),GetLineToPoints:i(464),GetLineToPolygon:i(465),GetLineToRectangle:i(229),GetRaysFromPointToPolygon:i(1207),GetRectangleIntersection:i(1208),GetRectangleToRectangle:i(1209),GetRectangleToTriangle:i(1210),GetTriangleToCircle:i(1211),GetTriangleToLine:i(470),GetTriangleToTriangle:i(1212),LineToCircle:i(228),LineToLine:i(91),LineToRectangle:i(466),PointToLine:i(474),PointToLineSegment:i(1213),RectangleToRectangle:i(112),RectangleToTriangle:i(467),RectangleToValues:i(1214),TriangleToCircle:i(469),TriangleToLine:i(471),TriangleToTriangle:i(472)}},function(t,e,i){var g=i(36);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,u=r-n,l=o-s,c=e.x2-a,d=e.y2-h;if(0==u||0==d*u-c*l)return!1;var f=(u*(h-s)+l*(n-a))/(c*l-d*u),p=(a+c*f-n)/u;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(487),h=i(488),n=i(0),u=i(9),l=i(3),s=new n({Extends:u,initialize:function(t,e){u.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xl))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=M(t,e,s,this.OVERLAP_BIAS),p=R(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,l+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,u,l,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,u=t.body,l={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!u(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,u,l,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),u=n,l=s,p=f=d=c=void 0,c=Math.max(u.minX,l.minX),d=Math.max(u.minY,l.minY),f=Math.min(u.maxX,l.maxX),p=Math.min(u.maxY,l.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0n.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=u(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(254),p=i(552),g=i(158);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],u=0;u=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(119),E=i(556),b=i(254);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=u(e,i),o.tilesets=l(e),o}},function(t,e,i){var d=i(117),f=i(83);t.exports=function(t,e){for(var i=[],n=0;ne.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(u.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(31),C=i(35),M=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=M(e,"callback"),s=M(e,"type","image/png"),r=M(e,"encoder",.92),o=M(e,"x",0),a=M(e,"y",0),h=M(e,"getPixel",!1),u=M(e,"isFramebuffer",!1),l=u?M(e,"bufferWidth",1):i.drawingBufferWidth,c=u?M(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=u?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=M(e,"width",l),g=M(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;w>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(320),BaseCamera:i(131),CameraManager:i(775),Effects:i(327),Events:i(34)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(17),s=i(0),u=i(34),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?u.FADE_OUT_START:u.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(l=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:lMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(345);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(14);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(366),Palettes:i(885)}},function(t,e,i){t.exports={ARNE16:i(367),C64:i(886),CGA:i(887),JMP:i(888),MSX:i(889)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(891),MoveTo:i(371),CubicBezier:i(368),Curve:i(89),Ellipse:i(369),Line:i(370),QuadraticBezier:i(372),Spline:i(373)}},function(t,e,i){var n=i(0),l=i(368),u=i(369),s=i(5),r=i(370),o=i(371),a=i(372),h=i(10),c=i(373),d=i(3),f=i(14),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),u=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new l(h,o,a,u))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(35),u=i(377);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=u(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=u(s,n,t),a=u(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(184);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:u(t,n,h),g:u(e,s,h),b:u(i,r,h)}}var u=i(133);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(191),s=i(35);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(376);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(304),GeometryMask:i(305)}},function(t,e,i){var n={AddToDOM:i(139),DOMContentLoaded:i(378),GetInnerHeight:i(379),GetScreenOrientation:i(380),GetTarget:i(385),ParseXML:i(386),RemoveFromDOM:i(197),RequestAnimationFrame:i(364)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(915)}},function(t,e,i){var n=i(0),s=i(9),r=i(24),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(139),s=i(315),r=i(319),o=i(31),a=i(0),h=i(340),u=i(917),l=i(360),c=i(98),d=i(362),f=i(341),p=i(378),g=i(9),v=i(22),m=i(387),y=i(24),x=i(392),T=i(393),w=i(395),E=i(103),b=i(400),S=i(363),A=i(365),_=i(404),C=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new b(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),l(this),u(this),d(this),n(this.canvas,this.config.parent),this.textures.once(E.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=C},function(t,e,i){var n=i(139);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){t.exports={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"}},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var u=i(78);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),u(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var R=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=R(e,"chars","");if(""!==o){var a=R(e,"image",""),h=t.sys.textures.getFrame(a),u=h.cutX,l=h.cutY,c=h.source.width,d=h.source.height,f=R(e,"offset.x",0),p=R(e,"offset.y",0),g=R(e,"spacing.x",0),v=R(e,"spacing.y",0),m=R(e,"lineSpacing",0),y=R(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},E=0,b=0;b=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(186);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(112);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(33);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){u.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){u.revokeObjectURL(s.data),s.onProcessError()},u.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;r=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(416),List:i(105),Map:i(99),ProcessQueue:i(206),RTree:i(509),Set:i(147),Size:i(394)}},function(t,e,i){var n=i(19),s=i(1404),r=n(!1,r={CanvasTexture:i(401),Events:i(103),FilterMode:s,Frame:i(104),Parsers:i(403),Texture:i(201),TextureManager:i(400),TextureSource:i(402)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(19),s=i(1406),r=n(!1,r={Components:i(245),Parsers:i(1439),Formats:i(37),ImageCollection:i(556),ParseToTilemap:i(256),Tile:i(83),Tilemap:i(560),TilemapCreator:i(1445),TilemapFactory:i(1446),Tileset:i(119),TilemapLayer:i(561),Orientation:i(29),LayerData:i(117),MapData:i(118),ObjectLayer:i(552)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(29)};t.exports=n},function(t,e,i){var p=i(26),g=i(60);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),u=s-t,l=r-e,c=0;c=t&&u.index<=e&&l(u,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(71),h=i(60),u=i(157);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(77),DeepCopy:i(171),Extend:i(19),GetAdvancedValue:i(13),GetFastValue:i(2),GetMinMaxValue:i(1471),GetValue:i(6),HasAll:i(1472),HasAny:i(433),HasValue:i(125),IsPlainObject:i(7),Merge:i(142),MergeRight:i(1473),Pick:i(551),SetValue:i(456)}},function(t,e,i){var o=i(6),a=i(17);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;i=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=l},function(t,e,i){t.exports={Alpha:i(605),AlphaSingle:i(297),BlendMode:i(298),ComputedSize:i(606),Crop:i(607),Depth:i(299),Flip:i(608),GetBounds:i(609),Mask:i(303),Origin:i(630),PathFollower:i(631),Pipeline:i(171),ScrollFactor:i(306),Size:i(632),Texture:i(633),TextureCrop:i(634),Tint:i(635),ToJSON:i(173),Transform:i(307),TransformMatrix:i(25),Visible:i(308)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var u=[],l=e;lthis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=u},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e,i){var n=i(0),y=i(172),s=i(9),v=i(368),x=i(2),m=i(67),T=i(88),w=i(139),E=i(12),b=i(369),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=l[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=l.length-1;0<=d;d--)l[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(20),u=i(23),s=i(8),l=i(2),c=i(6),d=i(7),r=new n({Extends:u,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=l(r=e,"key"),i=l(r,"url"),n=l(r,"xhrSettings"),o=l(r,"extension",o),s=l(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};u.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports={BITMAPMASK_PIPELINE:"BitmapMaskPipeline",LIGHT_PIPELINE:"Light2D",POINTLIGHT_PIPELINE:"PointLightPipeline",SINGLE_PIPELINE:"SinglePipeline",MULTI_PIPELINE:"MultiPipeline",ROPE_PIPELINE:"RopePipeline",GRAPHICS_PIPELINE:"GraphicsPipeline",POSTFX_PIPELINE:"PostFXPipeline",UTILITY_PIPELINE:"UtilityPipeline"}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(37),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,u,l,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=u,v[10]=l,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,E=n*h-s*a,b=u*p-l*f,S=u*g-c*f,A=u*v-d*f,_=l*g-c*p,C=l*v-d*p,M=c*v-d*g,R=m*M-y*C+x*_+T*A-w*S+E*b;return R?(R=1/R,this.setValues((o*M-a*C+h*_)*R,(n*C-i*M-s*_)*R,(p*E-g*w+v*T)*R,(c*w-l*E-d*T)*R,(a*A-r*M-h*S)*R,(e*M-n*A+s*S)*R,(g*x-f*E-v*y)*R,(u*E-c*x+d*y)*R,(r*C-o*A+h*b)*R,(i*A-e*C-s*b)*R,(f*w-p*x+v*m)*R,(l*x-u*w-d*m)*R,(o*S-r*_-a*b)*R,(e*_-i*S+n*b)*R,(p*y-f*T-g*m)*R,(u*T-l*y+c*m)*R)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-l*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-l*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+l*(n*h-s*a)),-(r*(c*v-d*g)-u*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-u*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+u*(n*h-s*a),r*(l*v-d*p)-u*(o*v-h*p)+f*(o*d-h*l),-(e*(l*v-d*p)-u*(i*v-s*p)+f*(i*d-s*l)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*l)-r*(i*d-s*l)+u*(i*h-s*o)),-(r*(l*g-c*p)-u*(o*g-a*p)+f*(o*c-a*l)),e*(l*g-c*p)-u*(i*g-n*p)+f*(i*c-n*l),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*l)-r*(i*c-n*l)+u*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],u=t[8],l=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(l*v-d*p)+(e*h-s*r)*(l*g-c*p)+(i*a-n*o)*(u*v-d*f)-(i*h-s*o)*(u*g-c*f)+(n*h-s*a)*(u*p-l*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],u=e[7],l=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],E=y[3];return e[0]=x*i+T*o+w*l+E*p,e[1]=x*n+T*a+w*c+E*g,e[2]=x*s+T*h+w*d+E*v,e[3]=x*r+T*u+w*f+E*m,x=y[4],T=y[5],w=y[6],E=y[7],e[4]=x*i+T*o+w*l+E*p,e[5]=x*n+T*a+w*c+E*g,e[6]=x*s+T*h+w*d+E*v,e[7]=x*r+T*u+w*f+E*m,x=y[8],T=y[9],w=y[10],E=y[11],e[8]=x*i+T*o+w*l+E*p,e[9]=x*n+T*a+w*c+E*g,e[10]=x*s+T*h+w*d+E*v,e[11]=x*r+T*u+w*f+E*m,x=y[12],T=y[13],w=y[14],E=y[15],e[12]=x*i+T*o+w*l+E*p,e[13]=x*n+T*a+w*c+E*g,e[14]=x*s+T*h+w*d+E*v,e[15]=x*r+T*u+w*f+E*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],u=i[5],l=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],E=n[8],b=n[12],S=n[1],A=n[5],_=n[9],C=n[13],M=n[2],R=n[6],P=n[10],O=n[14],L=n[3],D=n[7],F=n[11],k=n[15];return this.setValues(s*T+r*S+o*M+a*L,h*T+u*S+l*M+c*L,d*T+f*S+p*M+g*L,v*T+m*S+y*M+x*L,s*w+r*A+o*R+a*D,h*w+u*A+l*R+c*D,d*w+f*A+p*R+g*D,v*w+m*A+y*R+x*D,s*E+r*_+o*P+a*F,h*E+u*_+l*P+c*F,d*E+f*_+p*P+g*F,v*E+m*_+y*P+x*F,s*b+r*C+o*O+a*k,h*b+u*C+l*O+c*k,d*b+f*C+p*O+g*k,v*b+m*C+y*O+x*k)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,u=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,u*o+i,u*a-n*r,0,h*a-n*o,u*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),u=1-h,l=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],E=i[12],b=i[13],S=i[14],A=i[15],_=n*n*u+h,C=s*n*u+r*a,M=r*n*u-s*a,R=n*s*u-r*a,P=s*s*u+h,O=r*s*u+n*a,L=n*r*u+s*a,D=s*r*u-n*a,F=r*r*u+h;return this.setValues(l*_+p*C+y*M,c*_+g*C+x*M,d*_+v*C+T*M,f*_+m*C+w*M,l*R+p*P+y*O,c*R+g*P+x*O,d*R+v*P+T*O,f*R+m*P+w*O,l*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,E,b,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],u=e[9],l=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+u*i,e[6]=o*n+l*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=u*n-r*i,e[10]=l*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],u=e[9],l=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-u*i,e[2]=o*n-l*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+u*n,e[10]=o*i+l*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],u=e[5],l=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+u*i,e[2]=o*n+l*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=u*n-r*i,e[6]=l*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,u=i*o,l=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),l+m,c-v,0,l-m,1-(u+p),f+g,0,c+v,f-g,1-(u+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,u=e*o,l=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),u+v,l-g,0,u-v,1-(h+f),d+p,0,l+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return l.subVectors(t,e),0===l.getLengthSquared()&&(l.z=1),l.normalize(),o.crossVectors(i,l),0===o.getLengthSquared()&&(1===Math.abs(i.z)?l.x+=1e-4:l.z+=1e-4,l.normalize(),o.crossVectors(i,l)),o.normalize(),a.crossVectors(l,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=l.x,n[9]=l.y,n[10]=l.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,u=e.x,l=e.y,c=e.z;if(Math.abs(n-u)<1e-6&&Math.abs(s-l)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-u,f=s-l,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),u.zero();var n=this.val,s=h.val,r=u.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(u),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),u.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(u),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],u=i[5],l=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],E=n[2],b=n[3],S=n[4],A=n[5],_=n[6],C=n[7],M=n[8],R=n[9],P=n[10],O=n[11],L=n[12],D=n[13],F=n[14],k=n[15];return e.setValues(T*s+w*h+E*d+b*v,w*r+w*u+E*f+b*m,E*o+w*l+E*p+b*y,b*a+w*c+E*g+b*x,S*s+A*h+_*d+C*v,S*r+A*u+_*f+C*m,S*o+A*l+_*p+C*y,S*a+A*c+_*g+C*x,M*s+R*h+P*d+O*v,M*r+R*u+P*f+O*m,M*o+R*l+P*p+O*y,M*a+R*c+P*g+O*x,L*s+D*h+F*d+k*v,L*r+D*u+F*f+k*m,L*o+D*l+F*p+k*y,L*a+D*c+F*g+k*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),u=Math.cos(t.y),l=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*u,m=a*u;return i||(l=u*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(u,p,g,0,0,a,o,0,h,v,m,0,l,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,u=new r,o=new s,a=new s,l=new s;t.exports=r},function(t,e,i){"use strict";function n(t,e,i){i=i||2;var n,s,r,o,a,h,u,l=e&&e.length,c=l?e[0]*i:t.length,d=g(t,0,c,i,!0),f=[];if(!d||d.next===d.prev)return f;if(l&&(d=function(t,e,i,n){var s,r,o,a,h,u=[];for(s=0,r=e.length;s=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=l&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==u;);return i}(t,e))&&(i=b(e,t),v(e,e.next),v(i,i.next))}}(u[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,l=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(u,l,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,u=h.next;else if((t=h)===u){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!l(s,r)&&c(s,n,n.next,r)&&E(s,r)&&E(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(E(t,e)&&E(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||l(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function u(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=l},function(t,e,i){var n=i(29),s=i(0),r=i(11),o=i(496),a=new s({Mixins:[r.Alpha,r.Flip,r.Visible],initialize:function(t,e,i,n,s,r,o,a){this.layer=t,this.index=e,this.x=i,this.y=n,this.width=s,this.height=r,this.right,this.bottom,this.baseWidth=void 0!==o?o:s,this.baseHeight=void 0!==a?a:r,this.pixelX=0,this.pixelY=0,this.updatePixelXY(),this.properties={},this.rotation=0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceLeft=!1,this.faceRight=!1,this.faceTop=!1,this.faceBottom=!1,this.collisionCallback=void 0,(this.collisionCallbackContext=this).tint=16777215,this.physics={}},containsPoint:function(t,e){return!(tthis.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){t.exports={POST_RENDER:i(626),PRE_RENDER:i(627),RENDER:i(628),RESIZE:i(629)}},function(t,e,i){var h=i(74);t.exports=function(t,e,i,n){if(void 0===n&&(n=t),!Array.isArray(e))return-1!==(o=t.indexOf(e))?(h(t,o),i&&i.call(n,e),e):null;for(var s=e.length-1,r=[];0<=s;){var o,a=e[s];-1!==(o=t.indexOf(a))&&(h(t,o),r.push(a),i&&i.call(n,a)),s--}return r}},function(t,e,i){var n=i(0),s=i(196),r=i(10),o=i(3),a=new n({initialize:function(t){this.type=t,this.defaultDivisions=5,this.arcLengthDivisions=100,this.cacheArcLengths=[],this.needsUpdate=!0,this.active=!0,this._tmpVec2A=new o,this._tmpVec2B=new o},draw:function(t,e){return void 0===e&&(e=32),t.strokePoints(this.getPoints(e))},getBounds:function(t,e){t=t||new r,void 0===e&&(e=16);var i=this.getLength();ih||a.y>u)?(l=Math.max(a.x,e),c=Math.max(a.y,i),E=d=Math.min(a.r,h)-l,b=f=Math.min(a.b,u)-c,T=r?p+(v-(l-a.x)-d):p+(l-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=l,i=c,n=d,s=f):b=E=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+E)/A),t.v1=Math.min(1,(w+b)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=E,t.ch=b,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(205),n=i(0),r=i(1),o=i(79),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),l=i(37),s=new n({Extends:l,initialize:function(t,e,i,n,s,r,o,a,h,u){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===u&&(u=0),l.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=u,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],u=s*a[1]+r*a[5]+o*a[9]+a[13],l=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-u/c*i,this.vz=n<=0?l/c:-l/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,u=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),u=Math.round(u)),this.tx=h,this.ty=u,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},,,function(t,e){t.exports=function(t,e,i){return 0<=t&&t=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},,function(t,e){t.exports={DEFAULT:0,LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(4);t.exports=function(t,e,i){return void 0===i&&(i=new n),i.x=t.x+t.radius*Math.cos(e),i.y=t.y+t.radius*Math.sin(e),i}},function(t,e,i){var a=i(4);t.exports=function(t,e){void 0===e&&(e=new a);var i=2*Math.PI*Math.random(),n=Math.random()+Math.random(),s=1=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(321),s=i(186),r=i(325),o=i(326);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(100);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(36),s=i(324);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(102),r=i(134),o=i(31),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var u,l,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(u=this.pipeline).manager.set(u),l=y.width,c=y.height,d=h.width/l,f=h.height/c,u.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},,function(t,e,i){t.exports={CalculateFacesAt:i(248),CalculateFacesWithin:i(61),CheckIsoBounds:i(537),Copy:i(1414),CreateFromTiles:i(1415),CullBounds:i(539),CullTiles:i(540),Fill:i(1416),FilterTiles:i(1417),FindByIndex:i(1418),FindTile:i(1419),ForEachTile:i(1420),GetCullTilesFunction:i(1421),GetTileAt:i(156),GetTileAtWorldXY:i(1422),GetTilesWithin:i(26),GetTilesWithinShape:i(1423),GetTilesWithinWorldXY:i(523),GetTileToWorldXFunction:i(1424),GetTileToWorldXYFunction:i(1425),GetTileToWorldYFunction:i(1426),GetWorldToTileXFunction:i(1427),GetWorldToTileXYFunction:i(1428),GetWorldToTileYFunction:i(1429),HasTileAt:i(558),HasTileAtWorldXY:i(1430),HexagonalCullBounds:i(542),HexagonalCullTiles:i(541),HexagonalTileToWorldXY:i(546),HexagonalTileToWorldY:i(550),HexagonalWorldToTileXY:i(552),HexagonalWorldToTileY:i(556),IsInLayerBounds:i(118),IsometricCullTiles:i(543),IsometricTileToWorldXY:i(547),IsometricWorldToTileXY:i(553),PutTileAt:i(253),PutTileAtWorldXY:i(1431),PutTilesAt:i(1432),Randomize:i(1433),RemoveTileAt:i(559),RemoveTileAtWorldXY:i(1434),RenderDebug:i(1435),ReplaceByIndex:i(538),RunCull:i(157),SetCollision:i(1436),SetCollisionBetween:i(1437),SetCollisionByExclusion:i(1438),SetCollisionByProperty:i(1439),SetCollisionFromCollisionGroup:i(1440),SetLayerCollisionIndex:i(158),SetTileCollision:i(72),SetTileIndexCallback:i(1441),SetTileLocationCallback:i(1442),Shuffle:i(1443),StaggeredCullBounds:i(545),StaggeredCullTiles:i(544),StaggeredTileToWorldXY:i(548),StaggeredTileToWorldY:i(551),StaggeredWorldToTileXY:i(554),StaggeredWorldToTileY:i(557),SwapByIndex:i(1444),TileToWorldX:i(249),TileToWorldXY:i(549),TileToWorldY:i(250),WeightedRandomize:i(1445),WorldToTileX:i(251),WorldToTileXY:i(555),WorldToTileY:i(252)}},function(t,e,i){var u=i(156);t.exports=function(t,e,i){var n=u(t,e,!0,i),s=u(t,e-1,!0,i),r=u(t,e+1,!0,i),o=u(t-1,e,!0,i),a=u(t+1,e,!0,i),h=n&&n.collides;return h&&(n.faceTop=!0,n.faceBottom=!0,n.faceLeft=!0,n.faceRight=!0),s&&s.collides&&(h&&(n.faceTop=!1),s.faceBottom=!h),r&&r.collides&&(h&&(n.faceBottom=!1),r.faceTop=!h),o&&o.collides&&(h&&(n.faceLeft=!1),o.faceRight=!h),a&&a.collides&&(h&&(n.faceRight=!1),a.faceLeft=!h),n&&!n.collides&&n.resetFaces(),n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileWidth,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.x+e.scrollX*(1-s.scrollFactorX),n*=s.scaleX),r+t*n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileHeight,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.y+e.scrollY*(1-s.scrollFactorY),n*=s.scaleY),r+t*n}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileWidth,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.x+i.scrollX*(1-r.scrollFactorX),s*=r.scaleX),e?Math.floor(t/s):t/s}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileHeight,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.y+i.scrollY*(1-r.scrollFactorY),s*=r.scaleY),e?Math.floor(t/s):t/s}},function(t,e,i){var l=i(83),c=i(118),d=i(248),f=i(72);t.exports=function(t,e,i,n,s){if(void 0===n&&(n=!0),!c(e,i,s))return null;var r,o=s.data[i][e],a=o&&o.collides;t instanceof l?(null===s.data[i][e]&&(s.data[i][e]=new l(s,t.index,e,i,s.tileWidth,s.tileHeight)),s.data[i][e].copy(t)):(r=t,null===s.data[i][e]?s.data[i][e]=new l(s,r,e,i,s.tileWidth,s.tileHeight):s.data[i][e].index=r);var h=s.data[i][e],u=-1!==s.collideIndexes.indexOf(h.index);return f(h,u),n&&a!==h.collides&&d(e,i,s),h}},function(t,e,i){var n=i(29);t.exports=function(t){return"isometric"===(t=t.toLowerCase())?n.ISOMETRIC:"staggered"===t?n.STAGGERED:"hexagonal"===t?n.HEXAGONAL:n.ORTHOGONAL}},function(t,e,i){var p=i(38),g=i(119),v=i(120),m=i(83);t.exports=function(t,e,i,n,s){for(var r=new g({tileWidth:i,tileHeight:n}),o=new v({name:t,tileWidth:i,tileHeight:n,format:p.ARRAY_2D,layers:[r]}),a=[],h=e.length,u=0,l=0;lt&&(t=s.totalDuration),s.delay=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),u=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(182),s=i(0),r=i(99),o=i(9),a=i(130),h=i(22),T=i(2),d=i(6),f=i(183),p=i(316),u=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1u.right&&(l=b(l,l+(d-u.right),this.lerp.x)),fu.bottom&&(c=b(c,c+(f-u.bottom),this.lerp.y))):(l=b(l,d-o,this.lerp.x),c=b(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(l=this.clampX(l),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),l=Math.round(l),c=Math.round(c));var g=(this.scrollX=l)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(E.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=l(i,0,1),n=l(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,u=t.y-r;return this.midPoint.set(h,u),this.scrollX=h-o,this.scrollY=u-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=u},function(t,e,i){var o=i(36);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,u=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(36);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(36);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(737),Flash:i(738),Pan:i(739),Shake:i(772),RotateTo:i(773),Zoom:i(774)}},function(t,e,i){t.exports={In:i(740),Out:i(741),InOut:i(742)}},function(t,e,i){t.exports={In:i(743),Out:i(744),InOut:i(745)}},function(t,e,i){t.exports={In:i(746),Out:i(747),InOut:i(748)}},function(t,e,i){t.exports={In:i(749),Out:i(750),InOut:i(751)}},function(t,e,i){t.exports={In:i(752),Out:i(753),InOut:i(754)}},function(t,e,i){t.exports={In:i(755),Out:i(756),InOut:i(757)}},function(t,e,i){t.exports=i(758)},function(t,e,i){t.exports={In:i(759),Out:i(760),InOut:i(761)}},function(t,e,i){t.exports={In:i(762),Out:i(763),InOut:i(764)}},function(t,e,i){t.exports={In:i(765),Out:i(766),InOut:i(767)}},function(t,e,i){t.exports={In:i(768),Out:i(769),InOut:i(770)}},function(t,e,i){t.exports=i(771)},function(t,e,i){var n=i(0),h=i(39),u=i(341),l=i(2),c=i(6),d=i(7),f=i(190),p=i(1),g=i(194),v=i(184),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",u.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=u.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=l(r,"global",[]),this.installScenePlugins=l(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(102),browser:i(134),features:i(188),input:i(805),audio:i(806),video:i(807),fullscreen:i(808),canvasFeatures:i(342)}},function(t,e,i){var n,s,r,o=i(31),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(361),u=a(31),l=a(39),c=a(188);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===l.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==l.HEADLESS)if(e.renderType===l.CANVAS||e.renderType!==l.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=l.CANVAS}else e.renderType=l.WEBGL;e.antialias||u.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=u.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==l.HEADLESS&&(i=a(362),n=a(365),e.renderType===l.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var d=i(35),l=i(363),n=i(0),s=i(39),r=i(9),f=i(88),o=i(364),a=i(101),h=i(103),u=i(25),c=new n({Extends:r,initialize:function(t){r.call(this);var e=t.config;this.config={clearBeforeRender:e.clearBeforeRender,backgroundColor:e.backgroundColor,antialias:e.antialias,roundPixels:e.roundPixels},this.game=t,this.type=s.CANVAS,this.drawCount=0,this.width=0,this.height=0,this.gameCanvas=t.canvas;var i={alpha:t.config.transparent,desynchronized:t.config.desynchronized};this.gameContext=e.context?e.context:this.gameCanvas.getContext("2d",i),this.currentContext=this.gameContext,this.antialias=t.config.antialias,this.blendModes=o(),this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92},this._tempMatrix1=new u,this._tempMatrix2=new u,this._tempMatrix3=new u,this.isBooted=!1,this.init()},init:function(){this.game.textures.once(h.READY,this.boot,this)},boot:function(){var t=this.game,e=t.scale.baseSize;this.width=e.width,this.height=e.height,this.isBooted=!0,t.scale.on(a.RESIZE,this.onResize,this),this.resize(e.width,e.height)},onResize:function(t,e){e.width===this.width&&e.height===this.height||this.resize(e.width,e.height)},resize:function(t,e){this.width=t,this.height=e,this.emit(f.RESIZE,t,e)},resetTransform:function(){this.currentContext.setTransform(1,0,0,1,0,0)},setBlendMode:function(t){return this.currentContext.globalCompositeOperation=t,this},setContext:function(t){return this.currentContext=t||this.gameContext,this},setAlpha:function(t){return this.currentContext.globalAlpha=t,this},preRender:function(){var t=this.gameContext,e=this.config,i=this.width,n=this.height;t.globalAlpha=1,t.globalCompositeOperation="source-over",t.setTransform(1,0,0,1,0,0),e.clearBeforeRender&&t.clearRect(0,0,i,n),e.transparent||(t.fillStyle=e.backgroundColor.rgba,t.fillRect(0,0,i,n)),t.save(),this.drawCount=0,this.emit(f.PRE_RENDER)},render:function(t,e,i){var n=e.length;this.emit(f.RENDER,t,i);var s=i.x,r=i.y,o=i.width,a=i.height,h=i.renderToTexture?i.context:t.sys.context;h.save(),this.game.scene.customViewports&&(h.beginPath(),h.rect(s,r,o,a),h.clip()),this.currentContext=h;var u=i.mask;u&&u.preRenderCanvas(this,null,i._maskCamera),i.transparent||(h.fillStyle=i.backgroundColor.rgba,h.fillRect(s,r,o,a)),h.globalAlpha=i.alpha,h.globalCompositeOperation="source-over",this.drawCount+=n,i.renderToTexture&&i.emit(d.PRE_RENDER,i),i.matrix.copyToContext(h);for(var l=0;le.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(u.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(31),C=i(36),M=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=M(e,"callback"),s=M(e,"type","image/png"),r=M(e,"encoder",.92),o=M(e,"x",0),a=M(e,"y",0),h=M(e,"getPixel",!1),u=M(e,"isFramebuffer",!1),l=u?M(e,"bufferWidth",1):i.drawingBufferWidth,c=u?M(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=u?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=M(e,"width",l),g=M(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;wthis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(22);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(383),y=i(31),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),u=x(t,"postRender",null),l=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,l,c),a=o=!1),o&&(i.width=l,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,l,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],u=i[s>i.length-3?i.length-1:s+2];return e.set(l(r,o.x,a.x,h.x,u.x),l(r,o.y,a.y,h.y,u.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===l.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===l.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(18),s=i(0),r=i(76),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,u[a++]=(15&i)<<4|n>>2,u[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(145),s=i(0),r=i(69),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=null,this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),t.context.createStereoPanner?(this.pannerNode=t.context.createStereoPanner(),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination)):this.volumeNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+u+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],l=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+l+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(135),r=i(80),o=i(2),a=i(66),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=l(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1094),r=i(68),o=i(10),a=i(32),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(l(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&u(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(55),s=i(17)(!1,s={Circle:i(1185),Ellipse:i(1195),Intersects:i(478),Line:i(1215),Mesh:i(1237),Point:i(1240),Polygon:i(1254),Rectangle:i(496),Triangle:i(1287)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(228),CircleToRectangle:i(150),GetCircleToCircle:i(1205),GetCircleToRectangle:i(1206),GetLineToCircle:i(229),GetLineToLine:i(479),GetLineToPoints:i(480),GetLineToPolygon:i(481),GetLineToRectangle:i(231),GetRaysFromPointToPolygon:i(1207),GetRectangleIntersection:i(1208),GetRectangleToRectangle:i(1209),GetRectangleToTriangle:i(1210),GetTriangleToCircle:i(1211),GetTriangleToLine:i(486),GetTriangleToTriangle:i(1212),LineToCircle:i(230),LineToLine:i(92),LineToRectangle:i(482),PointToLine:i(490),PointToLineSegment:i(1213),RectangleToRectangle:i(114),RectangleToTriangle:i(483),RectangleToValues:i(1214),TriangleToCircle:i(485),TriangleToLine:i(487),TriangleToTriangle:i(488)}},function(t,e,i){var g=i(37);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,u=r-n,l=o-s,c=e.x2-a,d=e.y2-h;if(0==u||0==d*u-c*l)return!1;var f=(u*(h-s)+l*(n-a))/(c*l-d*u),p=(a+c*f-n)/u;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(503),h=i(504),n=i(0),u=i(9),l=i(3),s=new n({Extends:u,initialize:function(t,e){u.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xl))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=M(t,e,s,this.OVERLAP_BIAS),p=R(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,l+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,u,l,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,u=t.body,l={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!u(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,u,l,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),u=n,l=s,p=f=d=c=void 0,c=Math.max(u.minX,l.minX),d=Math.max(u.minY,l.minY),f=Math.min(u.maxX,l.maxX),p=Math.min(u.maxY,l.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0n.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=u(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(256),p=i(568),g=i(159);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],u=0;u=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(121),E=i(572),b=i(256);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=u(e,i),o.tilesets=l(e),o}},function(t,e,i){var d=i(119),f=i(83);t.exports=function(t,e){for(var i=[],n=0;n>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(320),BaseCamera:i(131),CameraManager:i(775),Effects:i(327),Events:i(35)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(18),s=i(0),u=i(35),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?u.FADE_OUT_START:u.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(l=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:lMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(345);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(14);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(382),Palettes:i(885)}},function(t,e,i){t.exports={ARNE16:i(383),C64:i(886),CGA:i(887),JMP:i(888),MSX:i(889)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(891),MoveTo:i(387),CubicBezier:i(384),Curve:i(90),Ellipse:i(385),Line:i(386),QuadraticBezier:i(388),Spline:i(389)}},function(t,e,i){var n=i(0),l=i(384),u=i(385),s=i(5),r=i(386),o=i(387),a=i(388),h=i(10),c=i(389),d=i(3),f=i(14),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),u=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new l(h,o,a,u))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(36),u=i(393);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=u(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=u(s,n,t),a=u(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(185);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:u(t,n,h),g:u(e,s,h),b:u(i,r,h)}}var u=i(133);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(192),s=i(36);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(392);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(304),GeometryMask:i(305)}},function(t,e,i){var n={AddToDOM:i(140),DOMContentLoaded:i(394),GetInnerHeight:i(395),GetScreenOrientation:i(396),GetTarget:i(401),ParseXML:i(402),RemoveFromDOM:i(199),RequestAnimationFrame:i(380)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(915)}},function(t,e,i){var n=i(0),s=i(9),r=i(24),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(140),s=i(315),r=i(319),o=i(31),a=i(0),h=i(340),u=i(917),l=i(360),c=i(98),d=i(378),f=i(341),p=i(394),g=i(9),v=i(22),m=i(403),y=i(24),x=i(408),T=i(409),w=i(411),E=i(103),b=i(416),S=i(379),A=i(381),_=i(420),C=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new b(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),l(this),u(this),d(this),n(this.canvas,this.config.parent),this.textures.once(E.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=C},function(t,e,i){var n=i(140);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){t.exports={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"}},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var u=i(78);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),u(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var R=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=R(e,"chars","");if(""!==o){var a=R(e,"image",""),h=t.sys.textures.getFrame(a),u=h.cutX,l=h.cutY,c=h.source.width,d=h.source.height,f=R(e,"offset.x",0),p=R(e,"offset.y",0),g=R(e,"spacing.x",0),v=R(e,"spacing.y",0),m=R(e,"lineSpacing",0),y=R(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},E=0,b=0;b=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(187);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(114);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(34);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){u.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){u.revokeObjectURL(s.data),s.onProcessError()},u.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;r=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(432),List:i(107),Map:i(99),ProcessQueue:i(208),RTree:i(525),Set:i(148),Size:i(410)}},function(t,e,i){var n=i(17),s=i(1411),r=n(!1,r={CanvasTexture:i(417),Events:i(103),FilterMode:s,Frame:i(106),Parsers:i(419),Texture:i(203),TextureManager:i(416),TextureSource:i(418)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(17),s=i(1413),r=n(!1,r={Components:i(247),Parsers:i(1446),Formats:i(38),ImageCollection:i(572),ParseToTilemap:i(258),Tile:i(83),Tilemap:i(576),TilemapCreator:i(1452),TilemapFactory:i(1453),Tileset:i(121),TilemapLayer:i(577),Orientation:i(29),LayerData:i(119),MapData:i(120),ObjectLayer:i(568)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(29)};t.exports=n},function(t,e,i){var p=i(26),g=i(61);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),u=s-t,l=r-e,c=0;c=t&&u.index<=e&&l(u,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(72),h=i(61),u=i(158);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(77),DeepCopy:i(172),Extend:i(17),GetAdvancedValue:i(13),GetFastValue:i(2),GetMinMaxValue:i(1478),GetValue:i(6),HasAll:i(1479),HasAny:i(449),HasValue:i(125),IsPlainObject:i(7),Merge:i(143),MergeRight:i(1480),Pick:i(567),SetValue:i(472)}},function(t,e,i){var o=i(6),a=i(18);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;i=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=u},function(t,e,i){t.exports={Alpha:i(629),AlphaSingle:i(314),BlendMode:i(315),ComputedSize:i(630),Crop:i(631),Depth:i(316),Flip:i(632),GetBounds:i(633),Mask:i(320),Origin:i(654),PathFollower:i(655),Pipeline:i(136),ScrollFactor:i(323),Size:i(656),Texture:i(657),TextureCrop:i(658),Tint:i(659),ToJSON:i(182),Transform:i(324),TransformMatrix:i(26),Visible:i(325)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var l=[],u=e;ut.max.x&&(t.max.x=s.x),s.xt.max.y&&(t.max.y=s.y),s.y=t.min.x&&e.x<=t.max.x&&e.y>=t.min.y&&e.y<=t.max.y},i.overlaps=function(t,e){return t.min.x<=e.max.x&&t.max.x>=e.min.x&&t.max.y>=e.min.y&&t.min.y<=e.max.y},i.translate=function(t,e){t.min.x+=e.x,t.max.x+=e.x,t.min.y+=e.y,t.max.y+=e.y},i.shift=function(t,e){var i=t.max.x-t.min.x,n=t.max.y-t.min.y;t.min.x=e.x,t.max.x=e.x+i,t.min.y=e.y,t.max.y=e.y+n}},function(t,e,i){var n={VERSION:"3.50.0",BlendModes:i(36),ScaleModes:i(174),AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,FOREVER:-1,NONE:4,UP:5,DOWN:6,LEFT:7,RIGHT:8};t.exports=n},function(t,e){t.exports=function(t){return t.y+t.height-t.height*t.originY}},function(t,e){t.exports=function(t){return t.x-t.width*t.originX}},function(t,e){t.exports=function(t){return t.x+t.width-t.width*t.originX}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY}},function(t,e){t.exports=function(t,e,i,n,s,r){var o;void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=1);var a=0,h=t.length;if(1===r)for(o=s;othis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=l},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return Math.sqrt(s*s+r*r)}},function(t,e,i){t.exports={BOOT:i(942),DESTROY:i(943),DRAG_END:i(944),DRAG_ENTER:i(945),DRAG:i(946),DRAG_LEAVE:i(947),DRAG_OVER:i(948),DRAG_START:i(949),DROP:i(950),GAME_OUT:i(951),GAME_OVER:i(952),GAMEOBJECT_DOWN:i(953),GAMEOBJECT_DRAG_END:i(954),GAMEOBJECT_DRAG_ENTER:i(955),GAMEOBJECT_DRAG:i(956),GAMEOBJECT_DRAG_LEAVE:i(957),GAMEOBJECT_DRAG_OVER:i(958),GAMEOBJECT_DRAG_START:i(959),GAMEOBJECT_DROP:i(960),GAMEOBJECT_MOVE:i(961),GAMEOBJECT_OUT:i(962),GAMEOBJECT_OVER:i(963),GAMEOBJECT_POINTER_DOWN:i(964),GAMEOBJECT_POINTER_MOVE:i(965),GAMEOBJECT_POINTER_OUT:i(966),GAMEOBJECT_POINTER_OVER:i(967),GAMEOBJECT_POINTER_UP:i(968),GAMEOBJECT_POINTER_WHEEL:i(969),GAMEOBJECT_UP:i(970),GAMEOBJECT_WHEEL:i(971),MANAGER_BOOT:i(972),MANAGER_PROCESS:i(973),MANAGER_UPDATE:i(974),POINTER_DOWN:i(975),POINTER_DOWN_OUTSIDE:i(976),POINTER_MOVE:i(977),POINTER_OUT:i(978),POINTER_OVER:i(979),POINTER_UP:i(980),POINTER_UP_OUTSIDE:i(981),POINTER_WHEEL:i(982),POINTERLOCK_CHANGE:i(983),PRE_UPDATE:i(984),SHUTDOWN:i(985),START:i(986),UPDATE:i(987)}},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e,i){var n=i(0),y=i(181),s=i(9),v=i(385),x=i(2),m=i(72),T=i(94),w=i(148),b=i(12),E=i(386),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=u[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=u.length-1;0<=d;d--)u[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(21),l=i(24),s=i(8),u=i(2),c=i(6),d=i(7),r=new n({Extends:l,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=u(r=e,"key"),i=u(r,"url"),n=u(r,"xhrSettings"),o=u(r,"extension",o),s=u(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};l.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports={BITMAPMASK_PIPELINE:"BitmapMaskPipeline",LIGHT_PIPELINE:"Light2D",POINTLIGHT_PIPELINE:"PointLightPipeline",SINGLE_PIPELINE:"SinglePipeline",MULTI_PIPELINE:"MultiPipeline",ROPE_PIPELINE:"RopePipeline",GRAPHICS_PIPELINE:"GraphicsPipeline",POSTFX_PIPELINE:"PostFXPipeline",UTILITY_PIPELINE:"UtilityPipeline"}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(40),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,l,u,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=l,v[10]=u,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,b=n*h-s*a,E=l*p-u*f,S=l*g-c*f,A=l*v-d*f,_=u*g-c*p,C=u*v-d*p,P=c*v-d*g,M=m*P-y*C+x*_+T*A-w*S+b*E;return M?(M=1/M,this.setValues((o*P-a*C+h*_)*M,(n*C-i*P-s*_)*M,(p*b-g*w+v*T)*M,(c*w-u*b-d*T)*M,(a*A-r*P-h*S)*M,(e*P-n*A+s*S)*M,(g*x-f*b-v*y)*M,(l*b-c*x+d*y)*M,(r*C-o*A+h*E)*M,(i*A-e*C-s*E)*M,(f*w-p*x+v*m)*M,(u*x-l*w-d*m)*M,(o*S-r*_-a*E)*M,(e*_-i*S+n*E)*M,(p*y-f*T-g*m)*M,(l*T-u*y+c*m)*M)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-u*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-u*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+u*(n*h-s*a)),-(r*(c*v-d*g)-l*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-l*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+l*(n*h-s*a),r*(u*v-d*p)-l*(o*v-h*p)+f*(o*d-h*u),-(e*(u*v-d*p)-l*(i*v-s*p)+f*(i*d-s*u)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*u)-r*(i*d-s*u)+l*(i*h-s*o)),-(r*(u*g-c*p)-l*(o*g-a*p)+f*(o*c-a*u)),e*(u*g-c*p)-l*(i*g-n*p)+f*(i*c-n*u),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*u)-r*(i*c-n*u)+l*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(u*v-d*p)+(e*h-s*r)*(u*g-c*p)+(i*a-n*o)*(l*v-d*f)-(i*h-s*o)*(l*g-c*f)+(n*h-s*a)*(l*p-u*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],l=e[7],u=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],b=y[3];return e[0]=x*i+T*o+w*u+b*p,e[1]=x*n+T*a+w*c+b*g,e[2]=x*s+T*h+w*d+b*v,e[3]=x*r+T*l+w*f+b*m,x=y[4],T=y[5],w=y[6],b=y[7],e[4]=x*i+T*o+w*u+b*p,e[5]=x*n+T*a+w*c+b*g,e[6]=x*s+T*h+w*d+b*v,e[7]=x*r+T*l+w*f+b*m,x=y[8],T=y[9],w=y[10],b=y[11],e[8]=x*i+T*o+w*u+b*p,e[9]=x*n+T*a+w*c+b*g,e[10]=x*s+T*h+w*d+b*v,e[11]=x*r+T*l+w*f+b*m,x=y[12],T=y[13],w=y[14],b=y[15],e[12]=x*i+T*o+w*u+b*p,e[13]=x*n+T*a+w*c+b*g,e[14]=x*s+T*h+w*d+b*v,e[15]=x*r+T*l+w*f+b*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],l=i[5],u=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],b=n[8],E=n[12],S=n[1],A=n[5],_=n[9],C=n[13],P=n[2],M=n[6],R=n[10],O=n[14],L=n[3],D=n[7],F=n[11],I=n[15];return this.setValues(s*T+r*S+o*P+a*L,h*T+l*S+u*P+c*L,d*T+f*S+p*P+g*L,v*T+m*S+y*P+x*L,s*w+r*A+o*M+a*D,h*w+l*A+u*M+c*D,d*w+f*A+p*M+g*D,v*w+m*A+y*M+x*D,s*b+r*_+o*R+a*F,h*b+l*_+u*R+c*F,d*b+f*_+p*R+g*F,v*b+m*_+y*R+x*F,s*E+r*C+o*O+a*I,h*E+l*C+u*O+c*I,d*E+f*C+p*O+g*I,v*E+m*C+y*O+x*I)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,l=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,l*o+i,l*a-n*r,0,h*a-n*o,l*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),l=1-h,u=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],b=i[12],E=i[13],S=i[14],A=i[15],_=n*n*l+h,C=s*n*l+r*a,P=r*n*l-s*a,M=n*s*l-r*a,R=s*s*l+h,O=r*s*l+n*a,L=n*r*l+s*a,D=s*r*l-n*a,F=r*r*l+h;return this.setValues(u*_+p*C+y*P,c*_+g*C+x*P,d*_+v*C+T*P,f*_+m*C+w*P,u*M+p*R+y*O,c*M+g*R+x*O,d*M+v*R+T*O,f*M+m*R+w*O,u*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,b,E,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],l=e[9],u=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+l*i,e[6]=o*n+u*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=l*n-r*i,e[10]=u*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],l=e[9],u=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-l*i,e[2]=o*n-u*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+l*n,e[10]=o*i+u*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],l=e[5],u=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+l*i,e[2]=o*n+u*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=l*n-r*i,e[6]=u*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,l=i*o,u=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),u+m,c-v,0,u-m,1-(l+p),f+g,0,c+v,f-g,1-(l+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,l=e*o,u=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),l+v,u-g,0,l-v,1-(h+f),d+p,0,u+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return u.subVectors(t,e),0===u.getLengthSquared()&&(u.z=1),u.normalize(),o.crossVectors(i,u),0===o.getLengthSquared()&&(1===Math.abs(i.z)?u.x+=1e-4:u.z+=1e-4,u.normalize(),o.crossVectors(i,u)),o.normalize(),a.crossVectors(u,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=u.x,n[9]=u.y,n[10]=u.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,l=e.x,u=e.y,c=e.z;if(Math.abs(n-l)<1e-6&&Math.abs(s-u)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-l,f=s-u,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),l.zero();var n=this.val,s=h.val,r=l.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(l),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),l.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(l),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],l=i[5],u=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],b=n[2],E=n[3],S=n[4],A=n[5],_=n[6],C=n[7],P=n[8],M=n[9],R=n[10],O=n[11],L=n[12],D=n[13],F=n[14],I=n[15];return e.setValues(T*s+w*h+b*d+E*v,w*r+w*l+b*f+E*m,b*o+w*u+b*p+E*y,E*a+w*c+b*g+E*x,S*s+A*h+_*d+C*v,S*r+A*l+_*f+C*m,S*o+A*u+_*p+C*y,S*a+A*c+_*g+C*x,P*s+M*h+R*d+O*v,P*r+M*l+R*f+O*m,P*o+M*u+R*p+O*y,P*a+M*c+R*g+O*x,L*s+D*h+F*d+I*v,L*r+D*l+F*f+I*m,L*o+D*u+F*p+I*y,L*a+D*c+F*g+I*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),l=Math.cos(t.y),u=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*l,m=a*l;return i||(u=l*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(l,p,g,0,0,a,o,0,h,v,m,0,u,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,l=new r,o=new s,a=new s,u=new s;t.exports=r},function(t,e,i){"use strict";function n(t,e,i){i=i||2;var n,s,r,o,a,h,l,u=e&&e.length,c=u?e[0]*i:t.length,d=g(t,0,c,i,!0),f=[];if(!d||d.next===d.prev)return f;if(u&&(d=function(t,e,i,n){var s,r,o,a,h,l=[];for(s=0,r=e.length;s=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=u&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==l;);return i}(t,e))&&(i=E(e,t),v(e,e.next),v(i,i.next))}}(l[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,u=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(l,u,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,l=h.next;else if((t=h)===l){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!u(s,r)&&c(s,n,n.next,r)&&b(s,r)&&b(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(b(t,e)&&b(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||u(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function l(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=u},function(t,e,i){var w={};t.exports=w;var o=i(34),b=i(42),a=i(101),h=i(43),l=i(164),u=i(22);w._warming=.4,w._torqueDampen=1,w._minLength=1e-6,w.create=function(t){var e=t;e.bodyA&&!e.pointA&&(e.pointA={x:0,y:0}),e.bodyB&&!e.pointB&&(e.pointB={x:0,y:0});var i=e.bodyA?b.add(e.bodyA.position,e.pointA):e.pointA,n=e.bodyB?b.add(e.bodyB.position,e.pointB):e.pointB,s=b.magnitude(b.sub(i,n));e.length=void 0!==e.length?e.length:s,e.id=e.id||u.nextId(),e.label=e.label||"Constraint",e.type="constraint",e.stiffness=e.stiffness||(0this.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){t.exports={POST_RENDER:i(650),PRE_RENDER:i(651),RENDER:i(652),RESIZE:i(653)}},function(t,e,i){var n=i(0),a=i(326),s=new n({initialize:function(t,e){this.parent=t,(this.events=e)||(this.events=t.events?t.events:t),this.list={},this.values={},this._frozen=!1,!t.hasOwnProperty("sys")&&this.events&&this.events.once(a.DESTROY,this.destroy,this)},get:function(t){var e=this.list;if(Array.isArray(t)){for(var i=[],n=0;n=o.sleepThreshold&&u.set(o,!0)):0u._motionWakeThreshold*i&&u.set(a,!1)))}},u.set=function(t,e){var i=t.isSleeping;e?(t.isSleeping=!0,t.sleepCounter=t.sleepThreshold,t.positionImpulse.x=0,t.positionImpulse.y=0,t.positionPrev.x=t.position.x,t.positionPrev.y=t.position.y,t.anglePrev=t.angle,t.speed=0,t.angularSpeed=0,t.motion=0,i||n.trigger(t,"sleepStart")):(t.isSleeping=!1,t.sleepCounter=0,i&&n.trigger(t,"sleepEnd"))}},function(t,e,i){var n={};t.exports=n;var u=i(22);n.on=function(t,e,i){for(var n,s=e.split(" "),r=0;rh||a.y>l)?(u=Math.max(a.x,e),c=Math.max(a.y,i),b=d=Math.min(a.r,h)-u,E=f=Math.min(a.b,l)-c,T=r?p+(v-(u-a.x)-d):p+(u-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=u,i=c,n=d,s=f):E=b=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+b)/A),t.v1=Math.min(1,(w+E)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=b,t.ch=E,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(216),n=i(0),r=i(1),o=i(84),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),u=i(40),s=new n({Extends:u,initialize:function(t,e,i,n,s,r,o,a,h,l){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l=0),u.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=l,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],l=s*a[1]+r*a[5]+o*a[9]+a[13],u=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-l/c*i,this.vz=n<=0?u/c:-u/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,l=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),l=Math.round(l)),this.tx=h,this.ty=l,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},function(t,e,i){t.exports={Bounce:i(1417),Collision:i(1418),Force:i(1419),Friction:i(1420),Gravity:i(1421),Mass:i(1422),Sensor:i(1423),SetBody:i(1424),Sleep:i(1425),Static:i(1442),Transform:i(1443),Velocity:i(1444)}},function(t,e){var l={};(t.exports=l).create=function(t,e){var i=t.bodyA,n=t.bodyB,s={id:l.id(i,n),bodyA:i,bodyB:n,activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:i.isSensor||n.isSensor,timeCreated:e,timeUpdated:e,collision:null,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return l.update(s,t,e),s},l.update=function(t,e,i){if((t.collision=e).collided){var n=e.supports,s=t.activeContacts,r=e.parentA,o=e.parentB;t.inverseMass=r.inverseMass+o.inverseMass,t.friction=Math.min(r.friction,o.friction),t.frictionStatic=Math.max(r.frictionStatic,o.frictionStatic),t.restitution=Math.max(r.restitution,o.restitution),t.slop=Math.max(r.slop,o.slop);for(var a=0;a=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},function(t,e,i){var n=i(0),s=i(11),r=i(37),o=i(9),a=i(38),h=i(10),l=i(26),u=i(195),A=i(3),c=new n({Extends:o,Mixins:[s.Alpha,s.Visible],initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=0),o.call(this),this.scene,this.sceneManager,this.scaleManager,this.cameraManager,this.id=0,this.name="",this.roundPixels=!1,this.useBounds=!1,this.worldView=new h,this.dirty=!0,this._x=t,this._y=e,this._width=i,this._height=n,this._bounds=new h,this._scrollX=0,this._scrollY=0,this._zoomX=1,this._zoomY=1,this._rotation=0,this.matrix=new l,this.transparent=!0,this.backgroundColor=u("rgba(0,0,0,0)"),this.disableCull=!1,this.culledObjects=[],this.midPoint=new A(i/2,n/2),this.originX=.5,this.originY=.5,this._customViewport=!1,this.mask=null,this._maskCamera=null},setOrigin:function(t,e){return void 0===t&&(t=.5),void 0===e&&(e=t),this.originX=t,this.originY=e,this},getScroll:function(t,e,i){void 0===i&&(i=new A);var n=.5*this.width,s=.5*this.height;return i.x=t-n,i.y=e-s,this.useBounds&&(i.x=this.clampX(i.x),i.y=this.clampY(i.y)),i},centerOnX:function(t){var e=.5*this.width;return this.midPoint.x=t,this.scrollX=t-e,this.useBounds&&(this.scrollX=this.clampX(this.scrollX)),this},centerOnY:function(t){var e=.5*this.height;return this.midPoint.y=t,this.scrollY=t-e,this.useBounds&&(this.scrollY=this.clampY(this.scrollY)),this},centerOn:function(t,e){return this.centerOnX(t),this.centerOnY(e),this},centerToBounds:function(){var t,e,i;return this.useBounds&&(t=this._bounds,e=.5*this.width,i=.5*this.height,this.midPoint.set(t.centerX,t.centerY),this.scrollX=t.centerX-e,this.scrollY=t.centerY-i),this},centerToSize:function(){return this.scrollX=.5*this.width,this.scrollY=.5*this.height,this},cull:function(t){if(this.disableCull)return t;var e=this.matrix.matrix,i=e[0],n=e[1],s=e[2],r=e[3];if(!(i*r-n*s))return t;for(var o=e[4],a=e[5],h=this.scrollX,l=this.scrollY,u=this.width,c=this.height,d=this.y,f=d+c,p=this.x,g=p+u,v=this.culledObjects,m=t.length,y=v.length=0;y=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(338),s=i(197),r=i(342),o=i(343);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(109);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(39),s=i(341);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(111),r=i(143),o=i(33),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var l,u,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(l=this.pipeline).manager.set(l),u=y.width,c=y.height,d=h.width/u,f=h.height/c,l.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},function(t,e,i){var o=i(55),c=i(28),d=i(22),f=i(2),s=i(34),n={parseBody:function(t,e,i,n){void 0===n&&(n={});for(var s=f(i,"fixtures",[]),r=[],o=0;o=n[2];if("^"===i.operator)return 0=i.number:0=n[2]:r[2]===n[2]}return t===e||"*"===t}},function(t,e,i){var n={};t.exports=n;var s=i(77),r=(i(88),i(22));n.create=function(t){var e=s.create(),i={label:"World",gravity:{x:0,y:1,scale:.001},bounds:{min:{x:-1/0,y:-1/0},max:{x:1/0,y:1/0}}};return r.extend(e,i,t)}},function(t,e,i){var y={};t.exports=y;var a=i(129),n=i(166),r=i(22);y.create=function(t){var e={controller:y,detector:n.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return r.extend(e,t)},y.update=function(t,e,i,n){for(var s,r,o,a=i.world,h=t.buckets,l=!1,u=i.metrics,c=u.broadphaseTests=0;ca.bounds.max.x||d.bounds.max.ya.bounds.max.y)){var f=y._getRegion(t,d);if(!d.region||f.id!==d.region.id||n){u.broadphaseTests+=1,d.region&&!n||(d.region=f);for(var p=y._regionUnion(f,d.region),g=p.startCol;g<=p.endCol;g++)for(s=p.startRow;s<=p.endRow;s++){r=h[o=y._getBucketId(g,s)];var v=g>=f.startCol&&g<=f.endCol&&s>=f.startRow&&s<=f.endRow,m=g>=d.region.startCol&&g<=d.region.endCol&&s>=d.region.startRow&&s<=d.region.endRow;!v&&m&&m&&r&&y._bucketRemoveBody(t,r,d),(d.region===f||v&&!m||n)&&(r=r||y._createBucket(h,o),y._bucketAddBody(t,r,d))}d.region=f,l=!0}}}l&&(t.pairsList=y._createActivePairsList(t))},y.clear=function(t){t.buckets={},t.pairs={},t.pairsList=[]},y._regionUnion=function(t,e){var i=Math.min(t.startCol,e.startCol),n=Math.max(t.endCol,e.endCol),s=Math.min(t.startRow,e.startRow),r=Math.max(t.endRow,e.endRow);return y._createRegion(i,n,s,r)},y._getRegion=function(t,e){var i=e.bounds,n=Math.floor(i.min.x/t.bucketWidth),s=Math.floor(i.max.x/t.bucketWidth),r=Math.floor(i.min.y/t.bucketHeight),o=Math.floor(i.max.y/t.bucketHeight);return y._createRegion(n,s,r,o)},y._createRegion=function(t,e,i,n){return{id:t+","+e+","+i+","+n,startCol:t,endCol:e,startRow:i,endRow:n}},y._getBucketId=function(t,e){return"C"+t+"R"+e},y._createBucket=function(t,e){return t[e]=[]},y._bucketAddBody=function(t,e,i){for(var n=0;nl._pairMaxIdleLife&&a.push(h);for(h=0;hu.friction*u.frictionStatic*O*i&&(D=P,L=X.clamp(u.friction*M*i,-D,D));var F,I,k=U.cross(w,p),B=U.cross(b,p),N=m/(d.inverseMass+f.inverseMass+d.inverseInertia*k*k+f.inverseInertia*B*B);R*=N,L*=N,_<0&&_*_>Y._restingThresh*i?x.normalImpulse=0:(F=x.normalImpulse,x.normalImpulse=Math.min(x.normalImpulse+R,0),R=x.normalImpulse-F),C*C>Y._restingThreshTangent*i?x.tangentImpulse=0:(I=x.tangentImpulse,x.tangentImpulse=X.clamp(x.tangentImpulse+L,-D,D),L=x.tangentImpulse-I),n.x=p.x*R+g.x*L,n.y=p.y*R+g.y*L,d.isStatic||d.isSleeping||(d.positionPrev.x+=n.x*d.inverseMass,d.positionPrev.y+=n.y*d.inverseMass,d.anglePrev+=U.cross(w,n)*d.inverseInertia),f.isStatic||f.isSleeping||(f.positionPrev.x-=n.x*f.inverseMass,f.positionPrev.y-=n.y*f.inverseMass,f.anglePrev-=U.cross(b,n)*f.inverseInertia)}}}}},function(t,e,i){t.exports={CalculateFacesAt:i(269),CalculateFacesWithin:i(66),CheckIsoBounds:i(564),Copy:i(1467),CreateFromTiles:i(1468),CullBounds:i(566),CullTiles:i(567),Fill:i(1469),FilterTiles:i(1470),FindByIndex:i(1471),FindTile:i(1472),ForEachTile:i(1473),GetCullTilesFunction:i(1474),GetTileAt:i(168),GetTileAtWorldXY:i(1475),GetTilesWithin:i(27),GetTilesWithinShape:i(1476),GetTilesWithinWorldXY:i(541),GetTileToWorldXFunction:i(1477),GetTileToWorldXYFunction:i(1478),GetTileToWorldYFunction:i(1479),GetWorldToTileXFunction:i(1480),GetWorldToTileXYFunction:i(1481),GetWorldToTileYFunction:i(1482),HasTileAt:i(585),HasTileAtWorldXY:i(1483),HexagonalCullBounds:i(569),HexagonalCullTiles:i(568),HexagonalTileToWorldXY:i(573),HexagonalTileToWorldY:i(577),HexagonalWorldToTileXY:i(579),HexagonalWorldToTileY:i(583),IsInLayerBounds:i(130),IsometricCullTiles:i(570),IsometricTileToWorldXY:i(574),IsometricWorldToTileXY:i(580),PutTileAt:i(274),PutTileAtWorldXY:i(1484),PutTilesAt:i(1485),Randomize:i(1486),RemoveTileAt:i(586),RemoveTileAtWorldXY:i(1487),RenderDebug:i(1488),ReplaceByIndex:i(565),RunCull:i(169),SetCollision:i(1489),SetCollisionBetween:i(1490),SetCollisionByExclusion:i(1491),SetCollisionByProperty:i(1492),SetCollisionFromCollisionGroup:i(1493),SetLayerCollisionIndex:i(170),SetTileCollision:i(78),SetTileIndexCallback:i(1494),SetTileLocationCallback:i(1495),Shuffle:i(1496),StaggeredCullBounds:i(572),StaggeredCullTiles:i(571),StaggeredTileToWorldXY:i(575),StaggeredTileToWorldY:i(578),StaggeredWorldToTileXY:i(581),StaggeredWorldToTileY:i(584),SwapByIndex:i(1497),TileToWorldX:i(270),TileToWorldXY:i(576),TileToWorldY:i(271),WeightedRandomize:i(1498),WorldToTileX:i(272),WorldToTileXY:i(582),WorldToTileY:i(273)}},function(t,e,i){var l=i(168);t.exports=function(t,e,i){var n=l(t,e,!0,i),s=l(t,e-1,!0,i),r=l(t,e+1,!0,i),o=l(t-1,e,!0,i),a=l(t+1,e,!0,i),h=n&&n.collides;return h&&(n.faceTop=!0,n.faceBottom=!0,n.faceLeft=!0,n.faceRight=!0),s&&s.collides&&(h&&(n.faceTop=!1),s.faceBottom=!h),r&&r.collides&&(h&&(n.faceBottom=!1),r.faceTop=!h),o&&o.collides&&(h&&(n.faceLeft=!1),o.faceRight=!h),a&&a.collides&&(h&&(n.faceRight=!1),a.faceLeft=!h),n&&!n.collides&&n.resetFaces(),n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileWidth,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.x+e.scrollX*(1-s.scrollFactorX),n*=s.scaleX),r+t*n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileHeight,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.y+e.scrollY*(1-s.scrollFactorY),n*=s.scaleY),r+t*n}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileWidth,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.x+i.scrollX*(1-r.scrollFactorX),s*=r.scaleX),e?Math.floor(t/s):t/s}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileHeight,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.y+i.scrollY*(1-r.scrollFactorY),s*=r.scaleY),e?Math.floor(t/s):t/s}},function(t,e,i){var u=i(89),c=i(130),d=i(269),f=i(78);t.exports=function(t,e,i,n,s){if(void 0===n&&(n=!0),!c(e,i,s))return null;var r,o=s.data[i][e],a=o&&o.collides;t instanceof u?(null===s.data[i][e]&&(s.data[i][e]=new u(s,t.index,e,i,s.tileWidth,s.tileHeight)),s.data[i][e].copy(t)):(r=t,null===s.data[i][e]?s.data[i][e]=new u(s,r,e,i,s.tileWidth,s.tileHeight):s.data[i][e].index=r);var h=s.data[i][e],l=-1!==s.collideIndexes.indexOf(h.index);return f(h,l),n&&a!==h.collides&&d(e,i,s),h}},function(t,e,i){var n=i(31);t.exports=function(t){return"isometric"===(t=t.toLowerCase())?n.ISOMETRIC:"staggered"===t?n.STAGGERED:"hexagonal"===t?n.HEXAGONAL:n.ORTHOGONAL}},function(t,e,i){var p=i(41),g=i(131),v=i(132),m=i(89);t.exports=function(t,e,i,n,s){for(var r=new g({tileWidth:i,tileHeight:n}),o=new v({name:t,tileWidth:i,tileHeight:n,format:p.ARRAY_2D,layers:[r]}),a=[],h=e.length,l=0,u=0;ut&&(t=s.totalDuration),s.delay=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),l=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(193),s=i(0),r=i(108),o=i(9),a=i(138),h=i(23),T=i(2),d=i(6),f=i(194),p=i(333),l=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1l.right&&(u=E(u,u+(d-l.right),this.lerp.x)),fl.bottom&&(c=E(c,c+(f-l.bottom),this.lerp.y))):(u=E(u,d-o,this.lerp.x),c=E(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(u=this.clampX(u),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),u=Math.round(u),c=Math.round(c));var g=(this.scrollX=u)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(b.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=u(i,0,1),n=u(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,l=t.y-r;return this.midPoint.set(h,l),this.scrollX=h-o,this.scrollY=l-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=l},function(t,e,i){var o=i(39);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,l=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(39);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(39);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(761),Flash:i(762),Pan:i(763),Shake:i(796),RotateTo:i(797),Zoom:i(798)}},function(t,e,i){t.exports={In:i(764),Out:i(765),InOut:i(766)}},function(t,e,i){t.exports={In:i(767),Out:i(768),InOut:i(769)}},function(t,e,i){t.exports={In:i(770),Out:i(771),InOut:i(772)}},function(t,e,i){t.exports={In:i(773),Out:i(774),InOut:i(775)}},function(t,e,i){t.exports={In:i(776),Out:i(777),InOut:i(778)}},function(t,e,i){t.exports={In:i(779),Out:i(780),InOut:i(781)}},function(t,e,i){t.exports=i(782)},function(t,e,i){t.exports={In:i(783),Out:i(784),InOut:i(785)}},function(t,e,i){t.exports={In:i(786),Out:i(787),InOut:i(788)}},function(t,e,i){t.exports={In:i(789),Out:i(790),InOut:i(791)}},function(t,e,i){t.exports={In:i(792),Out:i(793),InOut:i(794)}},function(t,e,i){t.exports=i(795)},function(t,e,i){var n=i(0),h=i(44),l=i(358),u=i(2),c=i(6),d=i(7),f=i(201),p=i(1),g=i(205),v=i(195),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",l.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=l.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=u(r,"global",[]),this.installScenePlugins=u(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(111),browser:i(143),features:i(199),input:i(829),audio:i(830),video:i(831),fullscreen:i(832),canvasFeatures:i(359)}},function(t,e,i){var n,s,r,o=i(33),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(378),l=a(33),u=a(44),c=a(199);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===u.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==u.HEADLESS)if(e.renderType===u.CANVAS||e.renderType!==u.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=u.CANVAS}else e.renderType=u.WEBGL;e.antialias||l.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=l.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==u.HEADLESS&&(i=a(379),n=a(382),e.renderType===u.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var d=i(38),u=i(380),n=i(0),s=i(44),r=i(9),f=i(94),o=i(381),a=i(110),h=i(112),l=i(26),c=new n({Extends:r,initialize:function(t){r.call(this);var e=t.config;this.config={clearBeforeRender:e.clearBeforeRender,backgroundColor:e.backgroundColor,antialias:e.antialias,roundPixels:e.roundPixels},this.game=t,this.type=s.CANVAS,this.drawCount=0,this.width=0,this.height=0,this.gameCanvas=t.canvas;var i={alpha:t.config.transparent,desynchronized:t.config.desynchronized};this.gameContext=e.context?e.context:this.gameCanvas.getContext("2d",i),this.currentContext=this.gameContext,this.antialias=t.config.antialias,this.blendModes=o(),this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92},this._tempMatrix1=new l,this._tempMatrix2=new l,this._tempMatrix3=new l,this.isBooted=!1,this.init()},init:function(){this.game.textures.once(h.READY,this.boot,this)},boot:function(){var t=this.game,e=t.scale.baseSize;this.width=e.width,this.height=e.height,this.isBooted=!0,t.scale.on(a.RESIZE,this.onResize,this),this.resize(e.width,e.height)},onResize:function(t,e){e.width===this.width&&e.height===this.height||this.resize(e.width,e.height)},resize:function(t,e){this.width=t,this.height=e,this.emit(f.RESIZE,t,e)},resetTransform:function(){this.currentContext.setTransform(1,0,0,1,0,0)},setBlendMode:function(t){return this.currentContext.globalCompositeOperation=t,this},setContext:function(t){return this.currentContext=t||this.gameContext,this},setAlpha:function(t){return this.currentContext.globalAlpha=t,this},preRender:function(){var t=this.gameContext,e=this.config,i=this.width,n=this.height;t.globalAlpha=1,t.globalCompositeOperation="source-over",t.setTransform(1,0,0,1,0,0),e.clearBeforeRender&&t.clearRect(0,0,i,n),e.transparent||(t.fillStyle=e.backgroundColor.rgba,t.fillRect(0,0,i,n)),t.save(),this.drawCount=0,this.emit(f.PRE_RENDER)},render:function(t,e,i){var n=e.length;this.emit(f.RENDER,t,i);var s=i.x,r=i.y,o=i.width,a=i.height,h=i.renderToTexture?i.context:t.sys.context;h.save(),this.game.scene.customViewports&&(h.beginPath(),h.rect(s,r,o,a),h.clip()),this.currentContext=h;var l=i.mask;l&&l.preRenderCanvas(this,null,i._maskCamera),i.transparent||(h.fillStyle=i.backgroundColor.rgba,h.fillRect(s,r,o,a)),h.globalAlpha=i.alpha,h.globalCompositeOperation="source-over",this.drawCount+=n,i.renderToTexture&&i.emit(d.PRE_RENDER,i),i.matrix.copyToContext(h);for(var u=0;ue.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(l.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(33),C=i(39),P=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=P(e,"callback"),s=P(e,"type","image/png"),r=P(e,"encoder",.92),o=P(e,"x",0),a=P(e,"y",0),h=P(e,"getPixel",!1),l=P(e,"isFramebuffer",!1),u=l?P(e,"bufferWidth",1):i.drawingBufferWidth,c=l?P(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=l?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=P(e,"width",u),g=P(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;wthis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(23);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(400),y=i(33),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),l=x(t,"postRender",null),u=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,u,c),a=o=!1),o&&(i.width=u,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,u,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],l=i[s>i.length-3?i.length-1:s+2];return e.set(u(r,o.x,a.x,h.x,l.x),u(r,o.y,a.y,h.y,l.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===u.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===u.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(18),s=i(0),r=i(81),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,l[a++]=(15&i)<<4|n>>2,l[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(153),s=i(0),r=i(74),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=t.context.createStereoPanner(),this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+l+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],u=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+u+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(144),r=i(85),o=i(2),a=i(71),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=u(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1123),r=i(73),o=i(10),a=i(35),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(u(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&l(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(60),s=i(17)(!1,s={Circle:i(1214),Ellipse:i(1224),Intersects:i(496),Line:i(1244),Mesh:i(1266),Point:i(1269),Polygon:i(1283),Rectangle:i(514),Triangle:i(1316)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(239),CircleToRectangle:i(158),GetCircleToCircle:i(1234),GetCircleToRectangle:i(1235),GetLineToCircle:i(240),GetLineToLine:i(497),GetLineToPoints:i(498),GetLineToPolygon:i(499),GetLineToRectangle:i(242),GetRaysFromPointToPolygon:i(1236),GetRectangleIntersection:i(1237),GetRectangleToRectangle:i(1238),GetRectangleToTriangle:i(1239),GetTriangleToCircle:i(1240),GetTriangleToLine:i(504),GetTriangleToTriangle:i(1241),LineToCircle:i(241),LineToLine:i(99),LineToRectangle:i(500),PointToLine:i(508),PointToLineSegment:i(1242),RectangleToRectangle:i(126),RectangleToTriangle:i(501),RectangleToValues:i(1243),TriangleToCircle:i(503),TriangleToLine:i(505),TriangleToTriangle:i(506)}},function(t,e,i){var g=i(40);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,l=r-n,u=o-s,c=e.x2-a,d=e.y2-h;if(0==l||0==d*l-c*u)return!1;var f=(l*(h-s)+u*(n-a))/(c*u-d*l),p=(a+c*f-n)/l;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(521),h=i(522),n=i(0),l=i(9),u=i(3),s=new n({Extends:l,initialize:function(t,e){l.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xu))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=P(t,e,s,this.OVERLAP_BIAS),p=M(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,u+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,l,u,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,l=t.body,u={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!l(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,l,u,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),l=n,u=s,p=f=d=c=void 0,c=Math.max(l.minX,u.minX),d=Math.max(l.minY,u.minY),f=Math.min(l.maxX,u.maxX),p=Math.min(l.maxY,u.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0i[e][0])&&(e=n);return!S(M(t,e-1),M(t,e),M(t,e+1))&&(function(t){for(var e=[],i=t.length,n=0;n!==i;n++)e.push(t.pop());for(n=0;n!==i;n++)t[n]=e[n]}(t),!0)}};var u=[],c=[];function P(t,e){var i=e[0]-t[0],n=e[1]-t[1];return i*i+n*n}function M(t,e){var i=t.length;return t[e<0?e%i+i:e%i]}function R(t,e,i,n){for(var s=i;sn.deltaMax?n.deltaMax:e)/n.delta,n.delta=e),0!==n.timeScalePrev&&(r*=s.timeScale/n.timeScalePrev),0===s.timeScale&&(r=0),n.timeScalePrev=s.timeScale,n.correction=r,n.frameCounter+=1,1e3<=t-n.counterTimestamp&&(n.fps=n.frameCounter*((t-n.counterTimestamp)/1e3),n.counterTimestamp=t,n.frameCounter=0),T.update(i,e,r))},step:function(t,e){T.update(this.engine,t,e)},update60Hz:function(){return 1e3/60},update30Hz:function(){return 1e3/30},has:function(t){var e=t.hasOwnProperty("body")?t.body:t;return null!==u.get(this.localWorld,e.id,e.type)},getAllBodies:function(){return u.allBodies(this.localWorld)},getAllConstraints:function(){return u.allConstraints(this.localWorld)},getAllComposites:function(){return u.allComposites(this.localWorld)},postUpdate:function(){var t,e,i,n;this.drawDebug&&(t=this.debugConfig,e=this.engine,i=this.debugGraphic,n=u.allBodies(this.localWorld),this.debugGraphic.clear(),t.showBroadphase&&e.broadphase.controller&&this.renderGrid(e.broadphase,i,t.broadphaseColor,.5),t.showBounds&&this.renderBodyBounds(n,i,t.boundsColor,.5),(t.showBody||t.showStaticBody)&&this.renderBodies(n),t.showJoint&&this.renderJoints(),(t.showAxes||t.showAngleIndicator)&&this.renderBodyAxes(n,i,t.showAxes,t.angleColor,.5),t.showVelocity&&this.renderBodyVelocity(n,i,t.velocityColor,1,2),t.showSeparations&&this.renderSeparations(e.pairs.list,i,t.separationColor),t.showCollisions&&this.renderCollisions(e.pairs.list,i,t.collisionColor))},renderGrid:function(t,e,i,n){e.lineStyle(1,i,n);for(var s=y.keys(t.buckets),r=0;rn.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=l(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(277),p=i(595),g=i(171);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],l=0;l=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(133),b=i(599),E=i(277);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=l(e,i),o.tilesets=u(e),o}},function(t,e,i){var d=i(131),f=i(89);t.exports=function(t,e){for(var i=[],n=0;n>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(337),BaseCamera:i(140),CameraManager:i(799),Effects:i(344),Events:i(38)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(18),s=i(0),l=i(38),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?l.FADE_OUT_START:l.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(u=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:uMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(144);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(144);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(362);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(13);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(399),Palettes:i(909)}},function(t,e,i){t.exports={ARNE16:i(400),C64:i(910),CGA:i(911),JMP:i(912),MSX:i(913)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(915),MoveTo:i(404),CubicBezier:i(401),Curve:i(97),Ellipse:i(402),Line:i(403),QuadraticBezier:i(405),Spline:i(406)}},function(t,e,i){var n=i(0),u=i(401),l=i(402),s=i(5),r=i(403),o=i(404),a=i(405),h=i(10),c=i(406),d=i(3),f=i(13),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),l=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new u(h,o,a,l))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(39),l=i(410);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=l(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=l(s,n,t),a=l(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(196);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:l(t,n,h),g:l(e,s,h),b:l(i,r,h)}}var l=i(142);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(203),s=i(39);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(409);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(321),GeometryMask:i(322)}},function(t,e,i){var n={AddToDOM:i(149),DOMContentLoaded:i(411),GetInnerHeight:i(412),GetScreenOrientation:i(413),GetTarget:i(418),ParseXML:i(419),RemoveFromDOM:i(210),RequestAnimationFrame:i(397)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(939)}},function(t,e,i){var n=i(0),s=i(9),r=i(25),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(149),s=i(332),r=i(336),o=i(33),a=i(0),h=i(357),l=i(941),u=i(377),c=i(95),d=i(395),f=i(358),p=i(411),g=i(9),v=i(23),m=i(420),y=i(25),x=i(425),T=i(426),w=i(428),b=i(112),E=i(433),S=i(396),A=i(398),_=i(437),C=i(446),P=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new E(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.facebook=new C(this),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),u(this),l(this),d(this),n(this.canvas,this.config.parent),this.textures.once(b.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=P},function(t,e,i){var n=i(149);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){var n={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"};n.facebook="facebook",t.exports=n},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var l=i(83);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),l(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var M=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=M(e,"chars","");if(""!==o){var a=M(e,"image",""),h=t.sys.textures.getFrame(a),l=h.cutX,u=h.cutY,c=h.source.width,d=h.source.height,f=M(e,"offset.x",0),p=M(e,"offset.y",0),g=M(e,"spacing.x",0),v=M(e,"spacing.y",0),m=M(e,"lineSpacing",0),y=M(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},b=0,E=0;E=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(198);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(126);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(37);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){l.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){l.revokeObjectURL(s.data),s.onProcessError()},l.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;re.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?n=e.min.y-t.max.y:t.max.y=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(450),List:i(117),Map:i(108),ProcessQueue:i(219),RTree:i(543),Set:i(156),Size:i(427)}},function(t,e,i){var n=i(17),s=i(1464),r=n(!1,r={CanvasTexture:i(434),Events:i(112),FilterMode:s,Frame:i(116),Parsers:i(436),Texture:i(214),TextureManager:i(433),TextureSource:i(435)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(17),s=i(1466),r=n(!1,r={Components:i(268),Parsers:i(1499),Formats:i(41),ImageCollection:i(599),ParseToTilemap:i(279),Tile:i(89),Tilemap:i(603),TilemapCreator:i(1505),TilemapFactory:i(1506),Tileset:i(133),TilemapLayer:i(604),Orientation:i(31),LayerData:i(131),MapData:i(132),ObjectLayer:i(595)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(31)};t.exports=n},function(t,e,i){var p=i(27),g=i(66);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),l=s-t,u=r-e,c=0;c=t&&l.index<=e&&u(l,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(78),h=i(66),l=i(170);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(82),DeepCopy:i(181),Extend:i(17),GetAdvancedValue:i(15),GetFastValue:i(2),GetMinMaxValue:i(1531),GetValue:i(6),HasAll:i(1532),HasAny:i(467),HasValue:i(122),IsPlainObject:i(7),Merge:i(115),MergeRight:i(1533),Pick:i(594),SetValue:i(490)}},function(t,e,i){var o=i(6),a=i(18);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;i=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=u},function(t,e,i){t.exports={Alpha:i(629),AlphaSingle:i(314),BlendMode:i(315),ComputedSize:i(630),Crop:i(631),Depth:i(316),Flip:i(632),GetBounds:i(633),Mask:i(320),Origin:i(654),PathFollower:i(655),Pipeline:i(136),ScrollFactor:i(323),Size:i(656),Texture:i(657),TextureCrop:i(658),Tint:i(659),ToJSON:i(182),Transform:i(324),TransformMatrix:i(26),Visible:i(325)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var l=[],u=e;ut.max.x&&(t.max.x=s.x),s.xt.max.y&&(t.max.y=s.y),s.y=t.min.x&&e.x<=t.max.x&&e.y>=t.min.y&&e.y<=t.max.y},i.overlaps=function(t,e){return t.min.x<=e.max.x&&t.max.x>=e.min.x&&t.max.y>=e.min.y&&t.min.y<=e.max.y},i.translate=function(t,e){t.min.x+=e.x,t.max.x+=e.x,t.min.y+=e.y,t.max.y+=e.y},i.shift=function(t,e){var i=t.max.x-t.min.x,n=t.max.y-t.min.y;t.min.x=e.x,t.max.x=e.x+i,t.min.y=e.y,t.max.y=e.y+n}},function(t,e,i){var n={VERSION:"3.50.1",BlendModes:i(36),ScaleModes:i(174),AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,FOREVER:-1,NONE:4,UP:5,DOWN:6,LEFT:7,RIGHT:8};t.exports=n},function(t,e){t.exports=function(t){return t.y+t.height-t.height*t.originY}},function(t,e){t.exports=function(t){return t.x-t.width*t.originX}},function(t,e){t.exports=function(t){return t.x+t.width-t.width*t.originX}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY}},function(t,e){t.exports=function(t,e,i,n,s,r){var o;void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=1);var a=0,h=t.length;if(1===r)for(o=s;othis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=l},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return Math.sqrt(s*s+r*r)}},function(t,e,i){t.exports={BOOT:i(942),DESTROY:i(943),DRAG_END:i(944),DRAG_ENTER:i(945),DRAG:i(946),DRAG_LEAVE:i(947),DRAG_OVER:i(948),DRAG_START:i(949),DROP:i(950),GAME_OUT:i(951),GAME_OVER:i(952),GAMEOBJECT_DOWN:i(953),GAMEOBJECT_DRAG_END:i(954),GAMEOBJECT_DRAG_ENTER:i(955),GAMEOBJECT_DRAG:i(956),GAMEOBJECT_DRAG_LEAVE:i(957),GAMEOBJECT_DRAG_OVER:i(958),GAMEOBJECT_DRAG_START:i(959),GAMEOBJECT_DROP:i(960),GAMEOBJECT_MOVE:i(961),GAMEOBJECT_OUT:i(962),GAMEOBJECT_OVER:i(963),GAMEOBJECT_POINTER_DOWN:i(964),GAMEOBJECT_POINTER_MOVE:i(965),GAMEOBJECT_POINTER_OUT:i(966),GAMEOBJECT_POINTER_OVER:i(967),GAMEOBJECT_POINTER_UP:i(968),GAMEOBJECT_POINTER_WHEEL:i(969),GAMEOBJECT_UP:i(970),GAMEOBJECT_WHEEL:i(971),MANAGER_BOOT:i(972),MANAGER_PROCESS:i(973),MANAGER_UPDATE:i(974),POINTER_DOWN:i(975),POINTER_DOWN_OUTSIDE:i(976),POINTER_MOVE:i(977),POINTER_OUT:i(978),POINTER_OVER:i(979),POINTER_UP:i(980),POINTER_UP_OUTSIDE:i(981),POINTER_WHEEL:i(982),POINTERLOCK_CHANGE:i(983),PRE_UPDATE:i(984),SHUTDOWN:i(985),START:i(986),UPDATE:i(987)}},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e,i){var n=i(0),y=i(181),s=i(9),v=i(385),x=i(2),m=i(72),T=i(94),w=i(148),b=i(12),E=i(386),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=u[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=u.length-1;0<=d;d--)u[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(21),l=i(24),s=i(8),u=i(2),c=i(6),d=i(7),r=new n({Extends:l,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=u(r=e,"key"),i=u(r,"url"),n=u(r,"xhrSettings"),o=u(r,"extension",o),s=u(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};l.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports={BITMAPMASK_PIPELINE:"BitmapMaskPipeline",LIGHT_PIPELINE:"Light2D",POINTLIGHT_PIPELINE:"PointLightPipeline",SINGLE_PIPELINE:"SinglePipeline",MULTI_PIPELINE:"MultiPipeline",ROPE_PIPELINE:"RopePipeline",GRAPHICS_PIPELINE:"GraphicsPipeline",POSTFX_PIPELINE:"PostFXPipeline",UTILITY_PIPELINE:"UtilityPipeline"}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(40),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,l,u,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=l,v[10]=u,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,b=n*h-s*a,E=l*p-u*f,S=l*g-c*f,A=l*v-d*f,_=u*g-c*p,C=u*v-d*p,P=c*v-d*g,M=m*P-y*C+x*_+T*A-w*S+b*E;return M?(M=1/M,this.setValues((o*P-a*C+h*_)*M,(n*C-i*P-s*_)*M,(p*b-g*w+v*T)*M,(c*w-u*b-d*T)*M,(a*A-r*P-h*S)*M,(e*P-n*A+s*S)*M,(g*x-f*b-v*y)*M,(l*b-c*x+d*y)*M,(r*C-o*A+h*E)*M,(i*A-e*C-s*E)*M,(f*w-p*x+v*m)*M,(u*x-l*w-d*m)*M,(o*S-r*_-a*E)*M,(e*_-i*S+n*E)*M,(p*y-f*T-g*m)*M,(l*T-u*y+c*m)*M)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-u*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-u*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+u*(n*h-s*a)),-(r*(c*v-d*g)-l*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-l*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+l*(n*h-s*a),r*(u*v-d*p)-l*(o*v-h*p)+f*(o*d-h*u),-(e*(u*v-d*p)-l*(i*v-s*p)+f*(i*d-s*u)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*u)-r*(i*d-s*u)+l*(i*h-s*o)),-(r*(u*g-c*p)-l*(o*g-a*p)+f*(o*c-a*u)),e*(u*g-c*p)-l*(i*g-n*p)+f*(i*c-n*u),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*u)-r*(i*c-n*u)+l*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(u*v-d*p)+(e*h-s*r)*(u*g-c*p)+(i*a-n*o)*(l*v-d*f)-(i*h-s*o)*(l*g-c*f)+(n*h-s*a)*(l*p-u*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],l=e[7],u=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],b=y[3];return e[0]=x*i+T*o+w*u+b*p,e[1]=x*n+T*a+w*c+b*g,e[2]=x*s+T*h+w*d+b*v,e[3]=x*r+T*l+w*f+b*m,x=y[4],T=y[5],w=y[6],b=y[7],e[4]=x*i+T*o+w*u+b*p,e[5]=x*n+T*a+w*c+b*g,e[6]=x*s+T*h+w*d+b*v,e[7]=x*r+T*l+w*f+b*m,x=y[8],T=y[9],w=y[10],b=y[11],e[8]=x*i+T*o+w*u+b*p,e[9]=x*n+T*a+w*c+b*g,e[10]=x*s+T*h+w*d+b*v,e[11]=x*r+T*l+w*f+b*m,x=y[12],T=y[13],w=y[14],b=y[15],e[12]=x*i+T*o+w*u+b*p,e[13]=x*n+T*a+w*c+b*g,e[14]=x*s+T*h+w*d+b*v,e[15]=x*r+T*l+w*f+b*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],l=i[5],u=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],b=n[8],E=n[12],S=n[1],A=n[5],_=n[9],C=n[13],P=n[2],M=n[6],R=n[10],O=n[14],L=n[3],D=n[7],F=n[11],I=n[15];return this.setValues(s*T+r*S+o*P+a*L,h*T+l*S+u*P+c*L,d*T+f*S+p*P+g*L,v*T+m*S+y*P+x*L,s*w+r*A+o*M+a*D,h*w+l*A+u*M+c*D,d*w+f*A+p*M+g*D,v*w+m*A+y*M+x*D,s*b+r*_+o*R+a*F,h*b+l*_+u*R+c*F,d*b+f*_+p*R+g*F,v*b+m*_+y*R+x*F,s*E+r*C+o*O+a*I,h*E+l*C+u*O+c*I,d*E+f*C+p*O+g*I,v*E+m*C+y*O+x*I)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,l=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,l*o+i,l*a-n*r,0,h*a-n*o,l*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),l=1-h,u=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],b=i[12],E=i[13],S=i[14],A=i[15],_=n*n*l+h,C=s*n*l+r*a,P=r*n*l-s*a,M=n*s*l-r*a,R=s*s*l+h,O=r*s*l+n*a,L=n*r*l+s*a,D=s*r*l-n*a,F=r*r*l+h;return this.setValues(u*_+p*C+y*P,c*_+g*C+x*P,d*_+v*C+T*P,f*_+m*C+w*P,u*M+p*R+y*O,c*M+g*R+x*O,d*M+v*R+T*O,f*M+m*R+w*O,u*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,b,E,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],l=e[9],u=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+l*i,e[6]=o*n+u*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=l*n-r*i,e[10]=u*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],l=e[9],u=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-l*i,e[2]=o*n-u*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+l*n,e[10]=o*i+u*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],l=e[5],u=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+l*i,e[2]=o*n+u*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=l*n-r*i,e[6]=u*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,l=i*o,u=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),u+m,c-v,0,u-m,1-(l+p),f+g,0,c+v,f-g,1-(l+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,l=e*o,u=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),l+v,u-g,0,l-v,1-(h+f),d+p,0,u+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return u.subVectors(t,e),0===u.getLengthSquared()&&(u.z=1),u.normalize(),o.crossVectors(i,u),0===o.getLengthSquared()&&(1===Math.abs(i.z)?u.x+=1e-4:u.z+=1e-4,u.normalize(),o.crossVectors(i,u)),o.normalize(),a.crossVectors(u,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=u.x,n[9]=u.y,n[10]=u.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,l=e.x,u=e.y,c=e.z;if(Math.abs(n-l)<1e-6&&Math.abs(s-u)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-l,f=s-u,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),l.zero();var n=this.val,s=h.val,r=l.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(l),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),l.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(l),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],l=i[5],u=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],b=n[2],E=n[3],S=n[4],A=n[5],_=n[6],C=n[7],P=n[8],M=n[9],R=n[10],O=n[11],L=n[12],D=n[13],F=n[14],I=n[15];return e.setValues(T*s+w*h+b*d+E*v,w*r+w*l+b*f+E*m,b*o+w*u+b*p+E*y,E*a+w*c+b*g+E*x,S*s+A*h+_*d+C*v,S*r+A*l+_*f+C*m,S*o+A*u+_*p+C*y,S*a+A*c+_*g+C*x,P*s+M*h+R*d+O*v,P*r+M*l+R*f+O*m,P*o+M*u+R*p+O*y,P*a+M*c+R*g+O*x,L*s+D*h+F*d+I*v,L*r+D*l+F*f+I*m,L*o+D*u+F*p+I*y,L*a+D*c+F*g+I*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),l=Math.cos(t.y),u=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*l,m=a*l;return i||(u=l*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(l,p,g,0,0,a,o,0,h,v,m,0,u,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,l=new r,o=new s,a=new s,u=new s;t.exports=r},function(t,e,i){"use strict";function n(t,e,i){i=i||2;var n,s,r,o,a,h,l,u=e&&e.length,c=u?e[0]*i:t.length,d=g(t,0,c,i,!0),f=[];if(!d||d.next===d.prev)return f;if(u&&(d=function(t,e,i,n){var s,r,o,a,h,l=[];for(s=0,r=e.length;s=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=u&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==l;);return i}(t,e))&&(i=E(e,t),v(e,e.next),v(i,i.next))}}(l[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,u=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(l,u,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,l=h.next;else if((t=h)===l){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!u(s,r)&&c(s,n,n.next,r)&&b(s,r)&&b(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(b(t,e)&&b(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||u(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function l(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=u},function(t,e,i){var w={};t.exports=w;var o=i(34),b=i(42),a=i(101),h=i(43),l=i(164),u=i(22);w._warming=.4,w._torqueDampen=1,w._minLength=1e-6,w.create=function(t){var e=t;e.bodyA&&!e.pointA&&(e.pointA={x:0,y:0}),e.bodyB&&!e.pointB&&(e.pointB={x:0,y:0});var i=e.bodyA?b.add(e.bodyA.position,e.pointA):e.pointA,n=e.bodyB?b.add(e.bodyB.position,e.pointB):e.pointB,s=b.magnitude(b.sub(i,n));e.length=void 0!==e.length?e.length:s,e.id=e.id||u.nextId(),e.label=e.label||"Constraint",e.type="constraint",e.stiffness=e.stiffness||(0this.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){t.exports={POST_RENDER:i(650),PRE_RENDER:i(651),RENDER:i(652),RESIZE:i(653)}},function(t,e,i){var n=i(0),a=i(326),s=new n({initialize:function(t,e){this.parent=t,(this.events=e)||(this.events=t.events?t.events:t),this.list={},this.values={},this._frozen=!1,!t.hasOwnProperty("sys")&&this.events&&this.events.once(a.DESTROY,this.destroy,this)},get:function(t){var e=this.list;if(Array.isArray(t)){for(var i=[],n=0;n=o.sleepThreshold&&u.set(o,!0)):0u._motionWakeThreshold*i&&u.set(a,!1)))}},u.set=function(t,e){var i=t.isSleeping;e?(t.isSleeping=!0,t.sleepCounter=t.sleepThreshold,t.positionImpulse.x=0,t.positionImpulse.y=0,t.positionPrev.x=t.position.x,t.positionPrev.y=t.position.y,t.anglePrev=t.angle,t.speed=0,t.angularSpeed=0,t.motion=0,i||n.trigger(t,"sleepStart")):(t.isSleeping=!1,t.sleepCounter=0,i&&n.trigger(t,"sleepEnd"))}},function(t,e,i){var n={};t.exports=n;var u=i(22);n.on=function(t,e,i){for(var n,s=e.split(" "),r=0;rh||a.y>l)?(u=Math.max(a.x,e),c=Math.max(a.y,i),b=d=Math.min(a.r,h)-u,E=f=Math.min(a.b,l)-c,T=r?p+(v-(u-a.x)-d):p+(u-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=u,i=c,n=d,s=f):E=b=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+b)/A),t.v1=Math.min(1,(w+E)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=b,t.ch=E,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(216),n=i(0),r=i(1),o=i(84),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),u=i(40),s=new n({Extends:u,initialize:function(t,e,i,n,s,r,o,a,h,l){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l=0),u.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=l,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],l=s*a[1]+r*a[5]+o*a[9]+a[13],u=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-l/c*i,this.vz=n<=0?u/c:-u/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,l=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),l=Math.round(l)),this.tx=h,this.ty=l,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},function(t,e,i){t.exports={Bounce:i(1417),Collision:i(1418),Force:i(1419),Friction:i(1420),Gravity:i(1421),Mass:i(1422),Sensor:i(1423),SetBody:i(1424),Sleep:i(1425),Static:i(1442),Transform:i(1443),Velocity:i(1444)}},function(t,e){var l={};(t.exports=l).create=function(t,e){var i=t.bodyA,n=t.bodyB,s={id:l.id(i,n),bodyA:i,bodyB:n,activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:i.isSensor||n.isSensor,timeCreated:e,timeUpdated:e,collision:null,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return l.update(s,t,e),s},l.update=function(t,e,i){if((t.collision=e).collided){var n=e.supports,s=t.activeContacts,r=e.parentA,o=e.parentB;t.inverseMass=r.inverseMass+o.inverseMass,t.friction=Math.min(r.friction,o.friction),t.frictionStatic=Math.max(r.frictionStatic,o.frictionStatic),t.restitution=Math.max(r.restitution,o.restitution),t.slop=Math.max(r.slop,o.slop);for(var a=0;a=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},function(t,e,i){var n=i(0),s=i(11),r=i(37),o=i(9),a=i(38),h=i(10),l=i(26),u=i(195),A=i(3),c=new n({Extends:o,Mixins:[s.Alpha,s.Visible],initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=0),o.call(this),this.scene,this.sceneManager,this.scaleManager,this.cameraManager,this.id=0,this.name="",this.roundPixels=!1,this.useBounds=!1,this.worldView=new h,this.dirty=!0,this._x=t,this._y=e,this._width=i,this._height=n,this._bounds=new h,this._scrollX=0,this._scrollY=0,this._zoomX=1,this._zoomY=1,this._rotation=0,this.matrix=new l,this.transparent=!0,this.backgroundColor=u("rgba(0,0,0,0)"),this.disableCull=!1,this.culledObjects=[],this.midPoint=new A(i/2,n/2),this.originX=.5,this.originY=.5,this._customViewport=!1,this.mask=null,this._maskCamera=null},setOrigin:function(t,e){return void 0===t&&(t=.5),void 0===e&&(e=t),this.originX=t,this.originY=e,this},getScroll:function(t,e,i){void 0===i&&(i=new A);var n=.5*this.width,s=.5*this.height;return i.x=t-n,i.y=e-s,this.useBounds&&(i.x=this.clampX(i.x),i.y=this.clampY(i.y)),i},centerOnX:function(t){var e=.5*this.width;return this.midPoint.x=t,this.scrollX=t-e,this.useBounds&&(this.scrollX=this.clampX(this.scrollX)),this},centerOnY:function(t){var e=.5*this.height;return this.midPoint.y=t,this.scrollY=t-e,this.useBounds&&(this.scrollY=this.clampY(this.scrollY)),this},centerOn:function(t,e){return this.centerOnX(t),this.centerOnY(e),this},centerToBounds:function(){var t,e,i;return this.useBounds&&(t=this._bounds,e=.5*this.width,i=.5*this.height,this.midPoint.set(t.centerX,t.centerY),this.scrollX=t.centerX-e,this.scrollY=t.centerY-i),this},centerToSize:function(){return this.scrollX=.5*this.width,this.scrollY=.5*this.height,this},cull:function(t){if(this.disableCull)return t;var e=this.matrix.matrix,i=e[0],n=e[1],s=e[2],r=e[3];if(!(i*r-n*s))return t;for(var o=e[4],a=e[5],h=this.scrollX,l=this.scrollY,u=this.width,c=this.height,d=this.y,f=d+c,p=this.x,g=p+u,v=this.culledObjects,m=t.length,y=v.length=0;y=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(338),s=i(197),r=i(342),o=i(343);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(109);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(39),s=i(341);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(111),r=i(143),o=i(33),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var l,u,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(l=this.pipeline).manager.set(l),u=y.width,c=y.height,d=h.width/u,f=h.height/c,l.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},function(t,e,i){var o=i(55),c=i(28),d=i(22),f=i(2),s=i(34),n={parseBody:function(t,e,i,n){void 0===n&&(n={});for(var s=f(i,"fixtures",[]),r=[],o=0;o=n[2];if("^"===i.operator)return 0=i.number:0=n[2]:r[2]===n[2]}return t===e||"*"===t}},function(t,e,i){var n={};t.exports=n;var s=i(77),r=(i(88),i(22));n.create=function(t){var e=s.create(),i={label:"World",gravity:{x:0,y:1,scale:.001},bounds:{min:{x:-1/0,y:-1/0},max:{x:1/0,y:1/0}}};return r.extend(e,i,t)}},function(t,e,i){var y={};t.exports=y;var a=i(129),n=i(166),r=i(22);y.create=function(t){var e={controller:y,detector:n.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return r.extend(e,t)},y.update=function(t,e,i,n){for(var s,r,o,a=i.world,h=t.buckets,l=!1,u=i.metrics,c=u.broadphaseTests=0;ca.bounds.max.x||d.bounds.max.ya.bounds.max.y)){var f=y._getRegion(t,d);if(!d.region||f.id!==d.region.id||n){u.broadphaseTests+=1,d.region&&!n||(d.region=f);for(var p=y._regionUnion(f,d.region),g=p.startCol;g<=p.endCol;g++)for(s=p.startRow;s<=p.endRow;s++){r=h[o=y._getBucketId(g,s)];var v=g>=f.startCol&&g<=f.endCol&&s>=f.startRow&&s<=f.endRow,m=g>=d.region.startCol&&g<=d.region.endCol&&s>=d.region.startRow&&s<=d.region.endRow;!v&&m&&m&&r&&y._bucketRemoveBody(t,r,d),(d.region===f||v&&!m||n)&&(r=r||y._createBucket(h,o),y._bucketAddBody(t,r,d))}d.region=f,l=!0}}}l&&(t.pairsList=y._createActivePairsList(t))},y.clear=function(t){t.buckets={},t.pairs={},t.pairsList=[]},y._regionUnion=function(t,e){var i=Math.min(t.startCol,e.startCol),n=Math.max(t.endCol,e.endCol),s=Math.min(t.startRow,e.startRow),r=Math.max(t.endRow,e.endRow);return y._createRegion(i,n,s,r)},y._getRegion=function(t,e){var i=e.bounds,n=Math.floor(i.min.x/t.bucketWidth),s=Math.floor(i.max.x/t.bucketWidth),r=Math.floor(i.min.y/t.bucketHeight),o=Math.floor(i.max.y/t.bucketHeight);return y._createRegion(n,s,r,o)},y._createRegion=function(t,e,i,n){return{id:t+","+e+","+i+","+n,startCol:t,endCol:e,startRow:i,endRow:n}},y._getBucketId=function(t,e){return"C"+t+"R"+e},y._createBucket=function(t,e){return t[e]=[]},y._bucketAddBody=function(t,e,i){for(var n=0;nl._pairMaxIdleLife&&a.push(h);for(h=0;hu.friction*u.frictionStatic*O*i&&(D=P,L=X.clamp(u.friction*M*i,-D,D));var F,I,k=U.cross(w,p),B=U.cross(b,p),N=m/(d.inverseMass+f.inverseMass+d.inverseInertia*k*k+f.inverseInertia*B*B);R*=N,L*=N,_<0&&_*_>Y._restingThresh*i?x.normalImpulse=0:(F=x.normalImpulse,x.normalImpulse=Math.min(x.normalImpulse+R,0),R=x.normalImpulse-F),C*C>Y._restingThreshTangent*i?x.tangentImpulse=0:(I=x.tangentImpulse,x.tangentImpulse=X.clamp(x.tangentImpulse+L,-D,D),L=x.tangentImpulse-I),n.x=p.x*R+g.x*L,n.y=p.y*R+g.y*L,d.isStatic||d.isSleeping||(d.positionPrev.x+=n.x*d.inverseMass,d.positionPrev.y+=n.y*d.inverseMass,d.anglePrev+=U.cross(w,n)*d.inverseInertia),f.isStatic||f.isSleeping||(f.positionPrev.x-=n.x*f.inverseMass,f.positionPrev.y-=n.y*f.inverseMass,f.anglePrev-=U.cross(b,n)*f.inverseInertia)}}}}},function(t,e,i){t.exports={CalculateFacesAt:i(269),CalculateFacesWithin:i(66),CheckIsoBounds:i(564),Copy:i(1467),CreateFromTiles:i(1468),CullBounds:i(566),CullTiles:i(567),Fill:i(1469),FilterTiles:i(1470),FindByIndex:i(1471),FindTile:i(1472),ForEachTile:i(1473),GetCullTilesFunction:i(1474),GetTileAt:i(168),GetTileAtWorldXY:i(1475),GetTilesWithin:i(27),GetTilesWithinShape:i(1476),GetTilesWithinWorldXY:i(541),GetTileToWorldXFunction:i(1477),GetTileToWorldXYFunction:i(1478),GetTileToWorldYFunction:i(1479),GetWorldToTileXFunction:i(1480),GetWorldToTileXYFunction:i(1481),GetWorldToTileYFunction:i(1482),HasTileAt:i(585),HasTileAtWorldXY:i(1483),HexagonalCullBounds:i(569),HexagonalCullTiles:i(568),HexagonalTileToWorldXY:i(573),HexagonalTileToWorldY:i(577),HexagonalWorldToTileXY:i(579),HexagonalWorldToTileY:i(583),IsInLayerBounds:i(130),IsometricCullTiles:i(570),IsometricTileToWorldXY:i(574),IsometricWorldToTileXY:i(580),PutTileAt:i(274),PutTileAtWorldXY:i(1484),PutTilesAt:i(1485),Randomize:i(1486),RemoveTileAt:i(586),RemoveTileAtWorldXY:i(1487),RenderDebug:i(1488),ReplaceByIndex:i(565),RunCull:i(169),SetCollision:i(1489),SetCollisionBetween:i(1490),SetCollisionByExclusion:i(1491),SetCollisionByProperty:i(1492),SetCollisionFromCollisionGroup:i(1493),SetLayerCollisionIndex:i(170),SetTileCollision:i(78),SetTileIndexCallback:i(1494),SetTileLocationCallback:i(1495),Shuffle:i(1496),StaggeredCullBounds:i(572),StaggeredCullTiles:i(571),StaggeredTileToWorldXY:i(575),StaggeredTileToWorldY:i(578),StaggeredWorldToTileXY:i(581),StaggeredWorldToTileY:i(584),SwapByIndex:i(1497),TileToWorldX:i(270),TileToWorldXY:i(576),TileToWorldY:i(271),WeightedRandomize:i(1498),WorldToTileX:i(272),WorldToTileXY:i(582),WorldToTileY:i(273)}},function(t,e,i){var l=i(168);t.exports=function(t,e,i){var n=l(t,e,!0,i),s=l(t,e-1,!0,i),r=l(t,e+1,!0,i),o=l(t-1,e,!0,i),a=l(t+1,e,!0,i),h=n&&n.collides;return h&&(n.faceTop=!0,n.faceBottom=!0,n.faceLeft=!0,n.faceRight=!0),s&&s.collides&&(h&&(n.faceTop=!1),s.faceBottom=!h),r&&r.collides&&(h&&(n.faceBottom=!1),r.faceTop=!h),o&&o.collides&&(h&&(n.faceLeft=!1),o.faceRight=!h),a&&a.collides&&(h&&(n.faceRight=!1),a.faceLeft=!h),n&&!n.collides&&n.resetFaces(),n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileWidth,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.x+e.scrollX*(1-s.scrollFactorX),n*=s.scaleX),r+t*n}},function(t,e){t.exports=function(t,e,i){var n=i.baseTileHeight,s=i.tilemapLayer,r=0;return s&&(e=e||s.scene.cameras.main,r=s.y+e.scrollY*(1-s.scrollFactorY),n*=s.scaleY),r+t*n}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileWidth,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.x+i.scrollX*(1-r.scrollFactorX),s*=r.scaleX),e?Math.floor(t/s):t/s}},function(t,e){t.exports=function(t,e,i,n){void 0===e&&(e=!0);var s=n.baseTileHeight,r=n.tilemapLayer;return r&&(i=i||r.scene.cameras.main,t-=r.y+i.scrollY*(1-r.scrollFactorY),s*=r.scaleY),e?Math.floor(t/s):t/s}},function(t,e,i){var u=i(89),c=i(130),d=i(269),f=i(78);t.exports=function(t,e,i,n,s){if(void 0===n&&(n=!0),!c(e,i,s))return null;var r,o=s.data[i][e],a=o&&o.collides;t instanceof u?(null===s.data[i][e]&&(s.data[i][e]=new u(s,t.index,e,i,s.tileWidth,s.tileHeight)),s.data[i][e].copy(t)):(r=t,null===s.data[i][e]?s.data[i][e]=new u(s,r,e,i,s.tileWidth,s.tileHeight):s.data[i][e].index=r);var h=s.data[i][e],l=-1!==s.collideIndexes.indexOf(h.index);return f(h,l),n&&a!==h.collides&&d(e,i,s),h}},function(t,e,i){var n=i(31);t.exports=function(t){return"isometric"===(t=t.toLowerCase())?n.ISOMETRIC:"staggered"===t?n.STAGGERED:"hexagonal"===t?n.HEXAGONAL:n.ORTHOGONAL}},function(t,e,i){var p=i(41),g=i(131),v=i(132),m=i(89);t.exports=function(t,e,i,n,s){for(var r=new g({tileWidth:i,tileHeight:n}),o=new v({name:t,tileWidth:i,tileHeight:n,format:p.ARRAY_2D,layers:[r]}),a=[],h=e.length,l=0,u=0;ut&&(t=s.totalDuration),s.delay=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),l=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(193),s=i(0),r=i(108),o=i(9),a=i(138),h=i(23),T=i(2),d=i(6),f=i(194),p=i(333),l=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1l.right&&(u=E(u,u+(d-l.right),this.lerp.x)),fl.bottom&&(c=E(c,c+(f-l.bottom),this.lerp.y))):(u=E(u,d-o,this.lerp.x),c=E(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(u=this.clampX(u),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),u=Math.round(u),c=Math.round(c));var g=(this.scrollX=u)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(b.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=u(i,0,1),n=u(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,l=t.y-r;return this.midPoint.set(h,l),this.scrollX=h-o,this.scrollY=l-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=l},function(t,e,i){var o=i(39);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,l=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(39);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(39);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(761),Flash:i(762),Pan:i(763),Shake:i(796),RotateTo:i(797),Zoom:i(798)}},function(t,e,i){t.exports={In:i(764),Out:i(765),InOut:i(766)}},function(t,e,i){t.exports={In:i(767),Out:i(768),InOut:i(769)}},function(t,e,i){t.exports={In:i(770),Out:i(771),InOut:i(772)}},function(t,e,i){t.exports={In:i(773),Out:i(774),InOut:i(775)}},function(t,e,i){t.exports={In:i(776),Out:i(777),InOut:i(778)}},function(t,e,i){t.exports={In:i(779),Out:i(780),InOut:i(781)}},function(t,e,i){t.exports=i(782)},function(t,e,i){t.exports={In:i(783),Out:i(784),InOut:i(785)}},function(t,e,i){t.exports={In:i(786),Out:i(787),InOut:i(788)}},function(t,e,i){t.exports={In:i(789),Out:i(790),InOut:i(791)}},function(t,e,i){t.exports={In:i(792),Out:i(793),InOut:i(794)}},function(t,e,i){t.exports=i(795)},function(t,e,i){var n=i(0),h=i(44),l=i(358),u=i(2),c=i(6),d=i(7),f=i(201),p=i(1),g=i(205),v=i(195),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",l.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=l.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=u(r,"global",[]),this.installScenePlugins=u(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(111),browser:i(143),features:i(199),input:i(829),audio:i(830),video:i(831),fullscreen:i(832),canvasFeatures:i(359)}},function(t,e,i){var n,s,r,o=i(33),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(378),l=a(33),u=a(44),c=a(199);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===u.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==u.HEADLESS)if(e.renderType===u.CANVAS||e.renderType!==u.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=u.CANVAS}else e.renderType=u.WEBGL;e.antialias||l.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=l.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==u.HEADLESS&&(i=a(379),n=a(382),e.renderType===u.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var d=i(38),u=i(380),n=i(0),s=i(44),r=i(9),f=i(94),o=i(381),a=i(110),h=i(112),l=i(26),c=new n({Extends:r,initialize:function(t){r.call(this);var e=t.config;this.config={clearBeforeRender:e.clearBeforeRender,backgroundColor:e.backgroundColor,antialias:e.antialias,roundPixels:e.roundPixels},this.game=t,this.type=s.CANVAS,this.drawCount=0,this.width=0,this.height=0,this.gameCanvas=t.canvas;var i={alpha:t.config.transparent,desynchronized:t.config.desynchronized};this.gameContext=e.context?e.context:this.gameCanvas.getContext("2d",i),this.currentContext=this.gameContext,this.antialias=t.config.antialias,this.blendModes=o(),this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92},this._tempMatrix1=new l,this._tempMatrix2=new l,this._tempMatrix3=new l,this.isBooted=!1,this.init()},init:function(){this.game.textures.once(h.READY,this.boot,this)},boot:function(){var t=this.game,e=t.scale.baseSize;this.width=e.width,this.height=e.height,this.isBooted=!0,t.scale.on(a.RESIZE,this.onResize,this),this.resize(e.width,e.height)},onResize:function(t,e){e.width===this.width&&e.height===this.height||this.resize(e.width,e.height)},resize:function(t,e){this.width=t,this.height=e,this.emit(f.RESIZE,t,e)},resetTransform:function(){this.currentContext.setTransform(1,0,0,1,0,0)},setBlendMode:function(t){return this.currentContext.globalCompositeOperation=t,this},setContext:function(t){return this.currentContext=t||this.gameContext,this},setAlpha:function(t){return this.currentContext.globalAlpha=t,this},preRender:function(){var t=this.gameContext,e=this.config,i=this.width,n=this.height;t.globalAlpha=1,t.globalCompositeOperation="source-over",t.setTransform(1,0,0,1,0,0),e.clearBeforeRender&&t.clearRect(0,0,i,n),e.transparent||(t.fillStyle=e.backgroundColor.rgba,t.fillRect(0,0,i,n)),t.save(),this.drawCount=0,this.emit(f.PRE_RENDER)},render:function(t,e,i){var n=e.length;this.emit(f.RENDER,t,i);var s=i.x,r=i.y,o=i.width,a=i.height,h=i.renderToTexture?i.context:t.sys.context;h.save(),this.game.scene.customViewports&&(h.beginPath(),h.rect(s,r,o,a),h.clip()),this.currentContext=h;var l=i.mask;l&&l.preRenderCanvas(this,null,i._maskCamera),i.transparent||(h.fillStyle=i.backgroundColor.rgba,h.fillRect(s,r,o,a)),h.globalAlpha=i.alpha,h.globalCompositeOperation="source-over",this.drawCount+=n,i.renderToTexture&&i.emit(d.PRE_RENDER,i),i.matrix.copyToContext(h);for(var u=0;ue.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(l.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(33),C=i(39),P=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=P(e,"callback"),s=P(e,"type","image/png"),r=P(e,"encoder",.92),o=P(e,"x",0),a=P(e,"y",0),h=P(e,"getPixel",!1),l=P(e,"isFramebuffer",!1),u=l?P(e,"bufferWidth",1):i.drawingBufferWidth,c=l?P(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=l?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=P(e,"width",u),g=P(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;wthis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(23);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(400),y=i(33),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),l=x(t,"postRender",null),u=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,u,c),a=o=!1),o&&(i.width=u,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,u,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],l=i[s>i.length-3?i.length-1:s+2];return e.set(u(r,o.x,a.x,h.x,l.x),u(r,o.y,a.y,h.y,l.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===u.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===u.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(18),s=i(0),r=i(81),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,l[a++]=(15&i)<<4|n>>2,l[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(153),s=i(0),r=i(74),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=null,this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),t.context.createStereoPanner?(this.pannerNode=t.context.createStereoPanner(),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination)):this.volumeNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+l+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],u=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+u+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(144),r=i(85),o=i(2),a=i(71),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=u(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1123),r=i(73),o=i(10),a=i(35),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(u(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&l(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(60),s=i(17)(!1,s={Circle:i(1214),Ellipse:i(1224),Intersects:i(496),Line:i(1244),Mesh:i(1266),Point:i(1269),Polygon:i(1283),Rectangle:i(514),Triangle:i(1316)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(239),CircleToRectangle:i(158),GetCircleToCircle:i(1234),GetCircleToRectangle:i(1235),GetLineToCircle:i(240),GetLineToLine:i(497),GetLineToPoints:i(498),GetLineToPolygon:i(499),GetLineToRectangle:i(242),GetRaysFromPointToPolygon:i(1236),GetRectangleIntersection:i(1237),GetRectangleToRectangle:i(1238),GetRectangleToTriangle:i(1239),GetTriangleToCircle:i(1240),GetTriangleToLine:i(504),GetTriangleToTriangle:i(1241),LineToCircle:i(241),LineToLine:i(99),LineToRectangle:i(500),PointToLine:i(508),PointToLineSegment:i(1242),RectangleToRectangle:i(126),RectangleToTriangle:i(501),RectangleToValues:i(1243),TriangleToCircle:i(503),TriangleToLine:i(505),TriangleToTriangle:i(506)}},function(t,e,i){var g=i(40);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,l=r-n,u=o-s,c=e.x2-a,d=e.y2-h;if(0==l||0==d*l-c*u)return!1;var f=(l*(h-s)+u*(n-a))/(c*u-d*l),p=(a+c*f-n)/l;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(521),h=i(522),n=i(0),l=i(9),u=i(3),s=new n({Extends:l,initialize:function(t,e){l.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xu))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=P(t,e,s,this.OVERLAP_BIAS),p=M(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,u+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,l,u,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,l=t.body,u={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!l(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,l,u,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),l=n,u=s,p=f=d=c=void 0,c=Math.max(l.minX,u.minX),d=Math.max(l.minY,u.minY),f=Math.min(l.maxX,u.maxX),p=Math.min(l.maxY,u.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0i[e][0])&&(e=n);return!S(M(t,e-1),M(t,e),M(t,e+1))&&(function(t){for(var e=[],i=t.length,n=0;n!==i;n++)e.push(t.pop());for(n=0;n!==i;n++)t[n]=e[n]}(t),!0)}};var u=[],c=[];function P(t,e){var i=e[0]-t[0],n=e[1]-t[1];return i*i+n*n}function M(t,e){var i=t.length;return t[e<0?e%i+i:e%i]}function R(t,e,i,n){for(var s=i;sn.deltaMax?n.deltaMax:e)/n.delta,n.delta=e),0!==n.timeScalePrev&&(r*=s.timeScale/n.timeScalePrev),0===s.timeScale&&(r=0),n.timeScalePrev=s.timeScale,n.correction=r,n.frameCounter+=1,1e3<=t-n.counterTimestamp&&(n.fps=n.frameCounter*((t-n.counterTimestamp)/1e3),n.counterTimestamp=t,n.frameCounter=0),T.update(i,e,r))},step:function(t,e){T.update(this.engine,t,e)},update60Hz:function(){return 1e3/60},update30Hz:function(){return 1e3/30},has:function(t){var e=t.hasOwnProperty("body")?t.body:t;return null!==u.get(this.localWorld,e.id,e.type)},getAllBodies:function(){return u.allBodies(this.localWorld)},getAllConstraints:function(){return u.allConstraints(this.localWorld)},getAllComposites:function(){return u.allComposites(this.localWorld)},postUpdate:function(){var t,e,i,n;this.drawDebug&&(t=this.debugConfig,e=this.engine,i=this.debugGraphic,n=u.allBodies(this.localWorld),this.debugGraphic.clear(),t.showBroadphase&&e.broadphase.controller&&this.renderGrid(e.broadphase,i,t.broadphaseColor,.5),t.showBounds&&this.renderBodyBounds(n,i,t.boundsColor,.5),(t.showBody||t.showStaticBody)&&this.renderBodies(n),t.showJoint&&this.renderJoints(),(t.showAxes||t.showAngleIndicator)&&this.renderBodyAxes(n,i,t.showAxes,t.angleColor,.5),t.showVelocity&&this.renderBodyVelocity(n,i,t.velocityColor,1,2),t.showSeparations&&this.renderSeparations(e.pairs.list,i,t.separationColor),t.showCollisions&&this.renderCollisions(e.pairs.list,i,t.collisionColor))},renderGrid:function(t,e,i,n){e.lineStyle(1,i,n);for(var s=y.keys(t.buckets),r=0;rn.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=l(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(277),p=i(595),g=i(171);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],l=0;l=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(133),b=i(599),E=i(277);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=l(e,i),o.tilesets=u(e),o}},function(t,e,i){var d=i(131),f=i(89);t.exports=function(t,e){for(var i=[],n=0;n>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(337),BaseCamera:i(140),CameraManager:i(799),Effects:i(344),Events:i(38)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(18),s=i(0),l=i(38),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?l.FADE_OUT_START:l.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(u=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:uMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(144);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(144);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(362);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(13);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(399),Palettes:i(909)}},function(t,e,i){t.exports={ARNE16:i(400),C64:i(910),CGA:i(911),JMP:i(912),MSX:i(913)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(915),MoveTo:i(404),CubicBezier:i(401),Curve:i(97),Ellipse:i(402),Line:i(403),QuadraticBezier:i(405),Spline:i(406)}},function(t,e,i){var n=i(0),u=i(401),l=i(402),s=i(5),r=i(403),o=i(404),a=i(405),h=i(10),c=i(406),d=i(3),f=i(13),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),l=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new u(h,o,a,l))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(39),l=i(410);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=l(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=l(s,n,t),a=l(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(196);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:l(t,n,h),g:l(e,s,h),b:l(i,r,h)}}var l=i(142);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(203),s=i(39);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(409);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(321),GeometryMask:i(322)}},function(t,e,i){var n={AddToDOM:i(149),DOMContentLoaded:i(411),GetInnerHeight:i(412),GetScreenOrientation:i(413),GetTarget:i(418),ParseXML:i(419),RemoveFromDOM:i(210),RequestAnimationFrame:i(397)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(939)}},function(t,e,i){var n=i(0),s=i(9),r=i(25),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(149),s=i(332),r=i(336),o=i(33),a=i(0),h=i(357),l=i(941),u=i(377),c=i(95),d=i(395),f=i(358),p=i(411),g=i(9),v=i(23),m=i(420),y=i(25),x=i(425),T=i(426),w=i(428),b=i(112),E=i(433),S=i(396),A=i(398),_=i(437),C=i(446),P=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new E(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.facebook=new C(this),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),u(this),l(this),d(this),n(this.canvas,this.config.parent),this.textures.once(b.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=P},function(t,e,i){var n=i(149);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){var n={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"};n.facebook="facebook",t.exports=n},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var l=i(83);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),l(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var M=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=M(e,"chars","");if(""!==o){var a=M(e,"image",""),h=t.sys.textures.getFrame(a),l=h.cutX,u=h.cutY,c=h.source.width,d=h.source.height,f=M(e,"offset.x",0),p=M(e,"offset.y",0),g=M(e,"spacing.x",0),v=M(e,"spacing.y",0),m=M(e,"lineSpacing",0),y=M(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},b=0,E=0;E=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(198);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(126);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(37);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){l.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){l.revokeObjectURL(s.data),s.onProcessError()},l.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;re.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?n=e.min.y-t.max.y:t.max.y=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(450),List:i(117),Map:i(108),ProcessQueue:i(219),RTree:i(543),Set:i(156),Size:i(427)}},function(t,e,i){var n=i(17),s=i(1464),r=n(!1,r={CanvasTexture:i(434),Events:i(112),FilterMode:s,Frame:i(116),Parsers:i(436),Texture:i(214),TextureManager:i(433),TextureSource:i(435)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(17),s=i(1466),r=n(!1,r={Components:i(268),Parsers:i(1499),Formats:i(41),ImageCollection:i(599),ParseToTilemap:i(279),Tile:i(89),Tilemap:i(603),TilemapCreator:i(1505),TilemapFactory:i(1506),Tileset:i(133),TilemapLayer:i(604),Orientation:i(31),LayerData:i(131),MapData:i(132),ObjectLayer:i(595)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(31)};t.exports=n},function(t,e,i){var p=i(27),g=i(66);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),l=s-t,u=r-e,c=0;c=t&&l.index<=e&&u(l,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(78),h=i(66),l=i(170);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(82),DeepCopy:i(181),Extend:i(17),GetAdvancedValue:i(15),GetFastValue:i(2),GetMinMaxValue:i(1531),GetValue:i(6),HasAll:i(1532),HasAny:i(467),HasValue:i(122),IsPlainObject:i(7),Merge:i(115),MergeRight:i(1533),Pick:i(594),SetValue:i(490)}},function(t,e,i){var o=i(6),a=i(18);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;i - * @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; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TransformMatrix = __webpack_require__(25); - -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; - - -/***/ }), -/* 19 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -4154,6 +4053,107 @@ var Extend = function () module.exports = Extend; +/***/ }), +/* 18 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TransformMatrix = __webpack_require__(25); + +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; + + /***/ }), /* 20 */ /***/ (function(module, exports) { @@ -4395,12 +4395,12 @@ module.exports = { var Class = __webpack_require__(0); var CONST = __webpack_require__(20); -var Events = __webpack_require__(90); +var Events = __webpack_require__(91); var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(152); -var MergeXHRSettings = __webpack_require__(235); -var XHRLoader = __webpack_require__(495); -var XHRSettings = __webpack_require__(153); +var GetURL = __webpack_require__(153); +var MergeXHRSettings = __webpack_require__(237); +var XHRLoader = __webpack_require__(511); +var XHRSettings = __webpack_require__(154); /** * @classdesc @@ -6338,7 +6338,7 @@ module.exports = PropertyValueSet; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var GetAdvancedValue = __webpack_require__(13); /** @@ -6539,7 +6539,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Takes a reference to the Canvas Renderer, a Canvas Rendering Context, a Game Object, a Camera and a parent matrix @@ -6607,7 +6607,7 @@ module.exports = SetTransform; */ var CONST = __webpack_require__(39); -var Smoothing = __webpack_require__(188); +var Smoothing = __webpack_require__(189); // The pool into which the canvas elements are placed. var pool = []; @@ -6871,7 +6871,7 @@ var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var Line = __webpack_require__(45); -var PIPELINES_CONST = __webpack_require__(72); +var PIPELINES_CONST = __webpack_require__(65); /** * @classdesc @@ -7262,6 +7262,345 @@ module.exports = Shape; /***/ }), /* 33 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + DIFFERENCE: 11, + + /** + * Exclusion blend mode. For Canvas only. + * Like difference, but with lower contrast. + * + * @name Phaser.BlendModes.EXCLUSION + * @type {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + LUMINOSITY: 16, + + /** + * Alpha erase blend mode. For Canvas and WebGL. + * + * @name Phaser.BlendModes.ERASE + * @type {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + LIGHTER: 25, + + /** + * Copy blend mode. For Canvas only. + * Only the new shape is shown. + * + * @name Phaser.BlendModes.COPY + * @type {number} + * @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 {number} + * @const + * @since 3.0.0 + */ + XOR: 27 + +}; + + +/***/ }), +/* 34 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7291,7 +7630,7 @@ module.exports = DegToRad; /***/ }), -/* 34 */ +/* 35 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7329,7 +7668,7 @@ module.exports = { /***/ }), -/* 35 */ +/* 36 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -7341,7 +7680,7 @@ module.exports = { var Class = __webpack_require__(0); var GetColor = __webpack_require__(100); var GetColor32 = __webpack_require__(322); -var HSVToRGB = __webpack_require__(184); +var HSVToRGB = __webpack_require__(185); var RGBToHSV = __webpack_require__(323); /** @@ -8192,7 +8531,7 @@ module.exports = Color; /***/ }), -/* 36 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -9238,7 +9577,7 @@ module.exports = Vector3; /***/ }), -/* 37 */ +/* 38 */ /***/ (function(module, exports) { /** @@ -9292,345 +9631,6 @@ module.exports = { }; -/***/ }), -/* 38 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - DIFFERENCE: 11, - - /** - * Exclusion blend mode. For Canvas only. - * Like difference, but with lower contrast. - * - * @name Phaser.BlendModes.EXCLUSION - * @type {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - LUMINOSITY: 16, - - /** - * Alpha erase blend mode. For Canvas and WebGL. - * - * @name Phaser.BlendModes.ERASE - * @type {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - LIGHTER: 25, - - /** - * Copy blend mode. For Canvas only. - * Only the new shape is shown. - * - * @name Phaser.BlendModes.COPY - * @type {number} - * @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 {number} - * @const - * @since 3.0.0 - */ - XOR: 27 - -}; - - /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { @@ -9657,11 +9657,11 @@ var CONST = { * @type {string} * @since 3.0.0 */ - VERSION: '3.50.0', + VERSION: '3.50.1', - BlendModes: __webpack_require__(38), + BlendModes: __webpack_require__(33), - ScaleModes: __webpack_require__(263), + ScaleModes: __webpack_require__(164), /** * This setting will auto-detect if the browser is capable of suppporting WebGL. @@ -9966,9 +9966,9 @@ module.exports = PropertyValueInc; var Class = __webpack_require__(0); var GetPoint = __webpack_require__(301); -var GetPoints = __webpack_require__(167); +var GetPoints = __webpack_require__(168); var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(168); +var Random = __webpack_require__(169); var Vector2 = __webpack_require__(3); /** @@ -11466,44 +11466,6 @@ module.exports = Contains; /***/ }), /* 57 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets the strokeStyle and lineWidth on the target context based on the given Shape. - * - * @method Phaser.GameObjects.Shape#LineStyleCanvas - * @since 3.13.0 - * @private - * - * @param {CanvasRenderingContext2D} ctx - The context to set the stroke style on. - * @param {Phaser.GameObjects.Shape} src - The Game Object to set the stroke style from. - * @param {number} [altColor] - An alternative color to render with. - * @param {number} [altAlpha] - An alternative alpha to render with. - */ -var LineStyleCanvas = function (ctx, src, altColor, altAlpha) -{ - var strokeColor = (altColor) ? altColor : src.strokeColor; - var strokeAlpha = (altAlpha) ? altAlpha : src.strokeAlpha; - - var red = ((strokeColor & 0xFF0000) >>> 16); - var green = ((strokeColor & 0xFF00) >>> 8); - var blue = (strokeColor & 0xFF); - - ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; - ctx.lineWidth = src.lineWidth; -}; - -module.exports = LineStyleCanvas; - - -/***/ }), -/* 58 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -11513,2708 +11475,15 @@ module.exports = LineStyleCanvas; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -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 `.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 `.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; - - -/***/ }), -/* 59 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Arcade Physics consts. - * - * @ignore - */ - -var CONST = { - - /** - * Dynamic Body. - * - * @name Phaser.Physics.Arcade.DYNAMIC_BODY - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.Group#physicsType - */ - DYNAMIC_BODY: 0, - - /** - * Static Body. - * - * @name Phaser.Physics.Arcade.STATIC_BODY - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.StaticBody#physicsType - */ - STATIC_BODY: 1, - - /** - * Arcade Physics Group containing Dynamic Bodies. - * - * @name Phaser.Physics.Arcade.GROUP - * @readonly - * @type {number} - * @since 3.0.0 - */ - GROUP: 2, - - /** - * A Tilemap Layer. - * - * @name Phaser.Physics.Arcade.TILEMAPLAYER - * @readonly - * @type {number} - * @since 3.0.0 - */ - TILEMAPLAYER: 3, - - /** - * Facing no direction (initial value). - * - * @name Phaser.Physics.Arcade.FACING_NONE - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_NONE: 10, - - /** - * Facing up. - * - * @name Phaser.Physics.Arcade.FACING_UP - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_UP: 11, - - /** - * Facing down. - * - * @name Phaser.Physics.Arcade.FACING_DOWN - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_DOWN: 12, - - /** - * Facing left. - * - * @name Phaser.Physics.Arcade.FACING_LEFT - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_LEFT: 13, - - /** - * Facing right. - * - * @name Phaser.Physics.Arcade.FACING_RIGHT - * @readonly - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_RIGHT: 14 - -}; - -module.exports = CONST; - - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTileAt = __webpack_require__(155); -var GetTilesWithin = __webpack_require__(26); - -/** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * @function Phaser.Tilemaps.Components.CalculateFacesWithin - * @since 3.0.0 - * - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var CalculateFacesWithin = function (tileX, tileY, width, height, layer) -{ - var above = null; - var below = null; - var left = null; - var right = null; - - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; - - if (tile) - { - if (tile.collides) - { - above = GetTileAt(tile.x, tile.y - 1, true, layer); - below = GetTileAt(tile.x, tile.y + 1, true, layer); - left = GetTileAt(tile.x - 1, tile.y, true, layer); - right = GetTileAt(tile.x + 1, tile.y, true, layer); - - tile.faceTop = (above && above.collides) ? false : true; - tile.faceBottom = (below && below.collides) ? false : true; - tile.faceLeft = (left && left.collides) ? false : true; - tile.faceRight = (right && right.collides) ? false : true; - } - else - { - tile.resetFaces(); - } - } - } -}; - -module.exports = CalculateFacesWithin; - - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Contains = __webpack_require__(62); -var GetPoint = __webpack_require__(294); -var GetPoints = __webpack_require__(295); -var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(165); - -/** - * @classdesc - * A Circle object. - * - * This is a geometry object, containing numerical values and related methods to inspect and modify them. - * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. - * To render a Circle you should look at the capabilities of the Graphics class. - * - * @class Circle - * @memberof Phaser.Geom - * @constructor - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * @param {number} [radius=0] - The radius of the circle. - */ -var Circle = new Class({ - - initialize: - - function Circle (x, y, radius) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 0; } - - /** - * The geometry constant type of this object: `GEOM_CONST.CIRCLE`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Circle#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.CIRCLE; - - /** - * The x position of the center of the circle. - * - * @name Phaser.Geom.Circle#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = x; - - /** - * The y position of the center of the circle. - * - * @name Phaser.Geom.Circle#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = y; - - /** - * The internal radius of the circle. - * - * @name Phaser.Geom.Circle#_radius - * @type {number} - * @private - * @since 3.0.0 - */ - this._radius = radius; - - /** - * The internal diameter of the circle. - * - * @name Phaser.Geom.Circle#_diameter - * @type {number} - * @private - * @since 3.0.0 - */ - this._diameter = radius * 2; - }, - - /** - * Check to see if the Circle contains the given x / y coordinates. - * - * @method Phaser.Geom.Circle#contains - * @since 3.0.0 - * - * @param {number} x - The x coordinate to check within the circle. - * @param {number} y - The y coordinate to check within the circle. - * - * @return {boolean} True if the coordinates are within the circle, otherwise false. - */ - contains: function (x, y) - { - return Contains(this, x, y); - }, - - /** - * Returns a Point object containing the coordinates of a point on the circumference of the Circle - * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point - * at 180 degrees around the circle. - * - * @method Phaser.Geom.Circle#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle. - */ - getPoint: function (position, point) - { - return GetPoint(this, position, point); - }, - - /** - * Returns an array of Point objects containing the coordinates of the points around the circumference of the Circle, - * based on the given quantity or stepRate values. - * - * @method Phaser.Geom.Circle#getPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [output,$return] - * - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the circumference of the circle and dividing it by the stepRate. - * @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle. - */ - getPoints: function (quantity, stepRate, output) - { - return GetPoints(this, quantity, stepRate, output); - }, - - /** - * Returns a uniformly distributed random point from anywhere within the Circle. - * - * @method Phaser.Geom.Circle#getRandomPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. - * - * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. - */ - getRandomPoint: function (point) - { - return Random(this, point); - }, - - /** - * Sets the x, y and radius of this circle. - * - * @method Phaser.Geom.Circle#setTo - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * @param {number} [radius=0] - The radius of the circle. - * - * @return {this} This Circle object. - */ - setTo: function (x, y, radius) - { - this.x = x; - this.y = y; - this._radius = radius; - this._diameter = radius * 2; - - return this; - }, - - /** - * Sets this Circle to be empty with a radius of zero. - * Does not change its position. - * - * @method Phaser.Geom.Circle#setEmpty - * @since 3.0.0 - * - * @return {this} This Circle object. - */ - setEmpty: function () - { - this._radius = 0; - this._diameter = 0; - - return this; - }, - - /** - * Sets the position of this Circle. - * - * @method Phaser.Geom.Circle#setPosition - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of the center of the circle. - * @param {number} [y=0] - The y position of the center of the circle. - * - * @return {this} This Circle object. - */ - setPosition: function (x, y) - { - if (y === undefined) { y = x; } - - this.x = x; - this.y = y; - - return this; - }, - - /** - * Checks to see if the Circle is empty: has a radius of zero. - * - * @method Phaser.Geom.Circle#isEmpty - * @since 3.0.0 - * - * @return {boolean} True if the Circle is empty, otherwise false. - */ - isEmpty: function () - { - return (this._radius <= 0); - }, - - /** - * The radius of the Circle. - * - * @name Phaser.Geom.Circle#radius - * @type {number} - * @since 3.0.0 - */ - radius: { - - get: function () - { - return this._radius; - }, - - set: function (value) - { - this._radius = value; - this._diameter = value * 2; - } - - }, - - /** - * The diameter of the Circle. - * - * @name Phaser.Geom.Circle#diameter - * @type {number} - * @since 3.0.0 - */ - diameter: { - - get: function () - { - return this._diameter; - }, - - set: function (value) - { - this._diameter = value; - this._radius = value * 0.5; - } - - }, - - /** - * The left position of the Circle. - * - * @name Phaser.Geom.Circle#left - * @type {number} - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.x - this._radius; - }, - - set: function (value) - { - this.x = value + this._radius; - } - - }, - - /** - * The right position of the Circle. - * - * @name Phaser.Geom.Circle#right - * @type {number} - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.x + this._radius; - }, - - set: function (value) - { - this.x = value - this._radius; - } - - }, - - /** - * The top position of the Circle. - * - * @name Phaser.Geom.Circle#top - * @type {number} - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.y - this._radius; - }, - - set: function (value) - { - this.y = value + this._radius; - } - - }, - - /** - * The bottom position of the Circle. - * - * @name Phaser.Geom.Circle#bottom - * @type {number} - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.y + this._radius; - }, - - set: function (value) - { - this.y = value - this._radius; - } - - } - -}); - -module.exports = Circle; - - -/***/ }), -/* 62 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Check to see if the Circle contains the given x / y coordinates. - * - * @function Phaser.Geom.Circle.Contains - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The Circle to check. - * @param {number} x - The x coordinate to check within the circle. - * @param {number} y - The y coordinate to check within the circle. - * - * @return {boolean} True if the coordinates are within the circle, otherwise false. - */ -var Contains = function (circle, x, y) -{ - // Check if x/y are within the bounds first - if (circle.radius > 0 && x >= circle.left && x <= circle.right && y >= circle.top && y <= circle.bottom) - { - var dx = (circle.x - x) * (circle.x - x); - var dy = (circle.y - y) * (circle.y - y); - - return (dx + dy) <= (circle.radius * circle.radius); - } - else - { - return false; - } -}; - -module.exports = Contains; - - -/***/ }), -/* 63 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 64 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector3 = __webpack_require__(36); - -/** - * @ignore - */ -var EPSILON = 0.000001; - -/** - * @classdesc - * A four-dimensional matrix. - * - * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji - * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - * - * @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 {this} This Matrix4. - */ - set: function (src) - { - return this.copy(src); - }, - - /** - * Sets all values of this Matrix4. - * - * @method Phaser.Math.Matrix4#setValues - * @since 3.50.0 - * - * @param {number} m00 - The m00 value. - * @param {number} m01 - The m01 value. - * @param {number} m02 - The m02 value. - * @param {number} m03 - The m03 value. - * @param {number} m10 - The m10 value. - * @param {number} m11 - The m11 value. - * @param {number} m12 - The m12 value. - * @param {number} m13 - The m13 value. - * @param {number} m20 - The m20 value. - * @param {number} m21 - The m21 value. - * @param {number} m22 - The m22 value. - * @param {number} m23 - The m23 value. - * @param {number} m30 - The m30 value. - * @param {number} m31 - The m31 value. - * @param {number} m32 - The m32 value. - * @param {number} m33 - The m33 value. - * - * @return {this} This Matrix4 instance. - */ - setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) - { - var out = this.val; - - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - - return this; - }, - - /** - * 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 {this} This Matrix4. - */ - copy: function (src) - { - var a = src.val; - - return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - }, - - /** - * Set the values of this Matrix from the given array. - * - * @method Phaser.Math.Matrix4#fromArray - * @since 3.0.0 - * - * @param {number[]} a - The array to copy the values from. Must have at least 16 elements. - * - * @return {this} This Matrix4. - */ - fromArray: function (a) - { - return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); - }, - - /** - * 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 () - { - return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - }, - - /** - * 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 {this} This Matrix4. - */ - transform: function (position, scale, rotation) - { - var rotMatrix = _tempMat1.fromQuat(rotation); - - var rm = rotMatrix.val; - - var sx = scale.x; - var sy = scale.y; - var sz = scale.z; - - return this.setValues( - rm[0] * sx, - rm[1] * sx, - rm[2] * sx, - 0, - - rm[4] * sy, - rm[5] * sy, - rm[6] * sy, - 0, - - rm[8] * sz, - rm[9] * sz, - rm[10] * sz, - 0, - - position.x, - position.y, - position.z, - 1 - ); - }, - - /** - * 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 {this} 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 {this} 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 {this} This Matrix4. - */ - identity: function () - { - return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - }, - - /** - * Transpose this Matrix. - * - * @method Phaser.Math.Matrix4#transpose - * @since 3.0.0 - * - * @return {this} 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 - * - * @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4. - * - * @return {this} This Matrix4. - */ - getInverse: function (m) - { - this.copy(m); - - return this.invert(); - }, - - /** - * Invert this Matrix. - * - * @method Phaser.Math.Matrix4#invert - * @since 3.0.0 - * - * @return {this} 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; - - return this.setValues( - (a11 * b11 - a12 * b10 + a13 * b09) * det, - (a02 * b10 - a01 * b11 - a03 * b09) * det, - (a31 * b05 - a32 * b04 + a33 * b03) * det, - (a22 * b04 - a21 * b05 - a23 * b03) * det, - (a12 * b08 - a10 * b11 - a13 * b07) * det, - (a00 * b11 - a02 * b08 + a03 * b07) * det, - (a32 * b02 - a30 * b05 - a33 * b01) * det, - (a20 * b05 - a22 * b02 + a23 * b01) * det, - (a10 * b10 - a11 * b08 + a13 * b06) * det, - (a01 * b08 - a00 * b10 - a03 * b06) * det, - (a30 * b04 - a31 * b02 + a33 * b00) * det, - (a21 * b02 - a20 * b04 - a23 * b00) * det, - (a11 * b07 - a10 * b09 - a12 * b06) * det, - (a00 * b09 - a01 * b07 + a02 * b06) * det, - (a31 * b01 - a30 * b03 - a32 * b00) * det, - (a20 * b03 - a21 * b01 + a22 * b00) * det - ); - }, - - /** - * Calculate the adjoint, or adjugate, of this Matrix. - * - * @method Phaser.Math.Matrix4#adjoint - * @since 3.0.0 - * - * @return {this} 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]; - - return this.setValues( - (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)), - -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)), - (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)), - -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)), - -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)), - (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)), - -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)), - (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)), - (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)), - -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)), - (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)), - -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)), - -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)), - (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)), - -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)), - (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)) - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - multiplyLocal: function (src) - { - var a = this.val; - var b = src.val; - - return this.setValues( - a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12], - a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13], - a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14], - a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15], - - a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12], - a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13], - a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14], - a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15], - - a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12], - a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13], - a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14], - a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15], - - a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12], - a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13], - a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14], - a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15] - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - multiplyMatrices: function (a, b) - { - var am = a.val; - var bm = b.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]; - - return this.setValues( - a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41, - a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41, - a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41, - a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41, - a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42, - a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42, - a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42, - a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42, - a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43, - a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43, - a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43, - a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43, - a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44, - a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44, - a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44, - a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - translate: function (v) - { - return this.translateXYZ(v.x, v.y, v.z); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - scale: function (v) - { - return this.scaleXYZ(v.x, v.y, v.z); - }, - - /** - * 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 {this} 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 {this} 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; - - return this.setValues( - 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 - ); - }, - - /** - * 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 {this} 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 this; - } - - 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]; - - var a30 = a[12]; - var a31 = a[13]; - var a32 = a[14]; - var a33 = a[15]; - - // 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 - return this.setValues( - a00 * b00 + a10 * b01 + a20 * b02, - a01 * b00 + a11 * b01 + a21 * b02, - a02 * b00 + a12 * b01 + a22 * b02, - a03 * b00 + a13 * b01 + a23 * b02, - a00 * b10 + a10 * b11 + a20 * b12, - a01 * b10 + a11 * b11 + a21 * b12, - a02 * b10 + a12 * b11 + a22 * b12, - a03 * b10 + a13 * b11 + a23 * b12, - a00 * b20 + a10 * b21 + a20 * b22, - a01 * b20 + a11 * b21 + a21 * b22, - a02 * b20 + a12 * b21 + a22 * b22, - a03 * b20 + a13 * b21 + a23 * b22, - a30, a31, a32, a33 - ); - }, - - /** - * 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 {this} 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 {this} 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 {this} 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 {this} This Matrix4. - */ - fromRotationTranslation: function (q, v) - { - // Quaternion math - 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; - - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, - - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, - - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, - - v.x, - v.y, - v.z, - 1 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - 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; - - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, - - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, - - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, - - 0, - 0, - 0, - 1 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - frustum: function (left, right, bottom, top, near, far) - { - var rl = 1 / (right - left); - var tb = 1 / (top - bottom); - var nf = 1 / (near - far); - - return this.setValues( - (near * 2) * rl, - 0, - 0, - 0, - - 0, - (near * 2) * tb, - 0, - 0, - - (right + left) * rl, - (top + bottom) * tb, - (far + near) * nf, - -1, - - 0, - 0, - (far * near * 2) * nf, - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - perspective: function (fovy, aspect, near, far) - { - var f = 1.0 / Math.tan(fovy / 2); - var nf = 1 / (near - far); - - return this.setValues( - f / aspect, - 0, - 0, - 0, - - 0, - f, - 0, - 0, - - 0, - 0, - (far + near) * nf, - -1, - - 0, - 0, - (2 * far * near) * nf, - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - perspectiveLH: function (width, height, near, far) - { - return this.setValues( - (2 * near) / width, - 0, - 0, - 0, - - 0, - (2 * near) / height, - 0, - 0, - - 0, - 0, - -far / (near - far), - 1, - - 0, - 0, - (near * far) / (near - far), - 0 - ); - }, - - /** - * 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 {this} This Matrix4. - */ - ortho: function (left, right, bottom, top, near, far) - { - 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; - - return this.setValues( - -2 * lr, - 0, - 0, - 0, - - 0, - -2 * bt, - 0, - 0, - - 0, - 0, - 2 * nf, - 0, - - (left + right) * lr, - (top + bottom) * bt, - (far + near) * nf, - 1 - ); - }, - - /** - * 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 {this} 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 {this} This Matrix4. - */ - lookAt: function (eye, center, up) - { - 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; - } - - return this.setValues( - x0, - y0, - z0, - 0, - - x1, - y1, - z1, - 0, - - x2, - y2, - z2, - 0, - - -(x0 * eyex + x1 * eyey + x2 * eyez), - -(y0 * eyex + y1 * eyey + y2 * eyez), - -(z0 * eyex + z1 * eyey + z2 * eyez), - 1 - ); - }, - - /** - * 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 {this} 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 {this} 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) - { - this.multiplyLocal(viewMatrix); - } - - if (projectionMatrix) - { - this.multiplyLocal(projectionMatrix); - } - - return this; - }, - - /** - * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4. - * - * @method Phaser.Math.Matrix4#multiplyToMat4 - * @since 3.50.0 - * - * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one. - * @param {Phaser.Math.Matrix4} out - The receiving Matrix. - * - * @return {Phaser.Math.Matrix4} This `out` Matrix4. - */ - multiplyToMat4: function (src, out) - { - var a = this.val; - var b = src.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 = b[0]; - var b01 = b[1]; - var b02 = b[2]; - var b03 = b[3]; - var b10 = b[4]; - var b11 = b[5]; - var b12 = b[6]; - var b13 = b[7]; - var b20 = b[8]; - var b21 = b[9]; - var b22 = b[10]; - var b23 = b[11]; - var b30 = b[12]; - var b31 = b[13]; - var b32 = b[14]; - var b33 = b[15]; - - return out.setValues( - b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, - b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31, - b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32, - b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33, - - b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, - b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, - b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, - b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, - - b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, - b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, - b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, - b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, - - b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, - b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, - b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, - b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33 - ); - }, - - /** - * Takes the rotation and position vectors and builds this Matrix4 from them. - * - * @method Phaser.Math.Matrix4#fromRotationXYTranslation - * @since 3.50.0 - * - * @param {Phaser.Math.Vector3} rotation - The rotation vector. - * @param {Phaser.Math.Vector3} position - The position vector. - * @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`) - * - * @return {this} This Matrix4. - */ - fromRotationXYTranslation: function (rotation, position, translateFirst) - { - var x = position.x; - var y = position.y; - var z = position.z; - - var sx = Math.sin(rotation.x); - var cx = Math.cos(rotation.x); - - var sy = Math.sin(rotation.y); - var cy = Math.cos(rotation.y); - - var a30 = x; - var a31 = y; - var a32 = z; - - // Rotate X - - var b21 = -sx; - - // Rotate Y - - var c01 = 0 - b21 * sy; - - var c02 = 0 - cx * sy; - - var c21 = b21 * cy; - - var c22 = cx * cy; - - // Translate - if (!translateFirst) - { - // a30 = cy * x + 0 * y + sy * z; - a30 = cy * x + sy * z; - a31 = c01 * x + cx * y + c21 * z; - a32 = c02 * x + sx * y + c22 * z; - } - - return this.setValues( - cy, - c01, - c02, - 0, - 0, - cx, - sx, - 0, - sy, - c21, - c22, - 0, - a30, - a31, - a32, - 1 - ); - }, - - /** - * 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)); - } - -}); - -/** - * @ignore - */ -var _tempMat1 = new Matrix4(); - -/** - * @ignore - */ -var _tempMat2 = new Matrix4(); - -/** - * @ignore - */ -var _x = new Vector3(); - -/** - * @ignore - */ -var _y = new Vector3(); - -/** - * @ignore - */ -var _z = new Vector3(); - -module.exports = Matrix4; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DeepCopy = __webpack_require__(171); +var DeepCopy = __webpack_require__(172); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(575); +var Events = __webpack_require__(368); var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(65); -var RendererEvents = __webpack_require__(94); -var RenderTarget = __webpack_require__(162); +var Matrix4 = __webpack_require__(67); +var RendererEvents = __webpack_require__(88); +var RenderTarget = __webpack_require__(139); var Utils = __webpack_require__(12); -var WebGLShader = __webpack_require__(576); +var WebGLShader = __webpack_require__(369); /** * @classdesc @@ -16312,10 +13581,2847 @@ var WebGLPipeline = new Class({ module.exports = WebGLPipeline; +/***/ }), +/* 58 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets the strokeStyle and lineWidth on the target context based on the given Shape. + * + * @method Phaser.GameObjects.Shape#LineStyleCanvas + * @since 3.13.0 + * @private + * + * @param {CanvasRenderingContext2D} ctx - The context to set the stroke style on. + * @param {Phaser.GameObjects.Shape} src - The Game Object to set the stroke style from. + * @param {number} [altColor] - An alternative color to render with. + * @param {number} [altAlpha] - An alternative alpha to render with. + */ +var LineStyleCanvas = function (ctx, src, altColor, altAlpha) +{ + var strokeColor = (altColor) ? altColor : src.strokeColor; + var strokeAlpha = (altAlpha) ? altAlpha : src.strokeAlpha; + + var red = ((strokeColor & 0xFF0000) >>> 16); + var green = ((strokeColor & 0xFF00) >>> 8); + var blue = (strokeColor & 0xFF); + + ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; + ctx.lineWidth = src.lineWidth; +}; + +module.exports = LineStyleCanvas; + + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var GetValue = __webpack_require__(6); +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 `.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 `.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; + + +/***/ }), +/* 60 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Arcade Physics consts. + * + * @ignore + */ + +var CONST = { + + /** + * Dynamic Body. + * + * @name Phaser.Physics.Arcade.DYNAMIC_BODY + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#physicsType + * @see Phaser.Physics.Arcade.Group#physicsType + */ + DYNAMIC_BODY: 0, + + /** + * Static Body. + * + * @name Phaser.Physics.Arcade.STATIC_BODY + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#physicsType + * @see Phaser.Physics.Arcade.StaticBody#physicsType + */ + STATIC_BODY: 1, + + /** + * Arcade Physics Group containing Dynamic Bodies. + * + * @name Phaser.Physics.Arcade.GROUP + * @readonly + * @type {number} + * @since 3.0.0 + */ + GROUP: 2, + + /** + * A Tilemap Layer. + * + * @name Phaser.Physics.Arcade.TILEMAPLAYER + * @readonly + * @type {number} + * @since 3.0.0 + */ + TILEMAPLAYER: 3, + + /** + * Facing no direction (initial value). + * + * @name Phaser.Physics.Arcade.FACING_NONE + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_NONE: 10, + + /** + * Facing up. + * + * @name Phaser.Physics.Arcade.FACING_UP + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_UP: 11, + + /** + * Facing down. + * + * @name Phaser.Physics.Arcade.FACING_DOWN + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_DOWN: 12, + + /** + * Facing left. + * + * @name Phaser.Physics.Arcade.FACING_LEFT + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_LEFT: 13, + + /** + * Facing right. + * + * @name Phaser.Physics.Arcade.FACING_RIGHT + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_RIGHT: 14 + +}; + +module.exports = CONST; + + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTileAt = __webpack_require__(156); +var GetTilesWithin = __webpack_require__(26); + +/** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * @function Phaser.Tilemaps.Components.CalculateFacesWithin + * @since 3.0.0 + * + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var CalculateFacesWithin = function (tileX, tileY, width, height, layer) +{ + var above = null; + var below = null; + var left = null; + var right = null; + + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) + { + var tile = tiles[i]; + + if (tile) + { + if (tile.collides) + { + above = GetTileAt(tile.x, tile.y - 1, true, layer); + below = GetTileAt(tile.x, tile.y + 1, true, layer); + left = GetTileAt(tile.x - 1, tile.y, true, layer); + right = GetTileAt(tile.x + 1, tile.y, true, layer); + + tile.faceTop = (above && above.collides) ? false : true; + tile.faceBottom = (below && below.collides) ? false : true; + tile.faceLeft = (left && left.collides) ? false : true; + tile.faceRight = (right && right.collides) ? false : true; + } + else + { + tile.resetFaces(); + } + } + } +}; + +module.exports = CalculateFacesWithin; + + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Contains = __webpack_require__(63); +var GetPoint = __webpack_require__(294); +var GetPoints = __webpack_require__(295); +var GEOM_CONST = __webpack_require__(55); +var Random = __webpack_require__(166); + +/** + * @classdesc + * A Circle object. + * + * This is a geometry object, containing numerical values and related methods to inspect and modify them. + * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. + * To render a Circle you should look at the capabilities of the Graphics class. + * + * @class Circle + * @memberof Phaser.Geom + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * @param {number} [radius=0] - The radius of the circle. + */ +var Circle = new Class({ + + initialize: + + function Circle (x, y, radius) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 0; } + + /** + * The geometry constant type of this object: `GEOM_CONST.CIRCLE`. + * Used for fast type comparisons. + * + * @name Phaser.Geom.Circle#type + * @type {number} + * @readonly + * @since 3.19.0 + */ + this.type = GEOM_CONST.CIRCLE; + + /** + * The x position of the center of the circle. + * + * @name Phaser.Geom.Circle#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = x; + + /** + * The y position of the center of the circle. + * + * @name Phaser.Geom.Circle#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = y; + + /** + * The internal radius of the circle. + * + * @name Phaser.Geom.Circle#_radius + * @type {number} + * @private + * @since 3.0.0 + */ + this._radius = radius; + + /** + * The internal diameter of the circle. + * + * @name Phaser.Geom.Circle#_diameter + * @type {number} + * @private + * @since 3.0.0 + */ + this._diameter = radius * 2; + }, + + /** + * Check to see if the Circle contains the given x / y coordinates. + * + * @method Phaser.Geom.Circle#contains + * @since 3.0.0 + * + * @param {number} x - The x coordinate to check within the circle. + * @param {number} y - The y coordinate to check within the circle. + * + * @return {boolean} True if the coordinates are within the circle, otherwise false. + */ + contains: function (x, y) + { + return Contains(this, x, y); + }, + + /** + * Returns a Point object containing the coordinates of a point on the circumference of the Circle + * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point + * at 180 degrees around the circle. + * + * @method Phaser.Geom.Circle#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle. + */ + getPoint: function (position, point) + { + return GetPoint(this, position, point); + }, + + /** + * Returns an array of Point objects containing the coordinates of the points around the circumference of the Circle, + * based on the given quantity or stepRate values. + * + * @method Phaser.Geom.Circle#getPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [output,$return] + * + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the circumference of the circle and dividing it by the stepRate. + * @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle. + */ + getPoints: function (quantity, stepRate, output) + { + return GetPoints(this, quantity, stepRate, output); + }, + + /** + * Returns a uniformly distributed random point from anywhere within the Circle. + * + * @method Phaser.Geom.Circle#getRandomPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. + * + * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. + */ + getRandomPoint: function (point) + { + return Random(this, point); + }, + + /** + * Sets the x, y and radius of this circle. + * + * @method Phaser.Geom.Circle#setTo + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * @param {number} [radius=0] - The radius of the circle. + * + * @return {this} This Circle object. + */ + setTo: function (x, y, radius) + { + this.x = x; + this.y = y; + this._radius = radius; + this._diameter = radius * 2; + + return this; + }, + + /** + * Sets this Circle to be empty with a radius of zero. + * Does not change its position. + * + * @method Phaser.Geom.Circle#setEmpty + * @since 3.0.0 + * + * @return {this} This Circle object. + */ + setEmpty: function () + { + this._radius = 0; + this._diameter = 0; + + return this; + }, + + /** + * Sets the position of this Circle. + * + * @method Phaser.Geom.Circle#setPosition + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of the center of the circle. + * @param {number} [y=0] - The y position of the center of the circle. + * + * @return {this} This Circle object. + */ + setPosition: function (x, y) + { + if (y === undefined) { y = x; } + + this.x = x; + this.y = y; + + return this; + }, + + /** + * Checks to see if the Circle is empty: has a radius of zero. + * + * @method Phaser.Geom.Circle#isEmpty + * @since 3.0.0 + * + * @return {boolean} True if the Circle is empty, otherwise false. + */ + isEmpty: function () + { + return (this._radius <= 0); + }, + + /** + * The radius of the Circle. + * + * @name Phaser.Geom.Circle#radius + * @type {number} + * @since 3.0.0 + */ + radius: { + + get: function () + { + return this._radius; + }, + + set: function (value) + { + this._radius = value; + this._diameter = value * 2; + } + + }, + + /** + * The diameter of the Circle. + * + * @name Phaser.Geom.Circle#diameter + * @type {number} + * @since 3.0.0 + */ + diameter: { + + get: function () + { + return this._diameter; + }, + + set: function (value) + { + this._diameter = value; + this._radius = value * 0.5; + } + + }, + + /** + * The left position of the Circle. + * + * @name Phaser.Geom.Circle#left + * @type {number} + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.x - this._radius; + }, + + set: function (value) + { + this.x = value + this._radius; + } + + }, + + /** + * The right position of the Circle. + * + * @name Phaser.Geom.Circle#right + * @type {number} + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.x + this._radius; + }, + + set: function (value) + { + this.x = value - this._radius; + } + + }, + + /** + * The top position of the Circle. + * + * @name Phaser.Geom.Circle#top + * @type {number} + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.y - this._radius; + }, + + set: function (value) + { + this.y = value + this._radius; + } + + }, + + /** + * The bottom position of the Circle. + * + * @name Phaser.Geom.Circle#bottom + * @type {number} + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.y + this._radius; + }, + + set: function (value) + { + this.y = value - this._radius; + } + + } + +}); + +module.exports = Circle; + + +/***/ }), +/* 63 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check to see if the Circle contains the given x / y coordinates. + * + * @function Phaser.Geom.Circle.Contains + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle to check. + * @param {number} x - The x coordinate to check within the circle. + * @param {number} y - The y coordinate to check within the circle. + * + * @return {boolean} True if the coordinates are within the circle, otherwise false. + */ +var Contains = function (circle, x, y) +{ + // Check if x/y are within the bounds first + if (circle.radius > 0 && x >= circle.left && x <= circle.right && y >= circle.top && y <= circle.bottom) + { + var dx = (circle.x - x) * (circle.x - x); + var dy = (circle.y - y) * (circle.y - y); + + return (dx + dy) <= (circle.radius * circle.radius); + } + else + { + return false; + } +}; + +module.exports = Contains; + + +/***/ }), +/* 64 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 65 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 Point Light Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + POINTLIGHT_PIPELINE: 'PointLightPipeline', + + /** + * 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', + + /** + * The Graphics and Shapes Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + GRAPHICS_PIPELINE: 'GraphicsPipeline', + + /** + * The Post FX Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + POSTFX_PIPELINE: 'PostFXPipeline', + + /** + * The Utility Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + UTILITY_PIPELINE: 'UtilityPipeline' +}; + +module.exports = PIPELINE_CONST; + + +/***/ }), +/* 66 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + /***/ }), /* 67 */ /***/ (function(module, exports, __webpack_require__) { +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector3 = __webpack_require__(37); + +/** + * @ignore + */ +var EPSILON = 0.000001; + +/** + * @classdesc + * A four-dimensional matrix. + * + * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji + * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + * + * @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 {this} This Matrix4. + */ + set: function (src) + { + return this.copy(src); + }, + + /** + * Sets all values of this Matrix4. + * + * @method Phaser.Math.Matrix4#setValues + * @since 3.50.0 + * + * @param {number} m00 - The m00 value. + * @param {number} m01 - The m01 value. + * @param {number} m02 - The m02 value. + * @param {number} m03 - The m03 value. + * @param {number} m10 - The m10 value. + * @param {number} m11 - The m11 value. + * @param {number} m12 - The m12 value. + * @param {number} m13 - The m13 value. + * @param {number} m20 - The m20 value. + * @param {number} m21 - The m21 value. + * @param {number} m22 - The m22 value. + * @param {number} m23 - The m23 value. + * @param {number} m30 - The m30 value. + * @param {number} m31 - The m31 value. + * @param {number} m32 - The m32 value. + * @param {number} m33 - The m33 value. + * + * @return {this} This Matrix4 instance. + */ + setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) + { + var out = this.val; + + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + + return this; + }, + + /** + * 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 {this} This Matrix4. + */ + copy: function (src) + { + var a = src.val; + + return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + }, + + /** + * Set the values of this Matrix from the given array. + * + * @method Phaser.Math.Matrix4#fromArray + * @since 3.0.0 + * + * @param {number[]} a - The array to copy the values from. Must have at least 16 elements. + * + * @return {this} This Matrix4. + */ + fromArray: function (a) + { + return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + }, + + /** + * 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 () + { + return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + }, + + /** + * 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 {this} This Matrix4. + */ + transform: function (position, scale, rotation) + { + var rotMatrix = _tempMat1.fromQuat(rotation); + + var rm = rotMatrix.val; + + var sx = scale.x; + var sy = scale.y; + var sz = scale.z; + + return this.setValues( + rm[0] * sx, + rm[1] * sx, + rm[2] * sx, + 0, + + rm[4] * sy, + rm[5] * sy, + rm[6] * sy, + 0, + + rm[8] * sz, + rm[9] * sz, + rm[10] * sz, + 0, + + position.x, + position.y, + position.z, + 1 + ); + }, + + /** + * 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 {this} 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 {this} 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 {this} This Matrix4. + */ + identity: function () + { + return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + }, + + /** + * Transpose this Matrix. + * + * @method Phaser.Math.Matrix4#transpose + * @since 3.0.0 + * + * @return {this} 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 + * + * @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4. + * + * @return {this} This Matrix4. + */ + getInverse: function (m) + { + this.copy(m); + + return this.invert(); + }, + + /** + * Invert this Matrix. + * + * @method Phaser.Math.Matrix4#invert + * @since 3.0.0 + * + * @return {this} 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; + + return this.setValues( + (a11 * b11 - a12 * b10 + a13 * b09) * det, + (a02 * b10 - a01 * b11 - a03 * b09) * det, + (a31 * b05 - a32 * b04 + a33 * b03) * det, + (a22 * b04 - a21 * b05 - a23 * b03) * det, + (a12 * b08 - a10 * b11 - a13 * b07) * det, + (a00 * b11 - a02 * b08 + a03 * b07) * det, + (a32 * b02 - a30 * b05 - a33 * b01) * det, + (a20 * b05 - a22 * b02 + a23 * b01) * det, + (a10 * b10 - a11 * b08 + a13 * b06) * det, + (a01 * b08 - a00 * b10 - a03 * b06) * det, + (a30 * b04 - a31 * b02 + a33 * b00) * det, + (a21 * b02 - a20 * b04 - a23 * b00) * det, + (a11 * b07 - a10 * b09 - a12 * b06) * det, + (a00 * b09 - a01 * b07 + a02 * b06) * det, + (a31 * b01 - a30 * b03 - a32 * b00) * det, + (a20 * b03 - a21 * b01 + a22 * b00) * det + ); + }, + + /** + * Calculate the adjoint, or adjugate, of this Matrix. + * + * @method Phaser.Math.Matrix4#adjoint + * @since 3.0.0 + * + * @return {this} 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]; + + return this.setValues( + (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)), + -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)), + (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)), + -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)), + -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)), + (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)), + -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)), + (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)), + (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)), + -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)), + (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)), + -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)), + -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)), + (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)), + -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)), + (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)) + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + multiplyLocal: function (src) + { + var a = this.val; + var b = src.val; + + return this.setValues( + a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12], + a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13], + a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14], + a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15], + + a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12], + a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13], + a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14], + a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15], + + a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12], + a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13], + a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14], + a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15], + + a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12], + a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13], + a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14], + a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15] + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + multiplyMatrices: function (a, b) + { + var am = a.val; + var bm = b.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]; + + return this.setValues( + a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41, + a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41, + a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41, + a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41, + a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42, + a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42, + a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42, + a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42, + a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43, + a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43, + a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43, + a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43, + a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44, + a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44, + a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44, + a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + translate: function (v) + { + return this.translateXYZ(v.x, v.y, v.z); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + scale: function (v) + { + return this.scaleXYZ(v.x, v.y, v.z); + }, + + /** + * 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 {this} 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 {this} 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; + + return this.setValues( + 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 + ); + }, + + /** + * 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 {this} 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 this; + } + + 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]; + + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + + // 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 + return this.setValues( + a00 * b00 + a10 * b01 + a20 * b02, + a01 * b00 + a11 * b01 + a21 * b02, + a02 * b00 + a12 * b01 + a22 * b02, + a03 * b00 + a13 * b01 + a23 * b02, + a00 * b10 + a10 * b11 + a20 * b12, + a01 * b10 + a11 * b11 + a21 * b12, + a02 * b10 + a12 * b11 + a22 * b12, + a03 * b10 + a13 * b11 + a23 * b12, + a00 * b20 + a10 * b21 + a20 * b22, + a01 * b20 + a11 * b21 + a21 * b22, + a02 * b20 + a12 * b21 + a22 * b22, + a03 * b20 + a13 * b21 + a23 * b22, + a30, a31, a32, a33 + ); + }, + + /** + * 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 {this} 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 {this} 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 {this} 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 {this} This Matrix4. + */ + fromRotationTranslation: function (q, v) + { + // Quaternion math + 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; + + return this.setValues( + 1 - (yy + zz), + xy + wz, + xz - wy, + 0, + + xy - wz, + 1 - (xx + zz), + yz + wx, + 0, + + xz + wy, + yz - wx, + 1 - (xx + yy), + 0, + + v.x, + v.y, + v.z, + 1 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + 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; + + return this.setValues( + 1 - (yy + zz), + xy + wz, + xz - wy, + 0, + + xy - wz, + 1 - (xx + zz), + yz + wx, + 0, + + xz + wy, + yz - wx, + 1 - (xx + yy), + 0, + + 0, + 0, + 0, + 1 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + frustum: function (left, right, bottom, top, near, far) + { + var rl = 1 / (right - left); + var tb = 1 / (top - bottom); + var nf = 1 / (near - far); + + return this.setValues( + (near * 2) * rl, + 0, + 0, + 0, + + 0, + (near * 2) * tb, + 0, + 0, + + (right + left) * rl, + (top + bottom) * tb, + (far + near) * nf, + -1, + + 0, + 0, + (far * near * 2) * nf, + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + perspective: function (fovy, aspect, near, far) + { + var f = 1.0 / Math.tan(fovy / 2); + var nf = 1 / (near - far); + + return this.setValues( + f / aspect, + 0, + 0, + 0, + + 0, + f, + 0, + 0, + + 0, + 0, + (far + near) * nf, + -1, + + 0, + 0, + (2 * far * near) * nf, + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + perspectiveLH: function (width, height, near, far) + { + return this.setValues( + (2 * near) / width, + 0, + 0, + 0, + + 0, + (2 * near) / height, + 0, + 0, + + 0, + 0, + -far / (near - far), + 1, + + 0, + 0, + (near * far) / (near - far), + 0 + ); + }, + + /** + * 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 {this} This Matrix4. + */ + ortho: function (left, right, bottom, top, near, far) + { + 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; + + return this.setValues( + -2 * lr, + 0, + 0, + 0, + + 0, + -2 * bt, + 0, + 0, + + 0, + 0, + 2 * nf, + 0, + + (left + right) * lr, + (top + bottom) * bt, + (far + near) * nf, + 1 + ); + }, + + /** + * 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 {this} 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 {this} This Matrix4. + */ + lookAt: function (eye, center, up) + { + 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; + } + + return this.setValues( + x0, + y0, + z0, + 0, + + x1, + y1, + z1, + 0, + + x2, + y2, + z2, + 0, + + -(x0 * eyex + x1 * eyey + x2 * eyez), + -(y0 * eyex + y1 * eyey + y2 * eyez), + -(z0 * eyex + z1 * eyey + z2 * eyez), + 1 + ); + }, + + /** + * 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 {this} 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 {this} 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) + { + this.multiplyLocal(viewMatrix); + } + + if (projectionMatrix) + { + this.multiplyLocal(projectionMatrix); + } + + return this; + }, + + /** + * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4. + * + * @method Phaser.Math.Matrix4#multiplyToMat4 + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one. + * @param {Phaser.Math.Matrix4} out - The receiving Matrix. + * + * @return {Phaser.Math.Matrix4} This `out` Matrix4. + */ + multiplyToMat4: function (src, out) + { + var a = this.val; + var b = src.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 = b[0]; + var b01 = b[1]; + var b02 = b[2]; + var b03 = b[3]; + var b10 = b[4]; + var b11 = b[5]; + var b12 = b[6]; + var b13 = b[7]; + var b20 = b[8]; + var b21 = b[9]; + var b22 = b[10]; + var b23 = b[11]; + var b30 = b[12]; + var b31 = b[13]; + var b32 = b[14]; + var b33 = b[15]; + + return out.setValues( + b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, + b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31, + b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32, + b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33, + + b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, + b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, + b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, + b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, + + b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, + b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, + b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, + b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, + + b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, + b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, + b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, + b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33 + ); + }, + + /** + * Takes the rotation and position vectors and builds this Matrix4 from them. + * + * @method Phaser.Math.Matrix4#fromRotationXYTranslation + * @since 3.50.0 + * + * @param {Phaser.Math.Vector3} rotation - The rotation vector. + * @param {Phaser.Math.Vector3} position - The position vector. + * @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`) + * + * @return {this} This Matrix4. + */ + fromRotationXYTranslation: function (rotation, position, translateFirst) + { + var x = position.x; + var y = position.y; + var z = position.z; + + var sx = Math.sin(rotation.x); + var cx = Math.cos(rotation.x); + + var sy = Math.sin(rotation.y); + var cy = Math.cos(rotation.y); + + var a30 = x; + var a31 = y; + var a32 = z; + + // Rotate X + + var b21 = -sx; + + // Rotate Y + + var c01 = 0 - b21 * sy; + + var c02 = 0 - cx * sy; + + var c21 = b21 * cy; + + var c22 = cx * cy; + + // Translate + if (!translateFirst) + { + // a30 = cy * x + 0 * y + sy * z; + a30 = cy * x + sy * z; + a31 = c01 * x + cx * y + c21 * z; + a32 = c02 * x + sx * y + c22 * z; + } + + return this.setValues( + cy, + c01, + c02, + 0, + 0, + cx, + sx, + 0, + sy, + c21, + c22, + 0, + a30, + a31, + a32, + 1 + ); + }, + + /** + * 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)); + } + +}); + +/** + * @ignore + */ +var _tempMat1 = new Matrix4(); + +/** + * @ignore + */ +var _tempMat2 = new Matrix4(); + +/** + * @ignore + */ +var _x = new Vector3(); + +/** + * @ignore + */ +var _y = new Vector3(); + +/** + * @ignore + */ +var _z = new Vector3(); + +module.exports = Matrix4; + + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + "use strict"; /** * @author Richard Davey @@ -17077,7 +17183,7 @@ module.exports = earcut; /***/ }), -/* 68 */ +/* 69 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -17121,7 +17227,7 @@ module.exports = { /***/ }), -/* 69 */ +/* 70 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -17395,7 +17501,7 @@ module.exports = ImageFile; /***/ }), -/* 70 */ +/* 71 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -17411,11 +17517,11 @@ var Body = {}; module.exports = Body; -var Vertices = __webpack_require__(93); -var Vector = __webpack_require__(114); +var Vertices = __webpack_require__(94); +var Vector = __webpack_require__(116); var Sleeping = __webpack_require__(267); var Common = __webpack_require__(50); -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); var Axes = __webpack_require__(585); (function() { @@ -18777,7 +18883,7 @@ var Axes = __webpack_require__(585); /***/ }), -/* 71 */ +/* 72 */ /***/ (function(module, exports) { /** @@ -18811,112 +18917,6 @@ var SetTileCollision = function (tile, collides) module.exports = SetTileCollision; -/***/ }), -/* 72 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 Point Light Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - POINTLIGHT_PIPELINE: 'PointLightPipeline', - - /** - * 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', - - /** - * The Graphics and Shapes Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - GRAPHICS_PIPELINE: 'GraphicsPipeline', - - /** - * The Post FX Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - POSTFX_PIPELINE: 'PostFXPipeline', - - /** - * The Utility Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - UTILITY_PIPELINE: 'UtilityPipeline' -}; - -module.exports = PIPELINE_CONST; - - /***/ }), /* 73 */ /***/ (function(module, exports, __webpack_require__) { @@ -18927,7 +18927,7 @@ module.exports = PIPELINE_CONST; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(161); +var AnimationState = __webpack_require__(162); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); @@ -19797,7 +19797,7 @@ module.exports = StableSort; */ var EaseMap = __webpack_require__(132); -var UppercaseFirst = __webpack_require__(200); +var UppercaseFirst = __webpack_require__(202); /** * This internal function is used to return the correct ease function for a Tween. @@ -19979,12 +19979,12 @@ module.exports = StrokePathWebGL; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(110); -var GetPoint = __webpack_require__(454); -var GetPoints = __webpack_require__(455); +var Contains = __webpack_require__(112); +var GetPoint = __webpack_require__(470); +var GetPoints = __webpack_require__(471); var GEOM_CONST = __webpack_require__(55); var Line = __webpack_require__(45); -var Random = __webpack_require__(177); +var Random = __webpack_require__(178); /** * @classdesc @@ -20428,7 +20428,7 @@ module.exports = Triangle; var CONST = __webpack_require__(29); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var Rectangle = __webpack_require__(480); +var Rectangle = __webpack_require__(496); /** * @classdesc @@ -21454,6 +21454,30 @@ module.exports = SetCenterY; /* 88 */ /***/ (function(module, exports, __webpack_require__) { +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Events + */ + +module.exports = { + + POST_RENDER: __webpack_require__(626), + PRE_RENDER: __webpack_require__(627), + RENDER: __webpack_require__(628), + RESIZE: __webpack_require__(629) + +}; + + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + /** * @author Richard Davey * @copyright 2020 Photon Storm Ltd. @@ -21540,7 +21564,7 @@ module.exports = Remove; /***/ }), -/* 89 */ +/* 90 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -21550,7 +21574,7 @@ module.exports = Remove; */ var Class = __webpack_require__(0); -var FromPoints = __webpack_require__(194); +var FromPoints = __webpack_require__(196); var Rectangle = __webpack_require__(10); var Vector2 = __webpack_require__(3); @@ -22157,7 +22181,7 @@ module.exports = Curve; /***/ }), -/* 90 */ +/* 91 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -22187,7 +22211,7 @@ module.exports = { /***/ }), -/* 91 */ +/* 92 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -22263,7 +22287,7 @@ module.exports = LineToLine; /***/ }), -/* 92 */ +/* 93 */ /***/ (function(module, exports) { /** @@ -22291,7 +22315,7 @@ module.exports = Angle; /***/ }), -/* 93 */ +/* 94 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -22308,7 +22332,7 @@ var Vertices = {}; module.exports = Vertices; -var Vector = __webpack_require__(114); +var Vector = __webpack_require__(116); var Common = __webpack_require__(50); (function() { @@ -22751,30 +22775,6 @@ var Common = __webpack_require__(50); })(); -/***/ }), -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Renderer.Events - */ - -module.exports = { - - POST_RENDER: __webpack_require__(626), - PRE_RENDER: __webpack_require__(627), - RENDER: __webpack_require__(628), - RESIZE: __webpack_require__(629) - -}; - - /***/ }), /* 95 */ /***/ (function(module, exports, __webpack_require__) { @@ -22785,7 +22785,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); /** * Return a value based on the range between `min` and `max` and the percentage given. @@ -24372,6 +24372,638 @@ module.exports = { /***/ }), /* 104 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WEBGL_CONST = { + + /** + * 8-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.BYTE + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + BYTE: { enum: 0x1400, size: 1 }, + + /** + * 8-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_BYTE + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_BYTE: { enum: 0x1401, size: 1 }, + + /** + * 16-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.SHORT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + SHORT: { enum: 0x1402, size: 2 }, + + /** + * 16-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_SHORT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_SHORT: { enum: 0x1403, size: 2 }, + + /** + * 32-bit twos complement signed integer. + * + * @name Phaser.Renderer.WebGL.INT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + INT: { enum: 0x1404, size: 4 }, + + /** + * 32-bit twos complement unsigned integer. + * + * @name Phaser.Renderer.WebGL.UNSIGNED_INT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + UNSIGNED_INT: { enum: 0x1405, size: 4 }, + + /** + * 32-bit IEEE floating point number. + * + * @name Phaser.Renderer.WebGL.FLOAT + * @type {Phaser.Types.Renderer.WebGL.WebGLConst} + * @since 3.50.0 + */ + FLOAT: { enum: 0x1406, size: 4 } + +}; + +module.exports = WEBGL_CONST; + + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); +var ShaderSourceFS = __webpack_require__(874); +var ShaderSourceVS = __webpack_require__(875); +var TransformMatrix = __webpack_require__(25); +var Utils = __webpack_require__(12); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); + +/** + * @classdesc + * + * The Multi Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL. + * Virtually all Game Objects use this pipeline by default, including Sprites, Graphics + * and Tilemaps. It handles the batching of quads and tris, as well as methods for + * drawing and batching geometry data. + * + * Prior to Phaser v3.50 this pipeline was called the `TextureTintPipeline`. + * + * In previous versions of Phaser only one single texture unit was supported at any one time. + * The Multi Pipeline is an evolution of the old Texture Tint Pipeline, updated to support + * multi-textures for increased performance. + * + * The fragment shader it uses can be found in `shaders/src/Multi.frag`. + * The vertex shader it uses can be found in `shaders/src/Multi.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * `inTexId` (float, offset 16) + * `inTintEffect` (float, offset 20) + * `inTint` (vec4, offset 24, normalized) + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uMainSampler` (sampler2D array) + * + * If you wish to create a custom pipeline extending from this one, you can use two string + * declarations in your fragment shader source: `%count%` and `%forloop%`, where `count` is + * used to set the number of `sampler2Ds` available, and `forloop` is a block of GLSL code + * that will get the currently bound texture unit. + * + * This pipeline will automatically inject that code for you, should those values exist + * in your shader source. If you wish to handle this yourself, you can also use the + * function `Utils.parseFragmentShaderMaxTextures`. + * + * If you wish to create a pipeline that works from a single texture, or that doesn't have + * internal texture iteration, please see the `SinglePipeline` instead. + * + * @class MultiPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var MultiPipeline = new Class({ + + Extends: WebGLPipeline, + + initialize: + + function MultiPipeline (config) + { + var renderer = config.game.renderer; + + var fragmentShaderSource = GetFastValue(config, 'fragShader', ShaderSourceFS); + + config.fragShader = Utils.parseFragmentShaderMaxTextures(fragmentShaderSource, renderer.maxTextures); + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inTexCoord', + size: 2 + }, + { + name: 'inTexId' + }, + { + name: 'inTintEffect' + }, + { + name: 'inTint', + size: 4, + type: WEBGL_CONST.UNSIGNED_BYTE, + normalized: true + } + ]); + + WebGLPipeline.call(this, config); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix1 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix1 = new TransformMatrix(); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix2 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix3 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix3 = new TransformMatrix(); + }, + + /** + * Called every time the pipeline is bound by the renderer. + * Sets the shader program, vertex buffer and other resources. + * Should only be called when changing pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#bind + * @since 3.50.0 + * + * @return {this} This WebGLPipeline instance. + */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); + }, + + /** + * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchSprite + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set. + */ + batchSprite: function (gameObject, camera, parentTransformMatrix) + { + this.manager.set(this, gameObject); + + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; + var calcMatrix = this._tempMatrix3; + + var frame = gameObject.frame; + var texture = frame.glTexture; + + var u0 = frame.u0; + var v0 = frame.v0; + var u1 = frame.u1; + var v1 = frame.v1; + var frameX = frame.x; + var frameY = frame.y; + var frameWidth = frame.cutWidth; + var frameHeight = frame.cutHeight; + var customPivot = frame.customPivot; + + var displayOriginX = gameObject.displayOriginX; + var displayOriginY = gameObject.displayOriginY; + + var x = -displayOriginX + frameX; + var y = -displayOriginY + frameY; + + if (gameObject.isCropped) + { + var crop = gameObject._crop; + + if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) + { + frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); + } + + u0 = crop.u0; + v0 = crop.v0; + u1 = crop.u1; + v1 = crop.v1; + + frameWidth = crop.width; + frameHeight = crop.height; + + frameX = crop.x; + frameY = crop.y; + + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } + + var flipX = 1; + var flipY = 1; + + if (gameObject.flipX) + { + if (!customPivot) + { + x += (-frame.realWidth + (displayOriginX * 2)); + } + + flipX = -1; + } + + // Auto-invert the flipY if this is coming from a GLTexture + + if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) + { + if (!customPivot) + { + y += (-frame.realHeight + (displayOriginY * 2)); + } + + flipY = -1; + } + + spriteMatrix.applyITRS(gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); + + camMatrix.copyFrom(camera.matrix); + + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); + + // Undo the camera scroll + spriteMatrix.e = gameObject.x; + spriteMatrix.f = gameObject.y; + } + else + { + spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX; + spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY; + } + + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + + var xw = x + frameWidth; + var yh = y + frameHeight; + + var roundPixels = camera.roundPixels; + + var tx0 = calcMatrix.getXRound(x, y, roundPixels); + var ty0 = calcMatrix.getYRound(x, y, roundPixels); + + var tx1 = calcMatrix.getXRound(x, yh, roundPixels); + var ty1 = calcMatrix.getYRound(x, yh, roundPixels); + + var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); + var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); + + var tx3 = calcMatrix.getXRound(xw, y, roundPixels); + var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + + var getTint = Utils.getTintAppendFloatAlpha; + var cameraAlpha = camera.alpha; + + var tintTL = getTint(gameObject.tintTopLeft, cameraAlpha * gameObject._alphaTL); + var tintTR = getTint(gameObject.tintTopRight, cameraAlpha * gameObject._alphaTR); + var tintBL = getTint(gameObject.tintBottomLeft, cameraAlpha * gameObject._alphaBL); + var tintBR = getTint(gameObject.tintBottomRight, cameraAlpha * gameObject._alphaBR); + + if (this.shouldFlush(6)) + { + this.flush(); + } + + var unit = this.setGameObject(gameObject, frame); + + this.manager.preBatch(gameObject); + + this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); + + this.manager.postBatch(gameObject); + }, + + /** + * Generic function for batching a textured quad using argument values instead of a Game Object. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTexture + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject. + * @param {WebGLTexture} texture - Raw WebGLTexture associated with the quad. + * @param {number} textureWidth - Real texture width. + * @param {number} textureHeight - Real texture height. + * @param {number} srcX - X coordinate of the quad. + * @param {number} srcY - Y coordinate of the quad. + * @param {number} srcWidth - Width of the quad. + * @param {number} srcHeight - Height of the quad. + * @param {number} scaleX - X component of scale. + * @param {number} scaleY - Y component of scale. + * @param {number} rotation - Rotation of the quad. + * @param {boolean} flipX - Indicates if the quad is horizontally flipped. + * @param {boolean} flipY - Indicates if the quad is vertically flipped. + * @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll. + * @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll. + * @param {number} displayOriginX - Horizontal origin in pixels. + * @param {number} displayOriginY - Vertical origin in pixels. + * @param {number} frameX - X coordinate of the texture frame. + * @param {number} frameY - Y coordinate of the texture frame. + * @param {number} frameWidth - Width of the texture frame. + * @param {number} frameHeight - Height of the texture frame. + * @param {number} tintTL - Tint for top left. + * @param {number} tintTR - Tint for top right. + * @param {number} tintBL - Tint for bottom left. + * @param {number} tintBR - Tint for bottom right. + * @param {number} tintEffect - The tint effect. + * @param {number} uOffset - Horizontal offset on texture coordinate. + * @param {number} vOffset - Vertical offset on texture coordinate. + * @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container. + * @param {boolean} [skipFlip=false] - Skip the renderTexture check. + * @param {number} [textureUnit] - Use the currently bound texture unit? + */ + batchTexture: function ( + gameObject, + texture, + textureWidth, textureHeight, + srcX, srcY, + srcWidth, srcHeight, + scaleX, scaleY, + rotation, + flipX, flipY, + scrollFactorX, scrollFactorY, + displayOriginX, displayOriginY, + frameX, frameY, frameWidth, frameHeight, + tintTL, tintTR, tintBL, tintBR, tintEffect, + uOffset, vOffset, + camera, + parentTransformMatrix, + skipFlip, + textureUnit) + { + this.manager.set(this, gameObject); + + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; + var calcMatrix = this._tempMatrix3; + + var u0 = (frameX / textureWidth) + uOffset; + var v0 = (frameY / textureHeight) + vOffset; + var u1 = (frameX + frameWidth) / textureWidth + uOffset; + var v1 = (frameY + frameHeight) / textureHeight + vOffset; + + var width = srcWidth; + var height = srcHeight; + + var x = -displayOriginX; + var y = -displayOriginY; + + if (gameObject.isCropped) + { + var crop = gameObject._crop; + + var cropWidth = crop.width; + var cropHeight = crop.height; + + width = cropWidth; + height = cropHeight; + + srcWidth = cropWidth; + srcHeight = cropHeight; + + frameX = crop.x; + frameY = crop.y; + + var ox = frameX; + var oy = frameY; + + if (flipX) + { + ox = (frameWidth - crop.x - cropWidth); + } + + if (flipY) + { + oy = (frameHeight - crop.y - cropHeight); + } + + u0 = (ox / textureWidth) + uOffset; + v0 = (oy / textureHeight) + vOffset; + u1 = (ox + cropWidth) / textureWidth + uOffset; + v1 = (oy + cropHeight) / textureHeight + vOffset; + + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } + + // Invert the flipY if this is a RenderTexture + flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0); + + if (flipX) + { + width *= -1; + x += srcWidth; + } + + if (flipY) + { + height *= -1; + y += srcHeight; + } + + var xw = x + width; + var yh = y + height; + + spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); + + camMatrix.copyFrom(camera.matrix); + + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); + + // Undo the camera scroll + spriteMatrix.e = srcX; + spriteMatrix.f = srcY; + } + else + { + spriteMatrix.e -= camera.scrollX * scrollFactorX; + spriteMatrix.f -= camera.scrollY * scrollFactorY; + } + + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + + var roundPixels = camera.roundPixels; + + var tx0 = calcMatrix.getXRound(x, y, roundPixels); + var ty0 = calcMatrix.getYRound(x, y, roundPixels); + + var tx1 = calcMatrix.getXRound(x, yh, roundPixels); + var ty1 = calcMatrix.getYRound(x, yh, roundPixels); + + var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); + var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); + + var tx3 = calcMatrix.getXRound(xw, y, roundPixels); + var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + + if (textureUnit === undefined) + { + textureUnit = this.renderer.setTexture2D(texture); + } + + if (gameObject) + { + this.manager.preBatch(gameObject); + } + + this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); + + if (gameObject) + { + this.manager.postBatch(gameObject); + } + }, + + /** + * Adds a Texture Frame into the batch for rendering. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTextureFrame + * @since 3.12.0 + * + * @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered. + * @param {number} x - The horizontal position to render the texture at. + * @param {number} y - The vertical position to render the texture at. + * @param {number} tint - The tint color. + * @param {number} alpha - The alpha value. + * @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix. + */ + batchTextureFrame: function ( + frame, + x, y, + tint, alpha, + transformMatrix, + parentTransformMatrix + ) + { + this.manager.set(this); + + var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); + var calcMatrix = this._tempMatrix2; + + var xw = x + frame.width; + var yh = y + frame.height; + + if (parentTransformMatrix) + { + spriteMatrix.multiply(parentTransformMatrix, calcMatrix); + } + else + { + calcMatrix = spriteMatrix; + } + + var tx0 = calcMatrix.getX(x, y); + var ty0 = calcMatrix.getY(x, y); + + var tx1 = calcMatrix.getX(x, yh); + var ty1 = calcMatrix.getY(x, yh); + + var tx2 = calcMatrix.getX(xw, yh); + var ty2 = calcMatrix.getY(xw, yh); + + var tx3 = calcMatrix.getX(xw, y); + var ty3 = calcMatrix.getY(xw, y); + + var unit = this.renderer.setTextureSource(frame.source); + + tint = Utils.getTintAppendFloatAlpha(tint, alpha); + + this.batchQuad(null, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit); + } + +}); + +module.exports = MultiPipeline; + + +/***/ }), +/* 106 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -24381,8 +25013,8 @@ module.exports = { */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); -var Extend = __webpack_require__(19); +var Clamp = __webpack_require__(18); +var Extend = __webpack_require__(17); /** * @classdesc @@ -25228,7 +25860,7 @@ module.exports = Frame; /***/ }), -/* 105 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -25237,7 +25869,7 @@ module.exports = Frame; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(203); +var ArrayUtils = __webpack_require__(205); var Class = __webpack_require__(0); var NOOP = __webpack_require__(1); var StableSort = __webpack_require__(79); @@ -26044,7 +26676,7 @@ module.exports = List; /***/ }), -/* 106 */ +/* 108 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -26054,11 +26686,11 @@ module.exports = List; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(107); -var GetPoint = __webpack_require__(423); -var GetPoints = __webpack_require__(424); +var Contains = __webpack_require__(109); +var GetPoint = __webpack_require__(439); +var GetPoints = __webpack_require__(440); var GEOM_CONST = __webpack_require__(55); -var Random = __webpack_require__(176); +var Random = __webpack_require__(177); /** * @classdesc @@ -26426,7 +27058,7 @@ module.exports = Ellipse; /***/ }), -/* 107 */ +/* 109 */ /***/ (function(module, exports) { /** @@ -26468,7 +27100,7 @@ module.exports = Contains; /***/ }), -/* 108 */ +/* 110 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -26481,12 +27113,12 @@ var Actions = __webpack_require__(269); var Class = __webpack_require__(0); var Events = __webpack_require__(75); var EventEmitter = __webpack_require__(9); -var GetAll = __webpack_require__(202); +var GetAll = __webpack_require__(204); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var IsPlainObject = __webpack_require__(7); -var Range = __webpack_require__(415); -var Set = __webpack_require__(147); +var Range = __webpack_require__(431); +var Set = __webpack_require__(148); var Sprite = __webpack_require__(73); /** @@ -28196,7 +28828,7 @@ module.exports = Group; /***/ }), -/* 109 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -28258,7 +28890,7 @@ module.exports = FillPathWebGL; /***/ }), -/* 110 */ +/* 112 */ /***/ (function(module, exports) { /** @@ -28311,7 +28943,7 @@ module.exports = Contains; /***/ }), -/* 111 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -28322,7 +28954,7 @@ module.exports = Contains; var Class = __webpack_require__(0); var Rectangle = __webpack_require__(10); -var RectangleToRectangle = __webpack_require__(112); +var RectangleToRectangle = __webpack_require__(114); var Vector2 = __webpack_require__(3); /** @@ -28875,7 +29507,7 @@ module.exports = Face; /***/ }), -/* 112 */ +/* 114 */ /***/ (function(module, exports) { /** @@ -28913,7 +29545,7 @@ module.exports = RectangleToRectangle; /***/ }), -/* 113 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -28924,7 +29556,7 @@ module.exports = RectangleToRectangle; var Class = __webpack_require__(0); var Utils = __webpack_require__(12); -var Vector3 = __webpack_require__(36); +var Vector3 = __webpack_require__(37); /** * @classdesc @@ -29208,7 +29840,7 @@ module.exports = Vertex; /***/ }), -/* 114 */ +/* 116 */ /***/ (function(module, exports) { /** @@ -29452,7 +30084,7 @@ module.exports = Vector; })(); /***/ }), -/* 115 */ +/* 117 */ /***/ (function(module, exports) { /** @@ -29578,7 +30210,7 @@ module.exports = Bounds; /***/ }), -/* 116 */ +/* 118 */ /***/ (function(module, exports) { /** @@ -29608,7 +30240,7 @@ module.exports = IsInLayerBounds; /***/ }), -/* 117 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -29848,7 +30480,7 @@ module.exports = LayerData; /***/ }), -/* 118 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -30084,7 +30716,7 @@ module.exports = MapData; /***/ }), -/* 119 */ +/* 121 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -30488,7 +31120,7 @@ module.exports = Tileset; /***/ }), -/* 120 */ +/* 122 */ /***/ (function(module, exports) { /** @@ -30622,7 +31254,7 @@ module.exports = ALIGN_CONST; /***/ }), -/* 121 */ +/* 123 */ /***/ (function(module, exports) { /** @@ -30655,638 +31287,6 @@ var Equal = function (a, b, epsilon) module.exports = Equal; -/***/ }), -/* 122 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var WEBGL_CONST = { - - /** - * 8-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.BYTE - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - BYTE: { enum: 0x1400, size: 1 }, - - /** - * 8-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_BYTE - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_BYTE: { enum: 0x1401, size: 1 }, - - /** - * 16-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.SHORT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - SHORT: { enum: 0x1402, size: 2 }, - - /** - * 16-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_SHORT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_SHORT: { enum: 0x1403, size: 2 }, - - /** - * 32-bit twos complement signed integer. - * - * @name Phaser.Renderer.WebGL.INT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - INT: { enum: 0x1404, size: 4 }, - - /** - * 32-bit twos complement unsigned integer. - * - * @name Phaser.Renderer.WebGL.UNSIGNED_INT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - UNSIGNED_INT: { enum: 0x1405, size: 4 }, - - /** - * 32-bit IEEE floating point number. - * - * @name Phaser.Renderer.WebGL.FLOAT - * @type {Phaser.Types.Renderer.WebGL.WebGLConst} - * @since 3.50.0 - */ - FLOAT: { enum: 0x1406, size: 4 } - -}; - -module.exports = WEBGL_CONST; - - -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(874); -var ShaderSourceVS = __webpack_require__(875); -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); - -/** - * @classdesc - * - * The Multi Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL. - * Virtually all Game Objects use this pipeline by default, including Sprites, Graphics - * and Tilemaps. It handles the batching of quads and tris, as well as methods for - * drawing and batching geometry data. - * - * Prior to Phaser v3.50 this pipeline was called the `TextureTintPipeline`. - * - * In previous versions of Phaser only one single texture unit was supported at any one time. - * The Multi Pipeline is an evolution of the old Texture Tint Pipeline, updated to support - * multi-textures for increased performance. - * - * The fragment shader it uses can be found in `shaders/src/Multi.frag`. - * The vertex shader it uses can be found in `shaders/src/Multi.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) - * `inTexId` (float, offset 16) - * `inTintEffect` (float, offset 20) - * `inTint` (vec4, offset 24, normalized) - * - * The default shader uniforms for this pipeline are: - * - * `uProjectionMatrix` (mat4) - * `uMainSampler` (sampler2D array) - * - * If you wish to create a custom pipeline extending from this one, you can use two string - * declarations in your fragment shader source: `%count%` and `%forloop%`, where `count` is - * used to set the number of `sampler2Ds` available, and `forloop` is a block of GLSL code - * that will get the currently bound texture unit. - * - * This pipeline will automatically inject that code for you, should those values exist - * in your shader source. If you wish to handle this yourself, you can also use the - * function `Utils.parseFragmentShaderMaxTextures`. - * - * If you wish to create a pipeline that works from a single texture, or that doesn't have - * internal texture iteration, please see the `SinglePipeline` instead. - * - * @class MultiPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. - */ -var MultiPipeline = new Class({ - - Extends: WebGLPipeline, - - initialize: - - function MultiPipeline (config) - { - var renderer = config.game.renderer; - - var fragmentShaderSource = GetFastValue(config, 'fragShader', ShaderSourceFS); - - config.fragShader = Utils.parseFragmentShaderMaxTextures(fragmentShaderSource, renderer.maxTextures); - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inTexCoord', - size: 2 - }, - { - name: 'inTexId' - }, - { - name: 'inTintEffect' - }, - { - name: 'inTint', - size: 4, - type: WEBGL_CONST.UNSIGNED_BYTE, - normalized: true - } - ]); - - WebGLPipeline.call(this, config); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix1 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix1 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix2 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#_tempMatrix3 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 - */ - this._tempMatrix3 = new TransformMatrix(); - }, - - /** - * Called every time the pipeline is bound by the renderer. - * Sets the shader program, vertex buffer and other resources. - * Should only be called when changing pipeline. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#bind - * @since 3.50.0 - * - * @return {this} This WebGLPipeline instance. - */ - boot: function () - { - WebGLPipeline.prototype.boot.call(this); - - this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); - }, - - /** - * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchSprite - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set. - */ - batchSprite: function (gameObject, camera, parentTransformMatrix) - { - this.manager.set(this, gameObject); - - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; - - var frame = gameObject.frame; - var texture = frame.glTexture; - - var u0 = frame.u0; - var v0 = frame.v0; - var u1 = frame.u1; - var v1 = frame.v1; - var frameX = frame.x; - var frameY = frame.y; - var frameWidth = frame.cutWidth; - var frameHeight = frame.cutHeight; - var customPivot = frame.customPivot; - - var displayOriginX = gameObject.displayOriginX; - var displayOriginY = gameObject.displayOriginY; - - var x = -displayOriginX + frameX; - var y = -displayOriginY + frameY; - - if (gameObject.isCropped) - { - var crop = gameObject._crop; - - if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) - { - frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); - } - - u0 = crop.u0; - v0 = crop.v0; - u1 = crop.u1; - v1 = crop.v1; - - frameWidth = crop.width; - frameHeight = crop.height; - - frameX = crop.x; - frameY = crop.y; - - x = -displayOriginX + frameX; - y = -displayOriginY + frameY; - } - - var flipX = 1; - var flipY = 1; - - if (gameObject.flipX) - { - if (!customPivot) - { - x += (-frame.realWidth + (displayOriginX * 2)); - } - - flipX = -1; - } - - // Auto-invert the flipY if this is coming from a GLTexture - - if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) - { - if (!customPivot) - { - y += (-frame.realHeight + (displayOriginY * 2)); - } - - flipY = -1; - } - - spriteMatrix.applyITRS(gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); - - camMatrix.copyFrom(camera.matrix); - - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); - - // Undo the camera scroll - spriteMatrix.e = gameObject.x; - spriteMatrix.f = gameObject.y; - } - else - { - spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX; - spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY; - } - - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(spriteMatrix, calcMatrix); - - var xw = x + frameWidth; - var yh = y + frameHeight; - - var roundPixels = camera.roundPixels; - - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); - - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); - - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); - - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); - - var getTint = Utils.getTintAppendFloatAlpha; - var cameraAlpha = camera.alpha; - - var tintTL = getTint(gameObject.tintTopLeft, cameraAlpha * gameObject._alphaTL); - var tintTR = getTint(gameObject.tintTopRight, cameraAlpha * gameObject._alphaTR); - var tintBL = getTint(gameObject.tintBottomLeft, cameraAlpha * gameObject._alphaBL); - var tintBR = getTint(gameObject.tintBottomRight, cameraAlpha * gameObject._alphaBR); - - if (this.shouldFlush(6)) - { - this.flush(); - } - - var unit = this.setGameObject(gameObject, frame); - - this.manager.preBatch(gameObject); - - this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); - - this.manager.postBatch(gameObject); - }, - - /** - * Generic function for batching a textured quad using argument values instead of a Game Object. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTexture - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject. - * @param {WebGLTexture} texture - Raw WebGLTexture associated with the quad. - * @param {number} textureWidth - Real texture width. - * @param {number} textureHeight - Real texture height. - * @param {number} srcX - X coordinate of the quad. - * @param {number} srcY - Y coordinate of the quad. - * @param {number} srcWidth - Width of the quad. - * @param {number} srcHeight - Height of the quad. - * @param {number} scaleX - X component of scale. - * @param {number} scaleY - Y component of scale. - * @param {number} rotation - Rotation of the quad. - * @param {boolean} flipX - Indicates if the quad is horizontally flipped. - * @param {boolean} flipY - Indicates if the quad is vertically flipped. - * @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll. - * @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll. - * @param {number} displayOriginX - Horizontal origin in pixels. - * @param {number} displayOriginY - Vertical origin in pixels. - * @param {number} frameX - X coordinate of the texture frame. - * @param {number} frameY - Y coordinate of the texture frame. - * @param {number} frameWidth - Width of the texture frame. - * @param {number} frameHeight - Height of the texture frame. - * @param {number} tintTL - Tint for top left. - * @param {number} tintTR - Tint for top right. - * @param {number} tintBL - Tint for bottom left. - * @param {number} tintBR - Tint for bottom right. - * @param {number} tintEffect - The tint effect. - * @param {number} uOffset - Horizontal offset on texture coordinate. - * @param {number} vOffset - Vertical offset on texture coordinate. - * @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container. - * @param {boolean} [skipFlip=false] - Skip the renderTexture check. - * @param {number} [textureUnit] - Use the currently bound texture unit? - */ - batchTexture: function ( - gameObject, - texture, - textureWidth, textureHeight, - srcX, srcY, - srcWidth, srcHeight, - scaleX, scaleY, - rotation, - flipX, flipY, - scrollFactorX, scrollFactorY, - displayOriginX, displayOriginY, - frameX, frameY, frameWidth, frameHeight, - tintTL, tintTR, tintBL, tintBR, tintEffect, - uOffset, vOffset, - camera, - parentTransformMatrix, - skipFlip, - textureUnit) - { - this.manager.set(this, gameObject); - - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; - - var u0 = (frameX / textureWidth) + uOffset; - var v0 = (frameY / textureHeight) + vOffset; - var u1 = (frameX + frameWidth) / textureWidth + uOffset; - var v1 = (frameY + frameHeight) / textureHeight + vOffset; - - var width = srcWidth; - var height = srcHeight; - - var x = -displayOriginX; - var y = -displayOriginY; - - if (gameObject.isCropped) - { - var crop = gameObject._crop; - - var cropWidth = crop.width; - var cropHeight = crop.height; - - width = cropWidth; - height = cropHeight; - - srcWidth = cropWidth; - srcHeight = cropHeight; - - frameX = crop.x; - frameY = crop.y; - - var ox = frameX; - var oy = frameY; - - if (flipX) - { - ox = (frameWidth - crop.x - cropWidth); - } - - if (flipY) - { - oy = (frameHeight - crop.y - cropHeight); - } - - u0 = (ox / textureWidth) + uOffset; - v0 = (oy / textureHeight) + vOffset; - u1 = (ox + cropWidth) / textureWidth + uOffset; - v1 = (oy + cropHeight) / textureHeight + vOffset; - - x = -displayOriginX + frameX; - y = -displayOriginY + frameY; - } - - // Invert the flipY if this is a RenderTexture - flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0); - - if (flipX) - { - width *= -1; - x += srcWidth; - } - - if (flipY) - { - height *= -1; - y += srcHeight; - } - - var xw = x + width; - var yh = y + height; - - spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); - - camMatrix.copyFrom(camera.matrix); - - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); - - // Undo the camera scroll - spriteMatrix.e = srcX; - spriteMatrix.f = srcY; - } - else - { - spriteMatrix.e -= camera.scrollX * scrollFactorX; - spriteMatrix.f -= camera.scrollY * scrollFactorY; - } - - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(spriteMatrix, calcMatrix); - - var roundPixels = camera.roundPixels; - - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); - - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); - - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); - - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); - - if (textureUnit === undefined) - { - textureUnit = this.renderer.setTexture2D(texture); - } - - if (gameObject) - { - this.manager.preBatch(gameObject); - } - - this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); - - if (gameObject) - { - this.manager.postBatch(gameObject); - } - }, - - /** - * Adds a Texture Frame into the batch for rendering. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTextureFrame - * @since 3.12.0 - * - * @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered. - * @param {number} x - The horizontal position to render the texture at. - * @param {number} y - The vertical position to render the texture at. - * @param {number} tint - The tint color. - * @param {number} alpha - The alpha value. - * @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix. - */ - batchTextureFrame: function ( - frame, - x, y, - tint, alpha, - transformMatrix, - parentTransformMatrix - ) - { - this.manager.set(this); - - var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); - var calcMatrix = this._tempMatrix2; - - var xw = x + frame.width; - var yh = y + frame.height; - - if (parentTransformMatrix) - { - spriteMatrix.multiply(parentTransformMatrix, calcMatrix); - } - else - { - calcMatrix = spriteMatrix; - } - - var tx0 = calcMatrix.getX(x, y); - var ty0 = calcMatrix.getY(x, y); - - var tx1 = calcMatrix.getX(x, yh); - var ty1 = calcMatrix.getY(x, yh); - - var tx2 = calcMatrix.getX(xw, yh); - var ty2 = calcMatrix.getY(xw, yh); - - var tx3 = calcMatrix.getX(xw, y); - var ty3 = calcMatrix.getY(xw, y); - - var unit = this.renderer.setTextureSource(frame.source); - - tint = Utils.getTintAppendFloatAlpha(tint, alpha); - - this.batchQuad(null, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit); - } - -}); - -module.exports = MultiPipeline; - - /***/ }), /* 124 */ /***/ (function(module, exports, __webpack_require__) { @@ -31436,12 +31436,12 @@ var Bodies = {}; module.exports = Bodies; -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); var Common = __webpack_require__(50); -var Body = __webpack_require__(70); -var Bounds = __webpack_require__(115); -var Vector = __webpack_require__(114); -var decomp = __webpack_require__(1480); +var Body = __webpack_require__(71); +var Bounds = __webpack_require__(117); +var Vector = __webpack_require__(116); +var decomp = __webpack_require__(1487); (function() { @@ -31785,9 +31785,9 @@ var decomp = __webpack_require__(1480); * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); -var Circle = __webpack_require__(61); -var CircleContains = __webpack_require__(62); +var BlendModes = __webpack_require__(33); +var Circle = __webpack_require__(62); +var CircleContains = __webpack_require__(63); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); @@ -32200,12 +32200,12 @@ module.exports = { var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Rectangle = __webpack_require__(10); var TransformMatrix = __webpack_require__(25); -var ValueToColor = __webpack_require__(183); +var ValueToColor = __webpack_require__(184); var Vector2 = __webpack_require__(3); /** @@ -34997,6 +34997,363 @@ module.exports = Vector4; /***/ }), /* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(88); + +/** + * @classdesc + * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. + * + * Instances of this class are typically created by, and belong to WebGL Pipelines, however + * other Game Objects and classes can take advantage of Render Targets as well. + * + * @class RenderTarget + * @memberof Phaser.Renderer.WebGL + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGLRenderer. + * @param {number} width - The width of this Render Target. + * @param {number} height - The height of this Render Target. + * @param {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. + * @param {number} [minFilter=0] - The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`. + * @param {boolean} [autoClear=true] - Automatically clear this framebuffer when bound? + * @param {boolean} [autoResize=false] - Automatically resize this Render Target if the WebGL Renderer resizes? + */ +var RenderTarget = new Class({ + + initialize: + + function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize) + { + if (scale === undefined) { scale = 1; } + if (minFilter === undefined) { minFilter = 0; } + if (autoClear === undefined) { autoClear = true; } + if (autoResize === undefined) { autoResize = false; } + + /** + * A reference to the WebGLRenderer instance. + * + * @name Phaser.Renderer.WebGL.RenderTarget#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.50.0 + */ + this.renderer = renderer; + + /** + * The WebGLFramebuffer of this Render Target. + * + * This is created in the `RenderTarget.resize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#framebuffer + * @type {WebGLFramebuffer} + * @since 3.50.0 + */ + this.framebuffer = null; + + /** + * The WebGLTexture of this Render Target. + * + * This is created in the `RenderTarget.resize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#texture + * @type {WebGLTexture} + * @since 3.50.0 + */ + this.texture = null; + + /** + * The width of the texture. + * + * @name Phaser.Renderer.WebGL.RenderTarget#width + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.width = 0; + + /** + * The height of the texture. + * + * @name Phaser.Renderer.WebGL.RenderTarget#height + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.height = 0; + + /** + * A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. + * + * A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc. + * + * @name Phaser.Renderer.WebGL.RenderTarget#scale + * @type {number} + * @since 3.50.0 + */ + this.scale = scale; + + /** + * The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`. + * + * @name Phaser.Renderer.WebGL.RenderTarget#minFilter + * @type {number} + * @since 3.50.0 + */ + this.minFilter = minFilter; + + /** + * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) + * during the `RenderTarget.bind` method. + * + * If you need more control over how, or if, the target is cleared, you can disable + * this via the config on creation, or even toggle it directly at runtime. + * + * @name Phaser.Renderer.WebGL.RenderTarget#autoClear + * @type {boolean} + * @since 3.50.0 + */ + this.autoClear = autoClear; + + /** + * Does this Render Target automatically resize when the WebGL Renderer does? + * + * Modify this property via the `setAutoResize` method. + * + * @name Phaser.Renderer.WebGL.RenderTarget#autoResize + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.autoResize = false; + + this.resize(width, height); + + if (autoResize) + { + this.setAutoResize(true); + } + }, + + /** + * Sets if this Render Target should automatically resize when the WebGL Renderer + * emits a resize event. + * + * @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize + * @since 3.50.0 + * + * @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes? + * + * @return {this} This RenderTarget instance. + */ + setAutoResize: function (autoResize) + { + if (autoResize && !this.autoResize) + { + this.renderer.on(Events.RESIZE, this.resize, this); + + this.autoResize = true; + } + else if (!autoResize && this.autoResize) + { + this.renderer.off(Events.RESIZE, this.resize, this); + + this.autoResize = false; + } + + return this; + }, + + /** + * Resizes this Render Target. + * + * Deletes both the frame buffer and texture, if they exist and then re-creates + * them using the new sizes. + * + * This method is called automatically by the pipeline during its resize handler. + * + * @method Phaser.Renderer.WebGL.RenderTarget#resize + * @since 3.50.0 + * + * @param {number} width - The new width of this Render Target. + * @param {number} height - The new height of this Render Target. + * + * @return {this} This RenderTarget instance. + */ + resize: function (width, height) + { + var scaledWidth = width * this.scale; + var scaledHeight = height * this.scale; + + if (scaledWidth !== this.width || scaledHeight !== this.height) + { + var renderer = this.renderer; + + renderer.deleteFramebuffer(this.framebuffer); + + renderer.deleteTexture(this.texture); + + width *= this.scale; + height *= this.scale; + + this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter); + this.framebuffer = renderer.createFramebuffer(width, height, this.texture, false); + + this.width = width; + this.height = height; + } + + return this; + }, + + /** + * Pushes this Render Target as the current frame buffer of the renderer. + * + * If `autoClear` is set, then clears the texture. + * + * If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport. + * + * @method Phaser.Renderer.WebGL.RenderTarget#bind + * @since 3.50.0 + * + * @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ? + * @param {number} [width] - Optional new width of this Render Target. + * @param {number} [height] - Optional new height of this Render Target. + */ + bind: function (adjustViewport, width, height) + { + if (adjustViewport === undefined) { adjustViewport = false; } + + if (adjustViewport) + { + this.renderer.flush(); + } + + if (width && height) + { + this.resize(width, height); + } + + this.renderer.pushFramebuffer(this.framebuffer, false, false, false); + + if (adjustViewport) + { + this.adjustViewport(); + } + + if (this.autoClear) + { + var gl = this.renderer.gl; + + gl.clearColor(0, 0, 0, 0); + + gl.clear(gl.COLOR_BUFFER_BIT); + } + }, + + /** + * Adjusts the GL viewport to match the width and height of this Render Target. + * + * Also disables `SCISSOR_TEST`. + * + * @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport + * @since 3.50.0 + */ + adjustViewport: function () + { + var gl = this.renderer.gl; + + gl.viewport(0, 0, this.width, this.height); + + gl.disable(gl.SCISSOR_TEST); + }, + + /** + * Clears this Render Target. + * + * @method Phaser.Renderer.WebGL.RenderTarget#clear + * @since 3.50.0 + */ + clear: function () + { + var renderer = this.renderer; + var gl = renderer.gl; + + renderer.pushFramebuffer(this.framebuffer); + + gl.disable(gl.SCISSOR_TEST); + + gl.clearColor(0, 0, 0, 0); + + gl.clear(gl.COLOR_BUFFER_BIT); + + renderer.popFramebuffer(); + + renderer.resetScissor(); + }, + + /** + * Unbinds this Render Target and optionally flushes the WebGL Renderer first. + * + * @name Phaser.Renderer.WebGL.RenderTarget#unbind + * @since 3.50.0 + * + * @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding? + * + * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. + */ + unbind: function (flush) + { + if (flush === undefined) { flush = false; } + + var renderer = this.renderer; + + if (flush) + { + renderer.flush(); + } + + return renderer.popFramebuffer(); + }, + + /** + * Removes all external references from this class and deletes the + * WebGL framebuffer and texture instances. + * + * Does not remove this Render Target from the parent pipeline. + * + * @name Phaser.Renderer.WebGL.RenderTarget#destroy + * @since 3.50.0 + */ + destroy: function () + { + var renderer = this.renderer; + + renderer.deleteFramebuffer(this.framebuffer); + renderer.deleteTexture(this.texture); + + renderer.off(Events.RESIZE, this.resize, this); + + this.renderer = null; + this.framebuffer = null; + this.texture = null; + } + +}); + +module.exports = RenderTarget; + + +/***/ }), +/* 140 */ /***/ (function(module, exports) { /** @@ -35054,7 +35411,7 @@ module.exports = AddToDOM; /***/ }), -/* 140 */ +/* 141 */ /***/ (function(module, exports) { /** @@ -35960,7 +36317,7 @@ module.exports = KeyCodes; /***/ }), -/* 141 */ +/* 142 */ /***/ (function(module, exports) { /** @@ -36083,7 +36440,7 @@ module.exports = CONST; /***/ }), -/* 142 */ +/* 143 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36128,7 +36485,7 @@ module.exports = Merge; /***/ }), -/* 143 */ +/* 144 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36141,11 +36498,11 @@ module.exports = Merge; var Class = __webpack_require__(0); var Clone = __webpack_require__(77); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(68); +var Events = __webpack_require__(69); var GameEvents = __webpack_require__(22); var NOOP = __webpack_require__(1); -var GetAll = __webpack_require__(202); -var GetFirst = __webpack_require__(406); +var GetAll = __webpack_require__(204); +var GetFirst = __webpack_require__(422); /** * @classdesc @@ -36842,7 +37199,7 @@ module.exports = BaseSoundManager; /***/ }), -/* 144 */ +/* 145 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -36854,8 +37211,8 @@ module.exports = BaseSoundManager; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(68); -var Extend = __webpack_require__(19); +var Events = __webpack_require__(69); +var Extend = __webpack_require__(17); var NOOP = __webpack_require__(1); /** @@ -37345,7 +37702,7 @@ module.exports = BaseSound; /***/ }), -/* 145 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -37354,8 +37711,8 @@ module.exports = BaseSound; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CheckMatrix = __webpack_require__(204); -var TransposeMatrix = __webpack_require__(413); +var CheckMatrix = __webpack_require__(206); +var TransposeMatrix = __webpack_require__(429); /** * Rotates the array matrix based on the given rotation value. @@ -37431,7 +37788,7 @@ module.exports = RotateMatrix; /***/ }), -/* 146 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -37441,12 +37798,12 @@ module.exports = RotateMatrix; */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var GetBitmapTextSize = __webpack_require__(1037); var ParseFromAtlas = __webpack_require__(1038); -var ParseXMLBitmapFont = __webpack_require__(207); +var ParseXMLBitmapFont = __webpack_require__(209); var Rectangle = __webpack_require__(10); var Render = __webpack_require__(1039); @@ -38520,7 +38877,7 @@ module.exports = BitmapText; /***/ }), -/* 147 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -38969,7 +39326,7 @@ module.exports = Set; /***/ }), -/* 148 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -38981,8 +39338,8 @@ module.exports = Set; var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var IntegerToColor = __webpack_require__(185); -var PIPELINES_CONST = __webpack_require__(72); +var IntegerToColor = __webpack_require__(186); +var PIPELINES_CONST = __webpack_require__(65); var Render = __webpack_require__(1176); /** @@ -39174,7 +39531,7 @@ module.exports = PointLight; /***/ }), -/* 149 */ +/* 150 */ /***/ (function(module, exports) { /** @@ -39228,7 +39585,7 @@ module.exports = CircleToRectangle; /***/ }), -/* 150 */ +/* 151 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39336,7 +39693,7 @@ module.exports = InputPluginCache; /***/ }), -/* 151 */ +/* 152 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39363,7 +39720,7 @@ module.exports = { /***/ }), -/* 152 */ +/* 153 */ /***/ (function(module, exports) { /** @@ -39404,7 +39761,7 @@ module.exports = GetURL; /***/ }), -/* 153 */ +/* 154 */ /***/ (function(module, exports) { /** @@ -39474,7 +39831,7 @@ module.exports = XHRSettings; /***/ }), -/* 154 */ +/* 155 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39484,7 +39841,7 @@ module.exports = XHRSettings; */ var Class = __webpack_require__(0); -var Components = __webpack_require__(238); +var Components = __webpack_require__(240); var Sprite = __webpack_require__(73); /** @@ -39577,7 +39934,7 @@ module.exports = ArcadeSprite; /***/ }), -/* 155 */ +/* 156 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39586,7 +39943,7 @@ module.exports = ArcadeSprite; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var IsInLayerBounds = __webpack_require__(116); +var IsInLayerBounds = __webpack_require__(118); /** * Gets a tile at the given tile coordinates from the given layer. @@ -39632,7 +39989,7 @@ module.exports = GetTileAt; /***/ }), -/* 156 */ +/* 157 */ /***/ (function(module, exports) { /** @@ -39758,7 +40115,7 @@ module.exports = RunCull; /***/ }), -/* 157 */ +/* 158 */ /***/ (function(module, exports) { /** @@ -39796,7 +40153,7 @@ module.exports = SetLayerCollisionIndex; /***/ }), -/* 158 */ +/* 159 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39857,7 +40214,7 @@ module.exports = CreateGroupLayer; /***/ }), -/* 159 */ +/* 160 */ /***/ (function(module, exports) { /** @@ -39921,7 +40278,7 @@ module.exports = GetNewValue; /***/ }), -/* 160 */ +/* 161 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -39930,17 +40287,17 @@ module.exports = GetNewValue; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Defaults = __webpack_require__(259); +var Defaults = __webpack_require__(261); var GetAdvancedValue = __webpack_require__(13); var GetBoolean = __webpack_require__(96); var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetProps = __webpack_require__(563); -var GetTargets = __webpack_require__(257); +var GetNewValue = __webpack_require__(160); +var GetProps = __webpack_require__(579); +var GetTargets = __webpack_require__(259); var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(258); -var Tween = __webpack_require__(260); -var TweenData = __webpack_require__(262); +var GetValueOp = __webpack_require__(260); +var Tween = __webpack_require__(262); +var TweenData = __webpack_require__(264); /** * Creates a new Tween. @@ -40054,7 +40411,7 @@ module.exports = TweenBuilder; /***/ }), -/* 161 */ +/* 162 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -40067,7 +40424,7 @@ var Class = __webpack_require__(0); var CustomMap = __webpack_require__(99); var GetFastValue = __webpack_require__(2); var Events = __webpack_require__(130); -var Animation = __webpack_require__(181); +var Animation = __webpack_require__(182); /** * @classdesc @@ -41930,363 +42287,6 @@ var AnimationState = new Class({ module.exports = AnimationState; -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(94); - -/** - * @classdesc - * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. - * - * Instances of this class are typically created by, and belong to WebGL Pipelines, however - * other Game Objects and classes can take advantage of Render Targets as well. - * - * @class RenderTarget - * @memberof Phaser.Renderer.WebGL - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGLRenderer. - * @param {number} width - The width of this Render Target. - * @param {number} height - The height of this Render Target. - * @param {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. - * @param {number} [minFilter=0] - The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`. - * @param {boolean} [autoClear=true] - Automatically clear this framebuffer when bound? - * @param {boolean} [autoResize=false] - Automatically resize this Render Target if the WebGL Renderer resizes? - */ -var RenderTarget = new Class({ - - initialize: - - function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize) - { - if (scale === undefined) { scale = 1; } - if (minFilter === undefined) { minFilter = 0; } - if (autoClear === undefined) { autoClear = true; } - if (autoResize === undefined) { autoResize = false; } - - /** - * A reference to the WebGLRenderer instance. - * - * @name Phaser.Renderer.WebGL.RenderTarget#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} - * @since 3.50.0 - */ - this.renderer = renderer; - - /** - * The WebGLFramebuffer of this Render Target. - * - * This is created in the `RenderTarget.resize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#framebuffer - * @type {WebGLFramebuffer} - * @since 3.50.0 - */ - this.framebuffer = null; - - /** - * The WebGLTexture of this Render Target. - * - * This is created in the `RenderTarget.resize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#texture - * @type {WebGLTexture} - * @since 3.50.0 - */ - this.texture = null; - - /** - * The width of the texture. - * - * @name Phaser.Renderer.WebGL.RenderTarget#width - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.width = 0; - - /** - * The height of the texture. - * - * @name Phaser.Renderer.WebGL.RenderTarget#height - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.height = 0; - - /** - * A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. - * - * A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc. - * - * @name Phaser.Renderer.WebGL.RenderTarget#scale - * @type {number} - * @since 3.50.0 - */ - this.scale = scale; - - /** - * The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`. - * - * @name Phaser.Renderer.WebGL.RenderTarget#minFilter - * @type {number} - * @since 3.50.0 - */ - this.minFilter = minFilter; - - /** - * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) - * during the `RenderTarget.bind` method. - * - * If you need more control over how, or if, the target is cleared, you can disable - * this via the config on creation, or even toggle it directly at runtime. - * - * @name Phaser.Renderer.WebGL.RenderTarget#autoClear - * @type {boolean} - * @since 3.50.0 - */ - this.autoClear = autoClear; - - /** - * Does this Render Target automatically resize when the WebGL Renderer does? - * - * Modify this property via the `setAutoResize` method. - * - * @name Phaser.Renderer.WebGL.RenderTarget#autoResize - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.autoResize = false; - - this.resize(width, height); - - if (autoResize) - { - this.setAutoResize(true); - } - }, - - /** - * Sets if this Render Target should automatically resize when the WebGL Renderer - * emits a resize event. - * - * @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize - * @since 3.50.0 - * - * @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes? - * - * @return {this} This RenderTarget instance. - */ - setAutoResize: function (autoResize) - { - if (autoResize && !this.autoResize) - { - this.renderer.on(Events.RESIZE, this.resize, this); - - this.autoResize = true; - } - else if (!autoResize && this.autoResize) - { - this.renderer.off(Events.RESIZE, this.resize, this); - - this.autoResize = false; - } - - return this; - }, - - /** - * Resizes this Render Target. - * - * Deletes both the frame buffer and texture, if they exist and then re-creates - * them using the new sizes. - * - * This method is called automatically by the pipeline during its resize handler. - * - * @method Phaser.Renderer.WebGL.RenderTarget#resize - * @since 3.50.0 - * - * @param {number} width - The new width of this Render Target. - * @param {number} height - The new height of this Render Target. - * - * @return {this} This RenderTarget instance. - */ - resize: function (width, height) - { - var scaledWidth = width * this.scale; - var scaledHeight = height * this.scale; - - if (scaledWidth !== this.width || scaledHeight !== this.height) - { - var renderer = this.renderer; - - renderer.deleteFramebuffer(this.framebuffer); - - renderer.deleteTexture(this.texture); - - width *= this.scale; - height *= this.scale; - - this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter); - this.framebuffer = renderer.createFramebuffer(width, height, this.texture, false); - - this.width = width; - this.height = height; - } - - return this; - }, - - /** - * Pushes this Render Target as the current frame buffer of the renderer. - * - * If `autoClear` is set, then clears the texture. - * - * If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport. - * - * @method Phaser.Renderer.WebGL.RenderTarget#bind - * @since 3.50.0 - * - * @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ? - * @param {number} [width] - Optional new width of this Render Target. - * @param {number} [height] - Optional new height of this Render Target. - */ - bind: function (adjustViewport, width, height) - { - if (adjustViewport === undefined) { adjustViewport = false; } - - if (adjustViewport) - { - this.renderer.flush(); - } - - if (width && height) - { - this.resize(width, height); - } - - this.renderer.pushFramebuffer(this.framebuffer, false, false, false); - - if (adjustViewport) - { - this.adjustViewport(); - } - - if (this.autoClear) - { - var gl = this.renderer.gl; - - gl.clearColor(0, 0, 0, 0); - - gl.clear(gl.COLOR_BUFFER_BIT); - } - }, - - /** - * Adjusts the GL viewport to match the width and height of this Render Target. - * - * Also disables `SCISSOR_TEST`. - * - * @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport - * @since 3.50.0 - */ - adjustViewport: function () - { - var gl = this.renderer.gl; - - gl.viewport(0, 0, this.width, this.height); - - gl.disable(gl.SCISSOR_TEST); - }, - - /** - * Clears this Render Target. - * - * @method Phaser.Renderer.WebGL.RenderTarget#clear - * @since 3.50.0 - */ - clear: function () - { - var renderer = this.renderer; - var gl = renderer.gl; - - renderer.pushFramebuffer(this.framebuffer); - - gl.disable(gl.SCISSOR_TEST); - - gl.clearColor(0, 0, 0, 0); - - gl.clear(gl.COLOR_BUFFER_BIT); - - renderer.popFramebuffer(); - - renderer.resetScissor(); - }, - - /** - * Unbinds this Render Target and optionally flushes the WebGL Renderer first. - * - * @name Phaser.Renderer.WebGL.RenderTarget#unbind - * @since 3.50.0 - * - * @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding? - * - * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. - */ - unbind: function (flush) - { - if (flush === undefined) { flush = false; } - - var renderer = this.renderer; - - if (flush) - { - renderer.flush(); - } - - return renderer.popFramebuffer(); - }, - - /** - * Removes all external references from this class and deletes the - * WebGL framebuffer and texture instances. - * - * Does not remove this Render Target from the parent pipeline. - * - * @name Phaser.Renderer.WebGL.RenderTarget#destroy - * @since 3.50.0 - */ - destroy: function () - { - var renderer = this.renderer; - - renderer.deleteFramebuffer(this.framebuffer); - renderer.deleteTexture(this.texture); - - renderer.off(Events.RESIZE, this.resize, this); - - this.renderer = null; - this.framebuffer = null; - this.texture = null; - } - -}); - -module.exports = RenderTarget; - - /***/ }), /* 163 */ /***/ (function(module, exports, __webpack_require__) { @@ -42308,8 +42308,8 @@ module.exports = Composite; var Events = __webpack_require__(268); var Common = __webpack_require__(50); -var Bounds = __webpack_require__(115); -var Body = __webpack_require__(70); +var Bounds = __webpack_require__(117); +var Body = __webpack_require__(71); (function() { @@ -42983,6 +42983,60 @@ var Body = __webpack_require__(70); /***/ }), /* 164 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Modes. + * + * @namespace Phaser.ScaleModes + * @since 3.0.0 + */ + +var ScaleModes = { + + /** + * Default Scale Mode (Linear). + * + * @name Phaser.ScaleModes.DEFAULT + * @type {number} + * @readonly + * @since 3.0.0 + */ + DEFAULT: 0, + + /** + * Linear Scale Mode. + * + * @name Phaser.ScaleModes.LINEAR + * @type {number} + * @readonly + * @since 3.0.0 + */ + LINEAR: 0, + + /** + * Nearest Scale Mode. + * + * @name Phaser.ScaleModes.NEAREST + * @type {number} + * @readonly + * @since 3.0.0 + */ + NEAREST: 1 + +}; + +module.exports = ScaleModes; + + +/***/ }), +/* 165 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43021,7 +43075,7 @@ module.exports = CircumferencePoint; /***/ }), -/* 165 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43065,7 +43119,7 @@ module.exports = Random; /***/ }), -/* 166 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43146,7 +43200,7 @@ module.exports = GetPoint; /***/ }), -/* 167 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43155,7 +43209,7 @@ module.exports = GetPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); var Point = __webpack_require__(4); /** @@ -43211,7 +43265,7 @@ module.exports = GetPoints; /***/ }), -/* 168 */ +/* 169 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43251,7 +43305,7 @@ module.exports = Random; /***/ }), -/* 169 */ +/* 170 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43289,7 +43343,7 @@ module.exports = Random; /***/ }), -/* 170 */ +/* 171 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43298,8 +43352,8 @@ module.exports = Random; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DeepCopy = __webpack_require__(171); -var PIPELINE_CONST = __webpack_require__(72); +var DeepCopy = __webpack_require__(172); +var PIPELINE_CONST = __webpack_require__(65); var SpliceOne = __webpack_require__(74); /** @@ -43690,7 +43744,7 @@ module.exports = Pipeline; /***/ }), -/* 171 */ +/* 172 */ /***/ (function(module, exports) { /** @@ -43739,7 +43793,7 @@ module.exports = DeepCopy; /***/ }), -/* 172 */ +/* 173 */ /***/ (function(module, exports) { /** @@ -43800,7 +43854,7 @@ module.exports = ToJSON; /***/ }), -/* 173 */ +/* 174 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43855,7 +43909,7 @@ module.exports = TransformXY; /***/ }), -/* 174 */ +/* 175 */ /***/ (function(module, exports) { /** @@ -43895,7 +43949,7 @@ module.exports = RotateLeft; /***/ }), -/* 175 */ +/* 176 */ /***/ (function(module, exports) { /** @@ -43935,7 +43989,7 @@ module.exports = RotateRight; /***/ }), -/* 176 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -43976,7 +44030,7 @@ module.exports = Random; /***/ }), -/* 177 */ +/* 178 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44032,7 +44086,7 @@ module.exports = Random; /***/ }), -/* 178 */ +/* 179 */ /***/ (function(module, exports) { /** @@ -44073,7 +44127,7 @@ module.exports = RotateAroundDistance; /***/ }), -/* 179 */ +/* 180 */ /***/ (function(module, exports) { /** @@ -44112,7 +44166,7 @@ module.exports = SmootherStep; /***/ }), -/* 180 */ +/* 181 */ /***/ (function(module, exports) { /** @@ -44159,7 +44213,7 @@ module.exports = SmoothStep; /***/ }), -/* 181 */ +/* 182 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -44168,7 +44222,7 @@ module.exports = SmoothStep; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Events = __webpack_require__(130); var FindClosestInSorted = __webpack_require__(312); @@ -45074,7 +45128,7 @@ module.exports = Animation; /***/ }), -/* 182 */ +/* 183 */ /***/ (function(module, exports) { /** @@ -45150,7 +45204,7 @@ module.exports = Pad; /***/ }), -/* 183 */ +/* 184 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45160,7 +45214,7 @@ module.exports = Pad; */ var HexStringToColor = __webpack_require__(321); -var IntegerToColor = __webpack_require__(185); +var IntegerToColor = __webpack_require__(186); var ObjectToColor = __webpack_require__(325); var RGBStringToColor = __webpack_require__(326); @@ -45206,7 +45260,7 @@ module.exports = ValueToColor; /***/ }), -/* 184 */ +/* 185 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45287,7 +45341,7 @@ module.exports = HSVToRGB; /***/ }), -/* 185 */ +/* 186 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45296,7 +45350,7 @@ module.exports = HSVToRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var IntegerToRGB = __webpack_require__(324); /** @@ -45320,7 +45374,7 @@ module.exports = IntegerToColor; /***/ }), -/* 186 */ +/* 187 */ /***/ (function(module, exports) { /** @@ -45357,7 +45411,7 @@ module.exports = CenterOn; /***/ }), -/* 187 */ +/* 188 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45549,7 +45603,7 @@ module.exports = init(); /***/ }), -/* 188 */ +/* 189 */ /***/ (function(module, exports) { /** @@ -45681,7 +45735,7 @@ module.exports = Smoothing(); /***/ }), -/* 189 */ +/* 190 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45691,7 +45745,7 @@ module.exports = Smoothing(); */ var CONST = __webpack_require__(14); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Math @@ -45714,11 +45768,11 @@ var PhaserMath = { // Single functions Average: __webpack_require__(837), Bernstein: __webpack_require__(350), - Between: __webpack_require__(191), - CatmullRom: __webpack_require__(190), + Between: __webpack_require__(192), + CatmullRom: __webpack_require__(191), CeilTo: __webpack_require__(838), - Clamp: __webpack_require__(17), - DegToRad: __webpack_require__(33), + Clamp: __webpack_require__(18), + DegToRad: __webpack_require__(34), Difference: __webpack_require__(839), Euler: __webpack_require__(840), Factorial: __webpack_require__(351), @@ -45732,30 +45786,30 @@ var PhaserMath = { MaxAdd: __webpack_require__(845), MinSub: __webpack_require__(846), Percent: __webpack_require__(847), - RadToDeg: __webpack_require__(192), + RadToDeg: __webpack_require__(193), RandomXY: __webpack_require__(848), RandomXYZ: __webpack_require__(849), RandomXYZW: __webpack_require__(850), Rotate: __webpack_require__(356), RotateAround: __webpack_require__(302), - RotateAroundDistance: __webpack_require__(178), + RotateAroundDistance: __webpack_require__(179), RotateTo: __webpack_require__(851), RoundAwayFromZero: __webpack_require__(357), RoundTo: __webpack_require__(852), SinCosTableGenerator: __webpack_require__(853), - SmootherStep: __webpack_require__(179), - SmoothStep: __webpack_require__(180), + SmootherStep: __webpack_require__(180), + SmoothStep: __webpack_require__(181), ToXY: __webpack_require__(854), - TransformXY: __webpack_require__(173), + TransformXY: __webpack_require__(174), Within: __webpack_require__(855), - Wrap: __webpack_require__(64), + Wrap: __webpack_require__(66), // Vector classes Vector2: __webpack_require__(3), - Vector3: __webpack_require__(36), + Vector3: __webpack_require__(37), Vector4: __webpack_require__(138), Matrix3: __webpack_require__(358), - Matrix4: __webpack_require__(65), + Matrix4: __webpack_require__(67), Quaternion: __webpack_require__(359), RotateVec3: __webpack_require__(856) @@ -45771,7 +45825,7 @@ module.exports = PhaserMath; /***/ }), -/* 190 */ +/* 191 */ /***/ (function(module, exports) { /** @@ -45808,7 +45862,7 @@ module.exports = CatmullRom; /***/ }), -/* 191 */ +/* 192 */ /***/ (function(module, exports) { /** @@ -45837,7 +45891,7 @@ module.exports = Between; /***/ }), -/* 192 */ +/* 193 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45867,7 +45921,7 @@ module.exports = RadToDeg; /***/ }), -/* 193 */ +/* 194 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45969,7 +46023,657 @@ module.exports = DefaultPlugins; /***/ }), -/* 194 */ +/* 195 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * The ColorMatrix class creates a 5x4 matrix that can be used in shaders and graphics + * operations. It provides methods required to modify the color values, such as adjusting + * the brightness, setting a sepia tone, hue rotation and more. + * + * Use the method `getData` to return a Float32Array containing the current color values. + * + * @class ColorMatrix + * @memberof Phaser.Display + * @constructor + * @since 3.50.0 + */ +var ColorMatrix = new Class({ + + initialize: + + function ColorMatrix () + { + /** + * Internal ColorMatrix array. + * + * @name Phaser.Display.ColorMatrix#_matrix + * @type {number[]} + * @private + * @since 3.50.0 + */ + this._matrix = [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + + /** + * The value that determines how much of the original color is used + * when mixing the colors. A value between 0 (all original) and 1 (all final) + * + * @name Phaser.Display.ColorMatrix#alpha + * @type {number} + * @since 3.50.0 + */ + this.alpha = 1; + + /** + * Is the ColorMatrix array dirty? + * + * @name Phaser.Display.ColorMatrix#_dirty + * @type {boolean} + * @private + * @since 3.50.0 + */ + this._dirty = true; + + /** + * The matrix data as a Float32Array. + * + * Returned by the `getData` method. + * + * @name Phaser.Display.ColorMatrix#data + * @type {Float32Array} + * @private + * @since 3.50.0 + */ + this._data; + }, + + /** + * Sets this ColorMatrix from the given array of color values. + * + * @method Phaser.Display.ColorMatrix#set + * @since 3.50.0 + * + * @param {number[]} value - The ColorMatrix values to set. + * + * @return {this} This ColorMatrix instance. + */ + set: function (value) + { + this._matrix = value; + + this._dirty = true; + + return this; + }, + + /** + * Resets the ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#reset + * @since 3.50.0 + * + * @return {this} This ColorMatrix instance. + */ + reset: function () + { + // Long-winded, but saves on gc, which happens a lot in Post FX Shaders + // that reset the ColorMatrix every frame. + + var m = this._matrix; + + m[0] = 1; + m[1] = 0; + m[2] = 0; + m[3] = 0; + m[4] = 0; + + m[5] = 0; + m[6] = 1; + m[7] = 0; + m[8] = 0; + m[9] = 0; + + m[10] = 0; + m[11] = 0; + m[12] = 1; + m[13] = 0; + m[14] = 0; + + m[15] = 0; + m[16] = 0; + m[17] = 0; + m[18] = 1; + m[19] = 0; + + this._dirty = true; + + return this; + }, + + /** + * Gets the ColorMatrix as a Float32Array. + * + * Can be used directly as a 1fv shader uniform value. + * + * @method Phaser.Display.ColorMatrix#getData + * @since 3.50.0 + * + * @return {Float32Array} The ColorMatrix as a Float32Array. + */ + getData: function () + { + if (this._dirty) + { + var f32 = new Float32Array(this._matrix); + + f32[4] /= 255; + f32[9] /= 255; + f32[14] /= 255; + f32[19] /= 255; + + this._data = f32; + + this._dirty = false; + } + + return this._data; + }, + + /** + * Changes the brightness of this ColorMatrix by the given amount. + * + * @method Phaser.Display.ColorMatrix#brightness + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + brightness: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var b = value; + + return this.multiply([ + b, 0, 0, 0, 0, + 0, b, 0, 0, 0, + 0, 0, b, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Changes the saturation of this ColorMatrix by the given amount. + * + * @method Phaser.Display.ColorMatrix#saturate + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + saturate: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var x = (value * 2 / 3) + 1; + var y = ((x - 1) * -0.5); + + return this.multiply([ + x, y, y, 0, 0, + y, x, y, 0, 0, + y, y, x, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Desaturates this ColorMatrix (removes color from it). + * + * @method Phaser.Display.ColorMatrix#saturation + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + desaturate: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.saturate(-1, multiply); + }, + + /** + * Rotates the hues of this ColorMatrix by the value given. + * + * @method Phaser.Display.ColorMatrix#hue + * @since 3.50.0 + * + * @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + hue: function (rotation, multiply) + { + if (rotation === undefined) { rotation = 0; } + if (multiply === undefined) { multiply = false; } + + rotation = rotation / 180 * Math.PI; + + var cos = Math.cos(rotation); + var sin = Math.sin(rotation); + var lumR = 0.213; + var lumG = 0.715; + var lumB = 0.072; + + return this.multiply([ + lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0, + lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0, + lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Sets this ColorMatrix to be grayscale. + * + * @method Phaser.Display.ColorMatrix#grayscale + * @since 3.50.0 + * + * @param {number} [value=1] - The grayscale scale (0 is black). + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + grayscale: function (value, multiply) + { + if (value === undefined) { value = 1; } + if (multiply === undefined) { multiply = false; } + + return this.saturate(-value, multiply); + }, + + /** + * Sets this ColorMatrix to be black and white. + * + * @method Phaser.Display.ColorMatrix#blackWhite + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + blackWhite: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.3, 0.6, 0.1, 0, 0, + 0.3, 0.6, 0.1, 0, 0, + 0.3, 0.6, 0.1, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Change the contrast of this ColorMatrix by the amount given. + * + * @method Phaser.Display.ColorMatrix#contrast + * @since 3.50.0 + * + * @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + contrast: function (value, multiply) + { + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } + + var v = value + 1; + var o = -0.5 * (v - 1); + + return this.multiply([ + v, 0, 0, 0, o, + 0, v, 0, 0, o, + 0, 0, v, 0, o, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Converts this ColorMatrix to have negative values. + * + * @method Phaser.Display.ColorMatrix#negative + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + negative: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + -1, 0, 0, 1, 0, + 0, -1, 0, 1, 0, + 0, 0, -1, 1, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Apply a desaturated luminance to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#desaturateLuminance + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + desaturateLuminance: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0.2764723, 0.9297080, 0.0938197, 0, -37.1, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a sepia tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#sepia + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + sepia: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.393, 0.7689999, 0.18899999, 0, 0, + 0.349, 0.6859999, 0.16799999, 0, 0, + 0.272, 0.5339999, 0.13099999, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a night vision tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#night + * @since 3.50.0 + * + * @param {number} [intensity=0.1] - The intensity of this effect. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + night: function (intensity, multiply) + { + if (intensity === undefined) { intensity = 0.1; } + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + intensity * (-2.0), -intensity, 0, 0, 0, + -intensity, 0, intensity, 0, 0, + 0, intensity, intensity * 2.0, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a trippy color tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#lsd + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + lsd: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 2, -0.4, 0.5, 0, 0, + -0.5, 2, -0.4, 0, 0, + -0.4, -0.5, 3, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a brown tone to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#brown + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + brown: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, + -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, + 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a vintage pinhole color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#vintagePinhole + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + vintagePinhole: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, + 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, + 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a kodachrome color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#kodachrome + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + kodachrome: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, + -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, + -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a technicolor color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#technicolor + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + technicolor: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, + -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, + -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Applies a polaroid color effect to this ColorMatrix. + * + * @method Phaser.Display.ColorMatrix#polaroid + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + polaroid: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 1.438, -0.062, -0.062, 0, 0, + -0.122, 1.378, -0.122, 0, 0, + -0.016, -0.016, 1.483, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Shifts the values of this ColorMatrix into BGR order. + * + * @method Phaser.Display.ColorMatrix#shiftToBGR + * @since 3.50.0 + * + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. + */ + shiftToBGR: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply([ + 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); + }, + + /** + * Multiplies the two given matrices. + * + * @method Phaser.Display.ColorMatrix#multiply + * @since 3.50.0 + * + * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix. + * + * @return {this} This ColorMatrix instance. + */ + multiply: function (a, multiply) + { + // Duplicate _matrix into c + + if (!multiply) + { + this.reset(); + } + + var m = this._matrix; + var c = []; + + for (var i = 0; i < 20; i++) + { + c[i] = m[i]; + } + + // R + m[0] = (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]); + m[1] = (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]); + m[2] = (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]); + m[3] = (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]); + m[4] = (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4]; + + // G + m[5] = (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]); + m[6] = (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]); + m[7] = (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]); + m[8] = (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]); + m[9] = (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9]; + + // B + m[10] = (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]); + m[11] = (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]); + m[12] = (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]); + m[13] = (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]); + m[14] = (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14]; + + // A + m[15] = (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]); + m[16] = (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]); + m[17] = (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]); + m[18] = (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]); + m[19] = (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19]; + + this._dirty = true; + + return this; + } + +}); + +module.exports = ColorMatrix; + + +/***/ }), +/* 196 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46055,7 +46759,7 @@ module.exports = FromPoints; /***/ }), -/* 195 */ +/* 197 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46275,7 +46979,7 @@ module.exports = RGB; /***/ }), -/* 196 */ +/* 198 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46286,10 +46990,10 @@ module.exports = RGB; var CONST = { - CENTER: __webpack_require__(381), - ORIENTATION: __webpack_require__(382), - SCALE_MODE: __webpack_require__(383), - ZOOM: __webpack_require__(384) + CENTER: __webpack_require__(397), + ORIENTATION: __webpack_require__(398), + SCALE_MODE: __webpack_require__(399), + ZOOM: __webpack_require__(400) }; @@ -46297,7 +47001,7 @@ module.exports = CONST; /***/ }), -/* 197 */ +/* 199 */ /***/ (function(module, exports) { /** @@ -46326,7 +47030,7 @@ module.exports = RemoveFromDOM; /***/ }), -/* 198 */ +/* 200 */ /***/ (function(module, exports) { /** @@ -46424,7 +47128,7 @@ module.exports = INPUT_CONST; /***/ }), -/* 199 */ +/* 201 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -46434,13 +47138,13 @@ module.exports = INPUT_CONST; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(141); -var DefaultPlugins = __webpack_require__(193); +var CONST = __webpack_require__(142); +var DefaultPlugins = __webpack_require__(194); var Events = __webpack_require__(21); -var GetPhysicsPlugins = __webpack_require__(397); -var GetScenePlugins = __webpack_require__(398); +var GetPhysicsPlugins = __webpack_require__(413); +var GetScenePlugins = __webpack_require__(414); var NOOP = __webpack_require__(1); -var Settings = __webpack_require__(399); +var Settings = __webpack_require__(415); /** * @classdesc @@ -47219,7 +47923,7 @@ module.exports = Systems; /***/ }), -/* 200 */ +/* 202 */ /***/ (function(module, exports) { /** @@ -47256,7 +47960,7 @@ module.exports = UppercaseFirst; /***/ }), -/* 201 */ +/* 203 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -47266,8 +47970,8 @@ module.exports = UppercaseFirst; */ var Class = __webpack_require__(0); -var Frame = __webpack_require__(104); -var TextureSource = __webpack_require__(402); +var Frame = __webpack_require__(106); +var TextureSource = __webpack_require__(418); var TEXTURE_MISSING_ERROR = 'Texture.frame missing: '; @@ -47776,7 +48480,7 @@ module.exports = Texture; /***/ }), -/* 202 */ +/* 204 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -47838,7 +48542,7 @@ module.exports = GetAll; /***/ }), -/* 203 */ +/* 205 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -47862,23 +48566,23 @@ module.exports = { Each: __webpack_require__(1021), EachInRange: __webpack_require__(1022), FindClosestInSorted: __webpack_require__(312), - GetAll: __webpack_require__(202), - GetFirst: __webpack_require__(406), - GetRandom: __webpack_require__(205), + GetAll: __webpack_require__(204), + GetFirst: __webpack_require__(422), + GetRandom: __webpack_require__(207), MoveDown: __webpack_require__(1023), MoveTo: __webpack_require__(1024), MoveUp: __webpack_require__(1025), NumberArray: __webpack_require__(316), NumberArrayStep: __webpack_require__(1026), - QuickSelect: __webpack_require__(414), - Range: __webpack_require__(415), - Remove: __webpack_require__(88), + QuickSelect: __webpack_require__(430), + Range: __webpack_require__(431), + Remove: __webpack_require__(89), RemoveAt: __webpack_require__(1027), RemoveBetween: __webpack_require__(1028), RemoveRandomElement: __webpack_require__(1029), Replace: __webpack_require__(1030), - RotateLeft: __webpack_require__(174), - RotateRight: __webpack_require__(175), + RotateLeft: __webpack_require__(175), + RotateRight: __webpack_require__(176), SafeRange: __webpack_require__(78), SendToBack: __webpack_require__(1031), SetAll: __webpack_require__(1032), @@ -47892,7 +48596,7 @@ module.exports = { /***/ }), -/* 204 */ +/* 206 */ /***/ (function(module, exports) { /** @@ -47954,7 +48658,7 @@ module.exports = CheckMatrix; /***/ }), -/* 205 */ +/* 207 */ /***/ (function(module, exports) { /** @@ -47989,7 +48693,7 @@ module.exports = GetRandom; /***/ }), -/* 206 */ +/* 208 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48000,7 +48704,7 @@ module.exports = GetRandom; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(416); +var Events = __webpack_require__(432); /** * @classdesc @@ -48292,7 +48996,7 @@ module.exports = ProcessQueue; /***/ }), -/* 207 */ +/* 209 */ /***/ (function(module, exports) { /** @@ -48453,7 +49157,7 @@ module.exports = ParseXMLBitmapFont; /***/ }), -/* 208 */ +/* 210 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48463,12 +49167,12 @@ module.exports = ParseXMLBitmapFont; */ var BlitterRender = __webpack_require__(1043); -var Bob = __webpack_require__(418); +var Bob = __webpack_require__(434); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var Frame = __webpack_require__(104); +var Frame = __webpack_require__(106); var GameObject = __webpack_require__(15); -var List = __webpack_require__(105); +var List = __webpack_require__(107); /** * @callback CreateCallback @@ -48752,7 +49456,7 @@ module.exports = Blitter; /***/ }), -/* 209 */ +/* 211 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -48762,15 +49466,15 @@ module.exports = Blitter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(203); -var BlendModes = __webpack_require__(38); +var ArrayUtils = __webpack_require__(205); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var Events = __webpack_require__(75); var GameObject = __webpack_require__(15); var Rectangle = __webpack_require__(10); var Render = __webpack_require__(1046); -var Union = __webpack_require__(419); +var Union = __webpack_require__(435); var Vector2 = __webpack_require__(3); /** @@ -50127,7 +50831,7 @@ module.exports = Container; /***/ }), -/* 210 */ +/* 212 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -50136,7 +50840,7 @@ module.exports = Container; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var Class = __webpack_require__(0); var Render = __webpack_require__(1051); @@ -50360,7 +51064,7 @@ module.exports = DynamicBitmapText; /***/ }), -/* 211 */ +/* 213 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -50371,21 +51075,21 @@ module.exports = DynamicBitmapText; var BaseCamera = __webpack_require__(131); var Class = __webpack_require__(0); -var Commands = __webpack_require__(212); +var Commands = __webpack_require__(214); var ComponentsAlpha = __webpack_require__(297); var ComponentsBlendMode = __webpack_require__(298); var ComponentsDepth = __webpack_require__(299); var ComponentsMask = __webpack_require__(303); -var ComponentsPipeline = __webpack_require__(170); +var ComponentsPipeline = __webpack_require__(171); var ComponentsScrollFactor = __webpack_require__(306); var ComponentsTransform = __webpack_require__(307); var ComponentsVisible = __webpack_require__(308); -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var MATH_CONST = __webpack_require__(14); -var PIPELINES_CONST = __webpack_require__(72); +var PIPELINES_CONST = __webpack_require__(65); var Render = __webpack_require__(1057); /** @@ -51837,7 +52541,7 @@ module.exports = Graphics; /***/ }), -/* 212 */ +/* 214 */ /***/ (function(module, exports) { /** @@ -51872,7 +52576,7 @@ module.exports = { /***/ }), -/* 213 */ +/* 215 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -51914,7 +52618,7 @@ module.exports = CircumferencePoint; /***/ }), -/* 214 */ +/* 216 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -51923,14 +52627,14 @@ module.exports = CircumferencePoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var ComponentsToJSON = __webpack_require__(172); +var ComponentsToJSON = __webpack_require__(173); var DataManager = __webpack_require__(98); var EventEmitter = __webpack_require__(9); var GameObjectEvents = __webpack_require__(75); -var List = __webpack_require__(105); +var List = __webpack_require__(107); var Render = __webpack_require__(1065); var SceneEvents = __webpack_require__(21); var StableSort = __webpack_require__(79); @@ -52665,7 +53369,7 @@ module.exports = Layer; /***/ }), -/* 215 */ +/* 217 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -52677,9 +53381,9 @@ module.exports = Layer; var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var GravityWell = __webpack_require__(428); -var List = __webpack_require__(105); -var ParticleEmitter = __webpack_require__(430); +var GravityWell = __webpack_require__(444); +var List = __webpack_require__(107); +var ParticleEmitter = __webpack_require__(446); var Render = __webpack_require__(1069); /** @@ -53166,7 +53870,7 @@ module.exports = ParticleEmitterManager; /***/ }), -/* 216 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -53175,20 +53879,20 @@ module.exports = ParticleEmitterManager; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Camera = __webpack_require__(131); var CanvasPool = __webpack_require__(31); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var CONST = __webpack_require__(39); -var Frame = __webpack_require__(104); +var Frame = __webpack_require__(106); var GameObject = __webpack_require__(15); var NOOP = __webpack_require__(1); -var PIPELINE_CONST = __webpack_require__(72); +var PIPELINE_CONST = __webpack_require__(65); var Render = __webpack_require__(1073); -var RenderTarget = __webpack_require__(162); +var RenderTarget = __webpack_require__(139); var Utils = __webpack_require__(12); -var UUID = __webpack_require__(217); +var UUID = __webpack_require__(219); /** * @classdesc @@ -54591,7 +55295,7 @@ module.exports = RenderTexture; /***/ }), -/* 217 */ +/* 219 */ /***/ (function(module, exports) { /** @@ -54626,7 +55330,7 @@ module.exports = UUID; /***/ }), -/* 218 */ +/* 220 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -54635,11 +55339,11 @@ module.exports = UUID; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(161); +var AnimationState = __webpack_require__(162); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); -var PIPELINE_CONST = __webpack_require__(72); +var PIPELINE_CONST = __webpack_require__(65); var RopeRender = __webpack_require__(1079); var Vector2 = __webpack_require__(3); @@ -55751,7 +56455,7 @@ module.exports = Rope; /***/ }), -/* 219 */ +/* 221 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -55760,17 +56464,17 @@ module.exports = Rope; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var CanvasPool = __webpack_require__(31); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameEvents = __webpack_require__(22); var GameObject = __webpack_require__(15); -var GetTextSize = __webpack_require__(436); +var GetTextSize = __webpack_require__(452); var GetValue = __webpack_require__(6); -var RemoveFromDOM = __webpack_require__(197); +var RemoveFromDOM = __webpack_require__(199); var TextRender = __webpack_require__(1082); -var TextStyle = __webpack_require__(437); +var TextStyle = __webpack_require__(453); /** * @classdesc @@ -57168,7 +57872,7 @@ module.exports = Text; /***/ }), -/* 220 */ +/* 222 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -57183,7 +57887,7 @@ var Components = __webpack_require__(11); var GameEvents = __webpack_require__(22); var GameObject = __webpack_require__(15); var GetPowerOfTwo = __webpack_require__(355); -var Smoothing = __webpack_require__(188); +var Smoothing = __webpack_require__(189); var TileSpriteRender = __webpack_require__(1085); var Vector2 = __webpack_require__(3); @@ -57820,7 +58524,7 @@ module.exports = TileSprite; /***/ }), -/* 221 */ +/* 223 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -57830,14 +58534,14 @@ module.exports = TileSprite; */ var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Components = __webpack_require__(11); var Events = __webpack_require__(75); var GameEvents = __webpack_require__(22); var InputEvents = __webpack_require__(49); var GameObject = __webpack_require__(15); -var SoundEvents = __webpack_require__(68); -var UUID = __webpack_require__(217); +var SoundEvents = __webpack_require__(69); +var UUID = __webpack_require__(219); var VideoRender = __webpack_require__(1088); var MATH_CONST = __webpack_require__(14); @@ -59666,7 +60370,7 @@ module.exports = Video; /***/ }), -/* 222 */ +/* 224 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59676,8 +60380,8 @@ module.exports = Video; */ var Class = __webpack_require__(0); -var Contains = __webpack_require__(223); -var GetPoints = __webpack_require__(448); +var Contains = __webpack_require__(225); +var GetPoints = __webpack_require__(464); var GEOM_CONST = __webpack_require__(55); /** @@ -59900,7 +60604,7 @@ module.exports = Polygon; /***/ }), -/* 223 */ +/* 225 */ /***/ (function(module, exports) { /** @@ -59949,7 +60653,7 @@ module.exports = Contains; /***/ }), -/* 224 */ +/* 226 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -59962,8 +60666,8 @@ var Class = __webpack_require__(0); var Components = __webpack_require__(11); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); -var Extend = __webpack_require__(19); -var SetValue = __webpack_require__(456); +var Extend = __webpack_require__(17); +var SetValue = __webpack_require__(472); var ShaderRender = __webpack_require__(1170); var TransformMatrix = __webpack_require__(25); @@ -61181,7 +61885,7 @@ module.exports = Shader; /***/ }), -/* 225 */ +/* 227 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -61192,17 +61896,17 @@ module.exports = Shader; var Class = __webpack_require__(0); var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(33); -var Face = __webpack_require__(111); +var DegToRad = __webpack_require__(34); +var Face = __webpack_require__(113); var GameObject = __webpack_require__(15); -var GenerateVerts = __webpack_require__(457); -var GenerateObjVerts = __webpack_require__(458); -var GetCalcMatrix = __webpack_require__(18); -var Matrix4 = __webpack_require__(65); +var GenerateVerts = __webpack_require__(473); +var GenerateObjVerts = __webpack_require__(474); +var GetCalcMatrix = __webpack_require__(19); +var Matrix4 = __webpack_require__(67); var MeshRender = __webpack_require__(1173); var StableSort = __webpack_require__(79); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); /** * @classdesc @@ -62236,7 +62940,7 @@ module.exports = Mesh; /***/ }), -/* 226 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62267,7 +62971,7 @@ module.exports = CircleToCircle; /***/ }), -/* 227 */ +/* 229 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62278,7 +62982,7 @@ module.exports = CircleToCircle; */ var Point = __webpack_require__(4); -var LineToCircle = __webpack_require__(228); +var LineToCircle = __webpack_require__(230); /** * Checks for intersection between the line segment and circle, @@ -62359,7 +63063,7 @@ module.exports = GetLineToCircle; /***/ }), -/* 228 */ +/* 230 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62368,7 +63072,7 @@ module.exports = GetLineToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); var Point = __webpack_require__(4); var tmp = new Point(); @@ -62443,7 +63147,7 @@ module.exports = LineToCircle; /***/ }), -/* 229 */ +/* 231 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62454,8 +63158,8 @@ module.exports = LineToCircle; */ var Point = __webpack_require__(4); -var LineToLine = __webpack_require__(91); -var LineToRectangle = __webpack_require__(466); +var LineToLine = __webpack_require__(92); +var LineToRectangle = __webpack_require__(482); /** * Checks for intersection between the Line and a Rectangle shape, @@ -62503,7 +63207,7 @@ module.exports = GetLineToRectangle; /***/ }), -/* 230 */ +/* 232 */ /***/ (function(module, exports) { /** @@ -62590,7 +63294,7 @@ module.exports = ContainsArray; /***/ }), -/* 231 */ +/* 233 */ /***/ (function(module, exports) { /** @@ -62638,7 +63342,7 @@ module.exports = RotateAroundXY; /***/ }), -/* 232 */ +/* 234 */ /***/ (function(module, exports) { /** @@ -62666,7 +63370,7 @@ module.exports = GetAspectRatio; /***/ }), -/* 233 */ +/* 235 */ /***/ (function(module, exports) { /** @@ -62720,7 +63424,7 @@ module.exports = RotateAroundXY; /***/ }), -/* 234 */ +/* 236 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62746,7 +63450,7 @@ module.exports = { /***/ }), -/* 235 */ +/* 237 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62755,8 +63459,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var XHRSettings = __webpack_require__(153); +var Extend = __webpack_require__(17); +var XHRSettings = __webpack_require__(154); /** * Takes two XHRSettings Objects and creates a new XHRSettings object from them. @@ -62794,7 +63498,7 @@ module.exports = MergeXHRSettings; /***/ }), -/* 236 */ +/* 238 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -62809,7 +63513,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var ParseXML = __webpack_require__(386); +var ParseXML = __webpack_require__(402); /** * @classdesc @@ -62979,7 +63683,7 @@ module.exports = XMLFile; /***/ }), -/* 237 */ +/* 239 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63158,7 +63862,7 @@ module.exports = TextFile; /***/ }), -/* 238 */ +/* 240 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63183,8 +63887,8 @@ module.exports = { Gravity: __webpack_require__(1369), Immovable: __webpack_require__(1370), Mass: __webpack_require__(1371), - OverlapCirc: __webpack_require__(501), - OverlapRect: __webpack_require__(239), + OverlapCirc: __webpack_require__(517), + OverlapRect: __webpack_require__(241), Pushable: __webpack_require__(1372), Size: __webpack_require__(1373), Velocity: __webpack_require__(1374) @@ -63193,7 +63897,7 @@ module.exports = { /***/ }), -/* 239 */ +/* 241 */ /***/ (function(module, exports) { /** @@ -63278,7 +63982,7 @@ module.exports = OverlapRect; /***/ }), -/* 240 */ +/* 242 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63306,7 +64010,7 @@ module.exports = { /***/ }), -/* 241 */ +/* 243 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63315,7 +64019,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); +var CONST = __webpack_require__(60); /** * Calculates and returns the horizontal overlap between two arcade physics bodies and sets their properties @@ -63414,7 +64118,7 @@ module.exports = GetOverlapX; /***/ }), -/* 242 */ +/* 244 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63423,7 +64127,7 @@ module.exports = GetOverlapX; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); +var CONST = __webpack_require__(60); /** * Calculates and returns the vertical overlap between two arcade physics bodies and sets their properties @@ -63522,7 +64226,7 @@ module.exports = GetOverlapY; /***/ }), -/* 243 */ +/* 245 */ /***/ (function(module, exports) { /** @@ -63558,7 +64262,7 @@ module.exports = TileIntersectsBody; /***/ }), -/* 244 */ +/* 246 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -63575,10 +64279,10 @@ var Constraint = {}; module.exports = Constraint; -var Vertices = __webpack_require__(93); -var Vector = __webpack_require__(114); +var Vertices = __webpack_require__(94); +var Vector = __webpack_require__(116); var Sleeping = __webpack_require__(267); -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); var Axes = __webpack_require__(585); var Common = __webpack_require__(50); @@ -64047,7 +64751,7 @@ var Common = __webpack_require__(50); /***/ }), -/* 245 */ +/* 247 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64062,81 +64766,81 @@ var Common = __webpack_require__(50); module.exports = { - CalculateFacesAt: __webpack_require__(246), - CalculateFacesWithin: __webpack_require__(60), - CheckIsoBounds: __webpack_require__(521), - Copy: __webpack_require__(1407), - CreateFromTiles: __webpack_require__(1408), - CullBounds: __webpack_require__(523), - CullTiles: __webpack_require__(524), - Fill: __webpack_require__(1409), - FilterTiles: __webpack_require__(1410), - FindByIndex: __webpack_require__(1411), - FindTile: __webpack_require__(1412), - ForEachTile: __webpack_require__(1413), - GetCullTilesFunction: __webpack_require__(1414), - GetTileAt: __webpack_require__(155), - GetTileAtWorldXY: __webpack_require__(1415), + CalculateFacesAt: __webpack_require__(248), + CalculateFacesWithin: __webpack_require__(61), + CheckIsoBounds: __webpack_require__(537), + Copy: __webpack_require__(1414), + CreateFromTiles: __webpack_require__(1415), + CullBounds: __webpack_require__(539), + CullTiles: __webpack_require__(540), + Fill: __webpack_require__(1416), + FilterTiles: __webpack_require__(1417), + FindByIndex: __webpack_require__(1418), + FindTile: __webpack_require__(1419), + ForEachTile: __webpack_require__(1420), + GetCullTilesFunction: __webpack_require__(1421), + GetTileAt: __webpack_require__(156), + GetTileAtWorldXY: __webpack_require__(1422), GetTilesWithin: __webpack_require__(26), - GetTilesWithinShape: __webpack_require__(1416), - GetTilesWithinWorldXY: __webpack_require__(507), - GetTileToWorldXFunction: __webpack_require__(1417), - GetTileToWorldXYFunction: __webpack_require__(1418), - GetTileToWorldYFunction: __webpack_require__(1419), - GetWorldToTileXFunction: __webpack_require__(1420), - GetWorldToTileXYFunction: __webpack_require__(1421), - GetWorldToTileYFunction: __webpack_require__(1422), - HasTileAt: __webpack_require__(542), - HasTileAtWorldXY: __webpack_require__(1423), - HexagonalCullBounds: __webpack_require__(526), - HexagonalCullTiles: __webpack_require__(525), - HexagonalTileToWorldXY: __webpack_require__(530), - HexagonalTileToWorldY: __webpack_require__(534), - HexagonalWorldToTileXY: __webpack_require__(536), - HexagonalWorldToTileY: __webpack_require__(540), - IsInLayerBounds: __webpack_require__(116), - IsometricCullTiles: __webpack_require__(527), - IsometricTileToWorldXY: __webpack_require__(531), - IsometricWorldToTileXY: __webpack_require__(537), - PutTileAt: __webpack_require__(251), - PutTileAtWorldXY: __webpack_require__(1424), - PutTilesAt: __webpack_require__(1425), - Randomize: __webpack_require__(1426), - RemoveTileAt: __webpack_require__(543), - RemoveTileAtWorldXY: __webpack_require__(1427), - RenderDebug: __webpack_require__(1428), - ReplaceByIndex: __webpack_require__(522), - RunCull: __webpack_require__(156), - SetCollision: __webpack_require__(1429), - SetCollisionBetween: __webpack_require__(1430), - SetCollisionByExclusion: __webpack_require__(1431), - SetCollisionByProperty: __webpack_require__(1432), - SetCollisionFromCollisionGroup: __webpack_require__(1433), - SetLayerCollisionIndex: __webpack_require__(157), - SetTileCollision: __webpack_require__(71), - SetTileIndexCallback: __webpack_require__(1434), - SetTileLocationCallback: __webpack_require__(1435), - Shuffle: __webpack_require__(1436), - StaggeredCullBounds: __webpack_require__(529), - StaggeredCullTiles: __webpack_require__(528), - StaggeredTileToWorldXY: __webpack_require__(532), - StaggeredTileToWorldY: __webpack_require__(535), - StaggeredWorldToTileXY: __webpack_require__(538), - StaggeredWorldToTileY: __webpack_require__(541), - SwapByIndex: __webpack_require__(1437), - TileToWorldX: __webpack_require__(247), - TileToWorldXY: __webpack_require__(533), - TileToWorldY: __webpack_require__(248), - WeightedRandomize: __webpack_require__(1438), - WorldToTileX: __webpack_require__(249), - WorldToTileXY: __webpack_require__(539), - WorldToTileY: __webpack_require__(250) + GetTilesWithinShape: __webpack_require__(1423), + GetTilesWithinWorldXY: __webpack_require__(523), + GetTileToWorldXFunction: __webpack_require__(1424), + GetTileToWorldXYFunction: __webpack_require__(1425), + GetTileToWorldYFunction: __webpack_require__(1426), + GetWorldToTileXFunction: __webpack_require__(1427), + GetWorldToTileXYFunction: __webpack_require__(1428), + GetWorldToTileYFunction: __webpack_require__(1429), + HasTileAt: __webpack_require__(558), + HasTileAtWorldXY: __webpack_require__(1430), + HexagonalCullBounds: __webpack_require__(542), + HexagonalCullTiles: __webpack_require__(541), + HexagonalTileToWorldXY: __webpack_require__(546), + HexagonalTileToWorldY: __webpack_require__(550), + HexagonalWorldToTileXY: __webpack_require__(552), + HexagonalWorldToTileY: __webpack_require__(556), + IsInLayerBounds: __webpack_require__(118), + IsometricCullTiles: __webpack_require__(543), + IsometricTileToWorldXY: __webpack_require__(547), + IsometricWorldToTileXY: __webpack_require__(553), + PutTileAt: __webpack_require__(253), + PutTileAtWorldXY: __webpack_require__(1431), + PutTilesAt: __webpack_require__(1432), + Randomize: __webpack_require__(1433), + RemoveTileAt: __webpack_require__(559), + RemoveTileAtWorldXY: __webpack_require__(1434), + RenderDebug: __webpack_require__(1435), + ReplaceByIndex: __webpack_require__(538), + RunCull: __webpack_require__(157), + SetCollision: __webpack_require__(1436), + SetCollisionBetween: __webpack_require__(1437), + SetCollisionByExclusion: __webpack_require__(1438), + SetCollisionByProperty: __webpack_require__(1439), + SetCollisionFromCollisionGroup: __webpack_require__(1440), + SetLayerCollisionIndex: __webpack_require__(158), + SetTileCollision: __webpack_require__(72), + SetTileIndexCallback: __webpack_require__(1441), + SetTileLocationCallback: __webpack_require__(1442), + Shuffle: __webpack_require__(1443), + StaggeredCullBounds: __webpack_require__(545), + StaggeredCullTiles: __webpack_require__(544), + StaggeredTileToWorldXY: __webpack_require__(548), + StaggeredTileToWorldY: __webpack_require__(551), + StaggeredWorldToTileXY: __webpack_require__(554), + StaggeredWorldToTileY: __webpack_require__(557), + SwapByIndex: __webpack_require__(1444), + TileToWorldX: __webpack_require__(249), + TileToWorldXY: __webpack_require__(549), + TileToWorldY: __webpack_require__(250), + WeightedRandomize: __webpack_require__(1445), + WorldToTileX: __webpack_require__(251), + WorldToTileXY: __webpack_require__(555), + WorldToTileY: __webpack_require__(252) }; /***/ }), -/* 246 */ +/* 248 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64145,7 +64849,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTileAt = __webpack_require__(155); +var GetTileAt = __webpack_require__(156); /** * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting @@ -64230,7 +64934,7 @@ module.exports = CalculateFacesAt; /***/ }), -/* 247 */ +/* 249 */ /***/ (function(module, exports) { /** @@ -64274,7 +64978,7 @@ module.exports = TileToWorldX; /***/ }), -/* 248 */ +/* 250 */ /***/ (function(module, exports) { /** @@ -64318,7 +65022,7 @@ module.exports = TileToWorldY; /***/ }), -/* 249 */ +/* 251 */ /***/ (function(module, exports) { /** @@ -64366,7 +65070,7 @@ module.exports = WorldToTileX; /***/ }), -/* 250 */ +/* 252 */ /***/ (function(module, exports) { /** @@ -64414,7 +65118,7 @@ module.exports = WorldToTileY; /***/ }), -/* 251 */ +/* 253 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64424,9 +65128,9 @@ module.exports = WorldToTileY; */ var Tile = __webpack_require__(83); -var IsInLayerBounds = __webpack_require__(116); -var CalculateFacesAt = __webpack_require__(246); -var SetTileCollision = __webpack_require__(71); +var IsInLayerBounds = __webpack_require__(118); +var CalculateFacesAt = __webpack_require__(248); +var SetTileCollision = __webpack_require__(72); /** * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index @@ -64499,7 +65203,7 @@ module.exports = PutTileAt; /***/ }), -/* 252 */ +/* 254 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64546,7 +65250,7 @@ module.exports = FromOrientationString; /***/ }), -/* 253 */ +/* 255 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64555,9 +65259,9 @@ module.exports = FromOrientationString; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(37); -var LayerData = __webpack_require__(117); -var MapData = __webpack_require__(118); +var Formats = __webpack_require__(38); +var LayerData = __webpack_require__(119); +var MapData = __webpack_require__(120); var Tile = __webpack_require__(83); /** @@ -64638,7 +65342,7 @@ module.exports = Parse2DArray; /***/ }), -/* 254 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64647,8 +65351,8 @@ module.exports = Parse2DArray; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Pick = __webpack_require__(551); -var ParseGID = __webpack_require__(255); +var Pick = __webpack_require__(567); +var ParseGID = __webpack_require__(257); var copyPoints = function (p) { return { x: p.x, y: p.y }; }; @@ -64718,7 +65422,7 @@ module.exports = ParseObject; /***/ }), -/* 255 */ +/* 257 */ /***/ (function(module, exports) { /** @@ -64808,7 +65512,7 @@ module.exports = ParseGID; /***/ }), -/* 256 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64817,10 +65521,10 @@ module.exports = ParseGID; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(37); -var MapData = __webpack_require__(118); -var Parse = __webpack_require__(544); -var Tilemap = __webpack_require__(560); +var Formats = __webpack_require__(38); +var MapData = __webpack_require__(120); +var Parse = __webpack_require__(560); +var Tilemap = __webpack_require__(576); /** * Create a Tilemap from the given key or data. If neither is given, make a blank Tilemap. When @@ -64894,7 +65598,7 @@ module.exports = ParseToTilemap; /***/ }), -/* 257 */ +/* 259 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -64943,7 +65647,7 @@ module.exports = GetTargets; /***/ }), -/* 258 */ +/* 260 */ /***/ (function(module, exports) { /** @@ -65211,7 +65915,7 @@ module.exports = GetValueOp; /***/ }), -/* 259 */ +/* 261 */ /***/ (function(module, exports) { /** @@ -65255,7 +65959,7 @@ module.exports = TWEEN_DEFAULTS; /***/ }), -/* 260 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -65266,7 +65970,7 @@ module.exports = TWEEN_DEFAULTS; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(261); +var Events = __webpack_require__(263); var GameObjectCreator = __webpack_require__(16); var GameObjectFactory = __webpack_require__(5); var TWEEN_CONST = __webpack_require__(97); @@ -66898,7 +67602,7 @@ module.exports = Tween; /***/ }), -/* 261 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -66913,26 +67617,26 @@ module.exports = Tween; module.exports = { - TIMELINE_COMPLETE: __webpack_require__(1452), - TIMELINE_LOOP: __webpack_require__(1453), - TIMELINE_PAUSE: __webpack_require__(1454), - TIMELINE_RESUME: __webpack_require__(1455), - TIMELINE_START: __webpack_require__(1456), - TIMELINE_UPDATE: __webpack_require__(1457), - TWEEN_ACTIVE: __webpack_require__(1458), - TWEEN_COMPLETE: __webpack_require__(1459), - TWEEN_LOOP: __webpack_require__(1460), - TWEEN_REPEAT: __webpack_require__(1461), - TWEEN_START: __webpack_require__(1462), - TWEEN_STOP: __webpack_require__(1463), - TWEEN_UPDATE: __webpack_require__(1464), - TWEEN_YOYO: __webpack_require__(1465) + TIMELINE_COMPLETE: __webpack_require__(1459), + TIMELINE_LOOP: __webpack_require__(1460), + TIMELINE_PAUSE: __webpack_require__(1461), + TIMELINE_RESUME: __webpack_require__(1462), + TIMELINE_START: __webpack_require__(1463), + TIMELINE_UPDATE: __webpack_require__(1464), + TWEEN_ACTIVE: __webpack_require__(1465), + TWEEN_COMPLETE: __webpack_require__(1466), + TWEEN_LOOP: __webpack_require__(1467), + TWEEN_REPEAT: __webpack_require__(1468), + TWEEN_START: __webpack_require__(1469), + TWEEN_STOP: __webpack_require__(1470), + TWEEN_UPDATE: __webpack_require__(1471), + TWEEN_YOYO: __webpack_require__(1472) }; /***/ }), -/* 262 */ +/* 264 */ /***/ (function(module, exports) { /** @@ -67059,61 +67763,7 @@ module.exports = TweenData; /***/ }), -/* 263 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Modes. - * - * @namespace Phaser.ScaleModes - * @since 3.0.0 - */ - -var ScaleModes = { - - /** - * Default Scale Mode (Linear). - * - * @name Phaser.ScaleModes.DEFAULT - * @type {number} - * @readonly - * @since 3.0.0 - */ - DEFAULT: 0, - - /** - * Linear Scale Mode. - * - * @name Phaser.ScaleModes.LINEAR - * @type {number} - * @readonly - * @since 3.0.0 - */ - LINEAR: 0, - - /** - * Nearest Scale Mode. - * - * @name Phaser.ScaleModes.NEAREST - * @type {number} - * @readonly - * @since 3.0.0 - */ - NEAREST: 1 - -}; - -module.exports = ScaleModes; - - -/***/ }), -/* 264 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -67122,7 +67772,7 @@ module.exports = ScaleModes; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathWrap = __webpack_require__(64); +var MathWrap = __webpack_require__(66); /** * Wrap an angle. @@ -67145,7 +67795,7 @@ module.exports = Wrap; /***/ }), -/* 265 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -67154,7 +67804,7 @@ module.exports = Wrap; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Wrap = __webpack_require__(64); +var Wrap = __webpack_require__(66); /** * Wrap an angle in degrees. @@ -67176,656 +67826,6 @@ var WrapDegrees = function (angle) module.exports = WrapDegrees; -/***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * The ColorMatrix class creates a 5x4 matrix that can be used in shaders and graphics - * operations. It provides methods required to modify the color values, such as adjusting - * the brightness, setting a sepia tone, hue rotation and more. - * - * Use the method `getData` to return a Float32Array containing the current color values. - * - * @class ColorMatrix - * @memberof Phaser.Display - * @constructor - * @since 3.50.0 - */ -var ColorMatrix = new Class({ - - initialize: - - function ColorMatrix () - { - /** - * Internal ColorMatrix array. - * - * @name Phaser.Display.ColorMatrix#_matrix - * @type {number[]} - * @private - * @since 3.50.0 - */ - this._matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - - /** - * The value that determines how much of the original color is used - * when mixing the colors. A value between 0 (all original) and 1 (all final) - * - * @name Phaser.Display.ColorMatrix#alpha - * @type {number} - * @since 3.50.0 - */ - this.alpha = 1; - - /** - * Is the ColorMatrix array dirty? - * - * @name Phaser.Display.ColorMatrix#_dirty - * @type {boolean} - * @private - * @since 3.50.0 - */ - this._dirty = true; - - /** - * The matrix data as a Float32Array. - * - * Returned by the `getData` method. - * - * @name Phaser.Display.ColorMatrix#data - * @type {Float32Array} - * @private - * @since 3.50.0 - */ - this._data; - }, - - /** - * Sets this ColorMatrix from the given array of color values. - * - * @method Phaser.Display.ColorMatrix#set - * @since 3.50.0 - * - * @param {number[]} value - The ColorMatrix values to set. - * - * @return {this} This ColorMatrix instance. - */ - set: function (value) - { - this._matrix = value; - - this._dirty = true; - - return this; - }, - - /** - * Resets the ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#reset - * @since 3.50.0 - * - * @return {this} This ColorMatrix instance. - */ - reset: function () - { - // Long-winded, but saves on gc, which happens a lot in Post FX Shaders - // that reset the ColorMatrix every frame. - - var m = this._matrix; - - m[0] = 1; - m[1] = 0; - m[2] = 0; - m[3] = 0; - m[4] = 0; - - m[5] = 0; - m[6] = 1; - m[7] = 0; - m[8] = 0; - m[9] = 0; - - m[10] = 0; - m[11] = 0; - m[12] = 1; - m[13] = 0; - m[14] = 0; - - m[15] = 0; - m[16] = 0; - m[17] = 0; - m[18] = 1; - m[19] = 0; - - this._dirty = true; - - return this; - }, - - /** - * Gets the ColorMatrix as a Float32Array. - * - * Can be used directly as a 1fv shader uniform value. - * - * @method Phaser.Display.ColorMatrix#getData - * @since 3.50.0 - * - * @return {Float32Array} The ColorMatrix as a Float32Array. - */ - getData: function () - { - if (this._dirty) - { - var f32 = new Float32Array(this._matrix); - - f32[4] /= 255; - f32[9] /= 255; - f32[14] /= 255; - f32[19] /= 255; - - this._data = f32; - - this._dirty = false; - } - - return this._data; - }, - - /** - * Changes the brightness of this ColorMatrix by the given amount. - * - * @method Phaser.Display.ColorMatrix#brightness - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - brightness: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var b = value; - - return this.multiply([ - b, 0, 0, 0, 0, - 0, b, 0, 0, 0, - 0, 0, b, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Changes the saturation of this ColorMatrix by the given amount. - * - * @method Phaser.Display.ColorMatrix#saturate - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - saturate: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var x = (value * 2 / 3) + 1; - var y = ((x - 1) * -0.5); - - return this.multiply([ - x, y, y, 0, 0, - y, x, y, 0, 0, - y, y, x, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Desaturates this ColorMatrix (removes color from it). - * - * @method Phaser.Display.ColorMatrix#saturation - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - desaturate: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.saturate(-1, multiply); - }, - - /** - * Rotates the hues of this ColorMatrix by the value given. - * - * @method Phaser.Display.ColorMatrix#hue - * @since 3.50.0 - * - * @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - hue: function (rotation, multiply) - { - if (rotation === undefined) { rotation = 0; } - if (multiply === undefined) { multiply = false; } - - rotation = rotation / 180 * Math.PI; - - var cos = Math.cos(rotation); - var sin = Math.sin(rotation); - var lumR = 0.213; - var lumG = 0.715; - var lumB = 0.072; - - return this.multiply([ - lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0, - lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0, - lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Sets this ColorMatrix to be grayscale. - * - * @method Phaser.Display.ColorMatrix#grayscale - * @since 3.50.0 - * - * @param {number} [value=1] - The grayscale scale (0 is black). - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - grayscale: function (value, multiply) - { - if (value === undefined) { value = 1; } - if (multiply === undefined) { multiply = false; } - - return this.saturate(-value, multiply); - }, - - /** - * Sets this ColorMatrix to be black and white. - * - * @method Phaser.Display.ColorMatrix#blackWhite - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - blackWhite: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.3, 0.6, 0.1, 0, 0, - 0.3, 0.6, 0.1, 0, 0, - 0.3, 0.6, 0.1, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Change the contrast of this ColorMatrix by the amount given. - * - * @method Phaser.Display.ColorMatrix#contrast - * @since 3.50.0 - * - * @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - contrast: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } - - var v = value + 1; - var o = -0.5 * (v - 1); - - return this.multiply([ - v, 0, 0, 0, o, - 0, v, 0, 0, o, - 0, 0, v, 0, o, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Converts this ColorMatrix to have negative values. - * - * @method Phaser.Display.ColorMatrix#negative - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - negative: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - -1, 0, 0, 1, 0, - 0, -1, 0, 1, 0, - 0, 0, -1, 1, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Apply a desaturated luminance to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#desaturateLuminance - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - desaturateLuminance: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0.2764723, 0.9297080, 0.0938197, 0, -37.1, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a sepia tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#sepia - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - sepia: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.393, 0.7689999, 0.18899999, 0, 0, - 0.349, 0.6859999, 0.16799999, 0, 0, - 0.272, 0.5339999, 0.13099999, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a night vision tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#night - * @since 3.50.0 - * - * @param {number} [intensity=0.1] - The intensity of this effect. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - night: function (intensity, multiply) - { - if (intensity === undefined) { intensity = 0.1; } - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - intensity * (-2.0), -intensity, 0, 0, 0, - -intensity, 0, intensity, 0, 0, - 0, intensity, intensity * 2.0, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a trippy color tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#lsd - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - lsd: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 2, -0.4, 0.5, 0, 0, - -0.5, 2, -0.4, 0, 0, - -0.4, -0.5, 3, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a brown tone to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#brown - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - brown: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, - -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, - 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a vintage pinhole color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#vintagePinhole - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - vintagePinhole: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, - 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, - 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a kodachrome color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#kodachrome - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - kodachrome: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, - -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, - -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a technicolor color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#technicolor - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - technicolor: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, - -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, - -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Applies a polaroid color effect to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#polaroid - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - polaroid: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 1.438, -0.062, -0.062, 0, 0, - -0.122, 1.378, -0.122, 0, 0, - -0.016, -0.016, 1.483, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Shifts the values of this ColorMatrix into BGR order. - * - * @method Phaser.Display.ColorMatrix#shiftToBGR - * @since 3.50.0 - * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? - * - * @return {this} This ColorMatrix instance. - */ - shiftToBGR: function (multiply) - { - if (multiply === undefined) { multiply = false; } - - return this.multiply([ - 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); - }, - - /** - * Multiplies the two given matrices. - * - * @method Phaser.Display.ColorMatrix#multiply - * @since 3.50.0 - * - * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix. - * - * @return {this} This ColorMatrix instance. - */ - multiply: function (a, multiply) - { - // Duplicate _matrix into c - - if (!multiply) - { - this.reset(); - } - - var m = this._matrix; - var c = []; - - for (var i = 0; i < 20; i++) - { - c[i] = m[i]; - } - - // R - m[0] = (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]); - m[1] = (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]); - m[2] = (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]); - m[3] = (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]); - m[4] = (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4]; - - // G - m[5] = (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]); - m[6] = (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]); - m[7] = (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]); - m[8] = (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]); - m[9] = (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9]; - - // B - m[10] = (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]); - m[11] = (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]); - m[12] = (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]); - m[13] = (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]); - m[14] = (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14]; - - // A - m[15] = (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]); - m[16] = (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]); - m[17] = (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]); - m[18] = (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]); - m[19] = (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19]; - - this._dirty = true; - - return this; - } - -}); - -module.exports = ColorMatrix; - - /***/ }), /* 267 */ /***/ (function(module, exports, __webpack_require__) { @@ -68162,7 +68162,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = __webpack_require__(120); +var ALIGN_CONST = __webpack_require__(122); var AlignToMap = []; @@ -68742,7 +68742,7 @@ module.exports = TopRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = __webpack_require__(120); +var ALIGN_CONST = __webpack_require__(122); var AlignInMap = []; @@ -69226,7 +69226,7 @@ module.exports = TopRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CircumferencePoint = __webpack_require__(164); +var CircumferencePoint = __webpack_require__(165); var FromPercent = __webpack_require__(95); var MATH_CONST = __webpack_require__(14); var Point = __webpack_require__(4); @@ -69270,7 +69270,7 @@ module.exports = GetPoint; */ var Circumference = __webpack_require__(296); -var CircumferencePoint = __webpack_require__(164); +var CircumferencePoint = __webpack_require__(165); var FromPercent = __webpack_require__(95); var MATH_CONST = __webpack_require__(14); @@ -69349,7 +69349,7 @@ module.exports = Circumference; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); // bitmask flag for GameObject.renderMask var _FLAG = 2; // 0010 @@ -69459,7 +69459,7 @@ module.exports = AlphaSingle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); /** * Provides methods used for setting the blend mode of a Game Object. @@ -69678,7 +69678,7 @@ module.exports = Depth; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetPoint = __webpack_require__(166); +var GetPoint = __webpack_require__(167); var Perimeter = __webpack_require__(128); // Return an array of points from the perimeter of the rectangle @@ -69966,7 +69966,7 @@ module.exports = Mask; var Class = __webpack_require__(0); var GameEvents = __webpack_require__(22); -var RenderEvents = __webpack_require__(94); +var RenderEvents = __webpack_require__(88); /** * @classdesc @@ -70710,9 +70710,9 @@ module.exports = ScrollFactor; var MATH_CONST = __webpack_require__(14); var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(173); -var WrapAngle = __webpack_require__(264); -var WrapAngleDegrees = __webpack_require__(265); +var TransformXY = __webpack_require__(174); +var WrapAngle = __webpack_require__(265); +var WrapAngleDegrees = __webpack_require__(266); var Vector2 = __webpack_require__(3); // global bitmask flag for GameObject.renderMask (used by Scale) @@ -71935,7 +71935,7 @@ module.exports = SortByDigits; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Animation = __webpack_require__(181); +var Animation = __webpack_require__(182); var Class = __webpack_require__(0); var CustomMap = __webpack_require__(99); var EventEmitter = __webpack_require__(9); @@ -71943,7 +71943,7 @@ var Events = __webpack_require__(130); var GameEvents = __webpack_require__(22); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); -var Pad = __webpack_require__(182); +var Pad = __webpack_require__(183); var NumberArray = __webpack_require__(316); /** @@ -73480,12 +73480,12 @@ module.exports = CacheManager; */ var BaseCamera = __webpack_require__(131); -var CenterOn = __webpack_require__(186); -var Clamp = __webpack_require__(17); +var CenterOn = __webpack_require__(187); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Components = __webpack_require__(11); var Effects = __webpack_require__(327); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Linear = __webpack_require__(133); var Rectangle = __webpack_require__(10); var Vector2 = __webpack_require__(3); @@ -74288,7 +74288,7 @@ module.exports = Camera; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts a hex string into a Phaser Color object. @@ -74500,7 +74500,7 @@ module.exports = IntegerToRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts an object containing `r`, `g`, `b` and `a` properties into a Color class instance. @@ -74530,7 +74530,7 @@ module.exports = ObjectToColor; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); /** * Converts a CSS 'web' string into a Phaser Color object. @@ -74868,10 +74868,10 @@ var Device = __webpack_require__(341); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var IsPlainObject = __webpack_require__(7); -var PhaserMath = __webpack_require__(189); +var PhaserMath = __webpack_require__(190); var NOOP = __webpack_require__(1); -var DefaultPlugins = __webpack_require__(193); -var ValueToColor = __webpack_require__(183); +var DefaultPlugins = __webpack_require__(194); +var ValueToColor = __webpack_require__(184); /** * @classdesc @@ -75498,7 +75498,7 @@ module.exports = { os: __webpack_require__(102), browser: __webpack_require__(134), - features: __webpack_require__(187), + features: __webpack_require__(188), input: __webpack_require__(805), audio: __webpack_require__(806), video: __webpack_require__(807), @@ -76065,7 +76065,7 @@ module.exports = QuadraticBezierInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SmoothStep = __webpack_require__(180); +var SmoothStep = __webpack_require__(181); /** * A Smooth Step interpolation method. @@ -76791,7 +76791,7 @@ module.exports = Matrix3; var Class = __webpack_require__(0); var Matrix3 = __webpack_require__(358); var NOOP = __webpack_require__(1); -var Vector3 = __webpack_require__(36); +var Vector3 = __webpack_require__(37); var EPSILON = 0.000001; @@ -77837,7 +77837,7 @@ module.exports = Quaternion; var CanvasInterpolation = __webpack_require__(361); var CanvasPool = __webpack_require__(31); var CONST = __webpack_require__(39); -var Features = __webpack_require__(187); +var Features = __webpack_require__(188); /** * Called automatically by Phaser.Game and responsible for creating the renderer it will use. @@ -77927,8 +77927,8 @@ var CreateRenderer = function (game) if (true) { - CanvasRenderer = __webpack_require__(569); - WebGLRenderer = __webpack_require__(572); + CanvasRenderer = __webpack_require__(362); + WebGLRenderer = __webpack_require__(365); // Let the config pick the renderer type, as both are included if (config.renderType === CONST.WEBGL) @@ -78019,52200 +78019,6 @@ module.exports = CanvasInterpolation; /* 362 */ /***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(39); - -/** - * Called automatically by Phaser.Game and responsible for creating the console.log debug header. - * - * You can customize or disable the header via the Game Config object. - * - * @function Phaser.Core.DebugHeader - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance which will output this debug header. - */ -var DebugHeader = function (game) -{ - var config = game.config; - - if (config.hideBanner) - { - return; - } - - var renderType = 'WebGL'; - - if (config.renderType === CONST.CANVAS) - { - renderType = 'Canvas'; - } - else if (config.renderType === CONST.HEADLESS) - { - renderType = 'Headless'; - } - - var audioConfig = config.audio; - var deviceAudio = game.device.audio; - - var audioType; - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - audioType = 'Web Audio'; - } - else if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - audioType = 'No Audio'; - } - else - { - audioType = 'HTML5 Audio'; - } - - if (!game.device.browser.ie) - { - var c = ''; - var args = [ c ]; - - if (Array.isArray(config.bannerBackgroundColor)) - { - var lastColor; - - config.bannerBackgroundColor.forEach(function (color) - { - c = c.concat('%c '); - - args.push('background: ' + color); - - lastColor = color; - - }); - - // inject the text color - args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; - } - else - { - c = c.concat('%c '); - - args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); - } - - // URL link background color (always white) - args.push('background: #fff'); - - if (config.gameTitle) - { - c = c.concat(config.gameTitle); - - if (config.gameVersion) - { - c = c.concat(' v' + config.gameVersion); - } - - if (!config.hidePhaser) - { - c = c.concat(' / '); - } - } - - var fb = ( false) ? undefined : ''; - - if (!config.hidePhaser) - { - c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); - } - - c = c.concat(' %c ' + config.gameURL); - - // Inject the new string back into the args array - args[0] = c; - - console.log.apply(console, args); - } - else if (window['console']) - { - console.log('Phaser v' + CONST.VERSION + ' / https://phaser.io'); - } -}; - -module.exports = DebugHeader; - - -/***/ }), -/* 363 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetValue = __webpack_require__(6); -var NOOP = __webpack_require__(1); -var RequestAnimationFrame = __webpack_require__(364); - -// http://www.testufo.com/#test=animation-time-graph - -/** - * @classdesc - * The core runner class that Phaser uses to handle the game loop. It can use either Request Animation Frame, - * or SetTimeout, based on browser support and config settings, to create a continuous loop within the browser. - * - * Each time the loop fires, `TimeStep.step` is called and this is then passed onto the core Game update loop, - * it is the core heartbeat of your game. It will fire as often as Request Animation Frame is capable of handling - * on the target device. - * - * Note that there are lots of situations where a browser will stop updating your game. Such as if the player - * switches tabs, or covers up the browser window with another application. In these cases, the 'heartbeat' - * of your game will pause, and only resume when focus is returned to it by the player. There is no way to avoid - * this situation, all you can do is use the visibility events the browser, and Phaser, provide to detect when - * it has happened and then gracefully recover. - * - * @class TimeStep - * @memberof Phaser.Core - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step. - * @param {Phaser.Types.Core.FPSConfig} config - */ -var TimeStep = new Class({ - - initialize: - - function TimeStep (game, config) - { - /** - * A reference to the Phaser.Game instance. - * - * @name Phaser.Core.TimeStep#game - * @type {Phaser.Game} - * @readonly - * @since 3.0.0 - */ - this.game = game; - - /** - * The Request Animation Frame DOM Event handler. - * - * @name Phaser.Core.TimeStep#raf - * @type {Phaser.DOM.RequestAnimationFrame} - * @readonly - * @since 3.0.0 - */ - this.raf = new RequestAnimationFrame(); - - /** - * A flag that is set once the TimeStep has started running and toggled when it stops. - * - * @name Phaser.Core.TimeStep#started - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.started = false; - - /** - * A flag that is set once the TimeStep has started running and toggled when it stops. - * The difference between this value and `started` is that `running` is toggled when - * the TimeStep is sent to sleep, where-as `started` remains `true`, only changing if - * the TimeStep is actually stopped, not just paused. - * - * @name Phaser.Core.TimeStep#running - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.running = false; - - /** - * The minimum fps rate you want the Time Step to run at. - * - * @name Phaser.Core.TimeStep#minFps - * @type {number} - * @default 5 - * @since 3.0.0 - */ - this.minFps = GetValue(config, 'min', 5); - - /** - * The target fps rate for the Time Step to run at. - * - * Setting this value will not actually change the speed at which the browser runs, that is beyond - * the control of Phaser. Instead, it allows you to determine performance issues and if the Time Step - * is spiraling out of control. - * - * @name Phaser.Core.TimeStep#targetFps - * @type {number} - * @default 60 - * @since 3.0.0 - */ - this.targetFps = GetValue(config, 'target', 60); - - /** - * The minFps value in ms. - * Defaults to 200ms between frames (i.e. super slow!) - * - * @name Phaser.Core.TimeStep#_min - * @type {number} - * @private - * @since 3.0.0 - */ - this._min = 1000 / this.minFps; - - /** - * The targetFps value in ms. - * Defaults to 16.66ms between frames (i.e. normal) - * - * @name Phaser.Core.TimeStep#_target - * @type {number} - * @private - * @since 3.0.0 - */ - this._target = 1000 / this.targetFps; - - /** - * An exponential moving average of the frames per second. - * - * @name Phaser.Core.TimeStep#actualFps - * @type {number} - * @readonly - * @default 60 - * @since 3.0.0 - */ - this.actualFps = this.targetFps; - - /** - * The time at which the next fps rate update will take place. - * When an fps update happens, the `framesThisSecond` value is reset. - * - * @name Phaser.Core.TimeStep#nextFpsUpdate - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.nextFpsUpdate = 0; - - /** - * The number of frames processed this second. - * - * @name Phaser.Core.TimeStep#framesThisSecond - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.framesThisSecond = 0; - - /** - * A callback to be invoked each time the Time Step steps. - * - * @name Phaser.Core.TimeStep#callback - * @type {Phaser.Types.Core.TimeStepCallback} - * @default NOOP - * @since 3.0.0 - */ - this.callback = NOOP; - - /** - * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting - * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time. - * - * @name Phaser.Core.TimeStep#forceSetTimeOut - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.forceSetTimeOut = GetValue(config, 'forceSetTimeOut', false); - - /** - * The time, calculated at the start of the current step, as smoothed by the delta value. - * - * @name Phaser.Core.TimeStep#time - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.time = 0; - - /** - * The time at which the game started running. This value is adjusted if the game is then - * paused and resumes. - * - * @name Phaser.Core.TimeStep#startTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * The time, as returned by `performance.now` of the previous step. - * - * @name Phaser.Core.TimeStep#lastTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lastTime = 0; - - /** - * The current frame the game is on. This counter is incremented once every game step, regardless of how much - * time has passed and is unaffected by delta smoothing. - * - * @name Phaser.Core.TimeStep#frame - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.frame = 0; - - /** - * Is the browser currently considered in focus by the Page Visibility API? - * This value is set in the `blur` method, which is called automatically by the Game instance. - * - * @name Phaser.Core.TimeStep#inFocus - * @type {boolean} - * @readonly - * @default true - * @since 3.0.0 - */ - this.inFocus = true; - - /** - * The timestamp at which the game became paused, as determined by the Page Visibility API. - * - * @name Phaser.Core.TimeStep#_pauseTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._pauseTime = 0; - - /** - * An internal counter to allow for the browser 'cooling down' after coming back into focus. - * - * @name Phaser.Core.TimeStep#_coolDown - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._coolDown = 0; - - /** - * The delta time, in ms, since the last game step. This is a clamped and smoothed average value. - * - * @name Phaser.Core.TimeStep#delta - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.delta = 0; - - /** - * Internal index of the delta history position. - * - * @name Phaser.Core.TimeStep#deltaIndex - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.deltaIndex = 0; - - /** - * Internal array holding the previous delta values, used for delta smoothing. - * - * @name Phaser.Core.TimeStep#deltaHistory - * @type {number[]} - * @since 3.0.0 - */ - this.deltaHistory = []; - - /** - * The maximum number of delta values that are retained in order to calculate a smoothed moving average. - * - * This can be changed in the Game Config via the `fps.deltaHistory` property. The default is 10. - * - * @name Phaser.Core.TimeStep#deltaSmoothingMax - * @type {number} - * @default 10 - * @since 3.0.0 - */ - this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10); - - /** - * The number of frames that the cooldown is set to after the browser panics over the FPS rate, usually - * as a result of switching tabs and regaining focus. - * - * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120. - * - * @name Phaser.Core.TimeStep#panicMax - * @type {number} - * @default 120 - * @since 3.0.0 - */ - this.panicMax = GetValue(config, 'panicMax', 120); - - /** - * The actual elapsed time in ms between one update and the next. - * - * Unlike with `delta`, no smoothing, capping, or averaging is applied to this value. - * So please be careful when using this value in math calculations. - * - * @name Phaser.Core.TimeStep#rawDelta - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.rawDelta = 0; - - /** - * The time, as returned by `performance.now` at the very start of the current step. - * This can differ from the `time` value in that it isn't calculated based on the delta value. - * - * @name Phaser.Core.TimeStep#now - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.now = 0; - - /** - * Apply smoothing to the delta value used within Phasers internal calculations? - * - * This can be changed in the Game Config via the `fps.smoothStep` property. The default is `true`. - * - * Smoothing helps settle down the delta values after browser tab switches, or other situations - * which could cause significant delta spikes or dips. By default it has been enabled in Phaser 3 - * since the first version, but is now exposed under this property (and the corresponding game config - * `smoothStep` value), to allow you to easily disable it, should you require. - * - * @name Phaser.Core.TimeStep#smoothStep - * @type {boolean} - * @since 3.22.0 - */ - this.smoothStep = GetValue(config, 'smoothStep', true); - }, - - /** - * Called by the Game instance when the DOM window.onBlur event triggers. - * - * @method Phaser.Core.TimeStep#blur - * @since 3.0.0 - */ - blur: function () - { - this.inFocus = false; - }, - - /** - * Called by the Game instance when the DOM window.onFocus event triggers. - * - * @method Phaser.Core.TimeStep#focus - * @since 3.0.0 - */ - focus: function () - { - this.inFocus = true; - - this.resetDelta(); - }, - - /** - * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc) - * - * @method Phaser.Core.TimeStep#pause - * @since 3.0.0 - */ - pause: function () - { - this._pauseTime = window.performance.now(); - }, - - /** - * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc) - * - * @method Phaser.Core.TimeStep#resume - * @since 3.0.0 - */ - resume: function () - { - this.resetDelta(); - - this.startTime += this.time - this._pauseTime; - }, - - /** - * Resets the time, lastTime, fps averages and delta history. - * Called automatically when a browser sleeps them resumes. - * - * @method Phaser.Core.TimeStep#resetDelta - * @since 3.0.0 - */ - resetDelta: function () - { - var now = window.performance.now(); - - this.time = now; - this.lastTime = now; - this.nextFpsUpdate = now + 1000; - this.framesThisSecond = 0; - - // Pre-populate smoothing array - - for (var i = 0; i < this.deltaSmoothingMax; i++) - { - this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]); - } - - this.delta = 0; - this.deltaIndex = 0; - - this._coolDown = this.panicMax; - }, - - /** - * Starts the Time Step running, if it is not already doing so. - * Called automatically by the Game Boot process. - * - * @method Phaser.Core.TimeStep#start - * @since 3.0.0 - * - * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps. - */ - start: function (callback) - { - if (this.started) - { - return this; - } - - this.started = true; - this.running = true; - - for (var i = 0; i < this.deltaSmoothingMax; i++) - { - this.deltaHistory[i] = this._target; - } - - this.resetDelta(); - - this.startTime = window.performance.now(); - - this.callback = callback; - - this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target); - }, - - /** - * The main step method. This is called each time the browser updates, either by Request Animation Frame, - * or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more. - * You generally should never call this method directly. - * - * @method Phaser.Core.TimeStep#step - * @since 3.0.0 - */ - step: function () - { - // Because the timestamp passed in from raf represents the beginning of the main thread frame that we’re currently in, - // not the actual time now, and as we want to compare this time value against Event timeStamps and the like, we need a - // more accurate one: - - var time = window.performance.now(); - - this.now = time; - - var before = time - this.lastTime; - - if (before < 0) - { - // Because, Chrome. - before = 0; - } - - this.rawDelta = before; - - var idx = this.deltaIndex; - var history = this.deltaHistory; - var max = this.deltaSmoothingMax; - - // delta time (time is in ms) - var dt = before; - - // Delta Average - var avg = before; - - // When a browser switches tab, then comes back again, it takes around 10 frames before - // the delta time settles down so we employ a 'cooling down' period before we start - // trusting the delta values again, to avoid spikes flooding through our delta average - - if (this.smoothStep) - { - if (this._coolDown > 0 || !this.inFocus) - { - this._coolDown--; - - dt = Math.min(dt, this._target); - } - - if (dt > this._min) - { - // Probably super bad start time or browser tab context loss, - // so use the last 'sane' dt value - - dt = history[idx]; - - // Clamp delta to min (in case history has become corrupted somehow) - dt = Math.min(dt, this._min); - } - - // Smooth out the delta over the previous X frames - - // add the delta to the smoothing array - history[idx] = dt; - - // adjusts the delta history array index based on the smoothing count - // this stops the array growing beyond the size of deltaSmoothingMax - this.deltaIndex++; - - if (this.deltaIndex > max) - { - this.deltaIndex = 0; - } - - // Loop the history array, adding the delta values together - avg = 0; - - for (var i = 0; i < max; i++) - { - avg += history[i]; - } - - // Then divide by the array length to get the average delta - avg /= max; - } - - // Set as the world delta value - this.delta = avg; - - // Real-world timer advance - this.time += this.rawDelta; - - // Update the estimate of the frame rate, `fps`. Every second, the number - // of frames that occurred in that second are included in an exponential - // moving average of all frames per second, with an alpha of 0.25. This - // means that more recent seconds affect the estimated frame rate more than - // older seconds. - // - // When a browser window is NOT minimized, but is covered up (i.e. you're using - // another app which has spawned a window over the top of the browser), then it - // will start to throttle the raf callback time. It waits for a while, and then - // starts to drop the frame rate at 1 frame per second until it's down to just over 1fps. - // So if the game was running at 60fps, and the player opens a new window, then - // after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz. - // - // When they make the game visible again, the frame rate is increased at a rate of - // approx. 8fps, back up to 60fps (or the max it can obtain) - // - // There is no easy way to determine if this drop in frame rate is because the - // browser is throttling raf, or because the game is struggling with performance - // because you're asking it to do too much on the device. - - if (time > this.nextFpsUpdate) - { - // Compute the new exponential moving average with an alpha of 0.25. - this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps; - this.nextFpsUpdate = time + 1000; - this.framesThisSecond = 0; - } - - this.framesThisSecond++; - - // Interpolation - how far between what is expected and where we are? - var interpolation = avg / this._target; - - this.callback(time, avg, interpolation); - - // Shift time value over - this.lastTime = time; - - this.frame++; - }, - - /** - * Manually calls `TimeStep.step`. - * - * @method Phaser.Core.TimeStep#tick - * @since 3.0.0 - */ - tick: function () - { - this.step(); - }, - - /** - * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false. - * - * @method Phaser.Core.TimeStep#sleep - * @since 3.0.0 - */ - sleep: function () - { - if (this.running) - { - this.raf.stop(); - - this.running = false; - } - }, - - /** - * Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true. - * The `seamless` argument controls if the wake-up should adjust the start time or not. - * - * @method Phaser.Core.TimeStep#wake - * @since 3.0.0 - * - * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values. - */ - wake: function (seamless) - { - if (this.running) - { - return; - } - else if (seamless) - { - this.startTime += -this.lastTime + (this.lastTime + window.performance.now()); - } - - this.raf.start(this.step.bind(this), this.useRAF); - - this.running = true; - - this.step(); - }, - - /** - * Gets the duration which the game has been running, in seconds. - * - * @method Phaser.Core.TimeStep#getDuration - * @since 3.17.0 - * - * @return {number} The duration in seconds. - */ - getDuration: function () - { - return Math.round(this.lastTime - this.startTime) / 1000; - }, - - /** - * Gets the duration which the game has been running, in ms. - * - * @method Phaser.Core.TimeStep#getDurationMS - * @since 3.17.0 - * - * @return {number} The duration in ms. - */ - getDurationMS: function () - { - return Math.round(this.lastTime - this.startTime); - }, - - /** - * Stops the TimeStep running. - * - * @method Phaser.Core.TimeStep#stop - * @since 3.0.0 - * - * @return {this} The TimeStep object. - */ - stop: function () - { - this.running = false; - this.started = false; - - this.raf.stop(); - - return this; - }, - - /** - * Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null - * any objects. - * - * @method Phaser.Core.TimeStep#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stop(); - - this.callback = NOOP; - - this.raf = null; - this.game = null; - } - -}); - -module.exports = TimeStep; - - -/***/ }), -/* 364 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * Abstracts away the use of RAF or setTimeOut for the core game update loop. - * This is invoked automatically by the Phaser.Game instance. - * - * @class RequestAnimationFrame - * @memberof Phaser.DOM - * @constructor - * @since 3.0.0 - */ -var RequestAnimationFrame = new Class({ - - initialize: - - function RequestAnimationFrame () - { - /** - * True if RequestAnimationFrame is running, otherwise false. - * - * @name Phaser.DOM.RequestAnimationFrame#isRunning - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isRunning = false; - - /** - * The callback to be invoked each step. - * - * @name Phaser.DOM.RequestAnimationFrame#callback - * @type {FrameRequestCallback} - * @since 3.0.0 - */ - this.callback = NOOP; - - /** - * The most recent timestamp. Either a DOMHighResTimeStamp under RAF or `Date.now` under SetTimeout. - * - * @name Phaser.DOM.RequestAnimationFrame#tick - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.tick = 0; - - /** - * True if the step is using setTimeout instead of RAF. - * - * @name Phaser.DOM.RequestAnimationFrame#isSetTimeOut - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isSetTimeOut = false; - - /** - * The setTimeout or RAF callback ID used when canceling them. - * - * @name Phaser.DOM.RequestAnimationFrame#timeOutID - * @type {?number} - * @default null - * @since 3.0.0 - */ - this.timeOutID = null; - - /** - * The previous time the step was called. - * - * @name Phaser.DOM.RequestAnimationFrame#lastTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lastTime = 0; - - /** - * The target FPS rate in ms. - * Only used when setTimeout is used instead of RAF. - * - * @name Phaser.DOM.RequestAnimationFrame#target - * @type {number} - * @default 0 - * @since 3.21.0 - */ - this.target = 0; - - var _this = this; - - /** - * The RAF step function. - * Updates the local tick value, invokes the callback and schedules another call to requestAnimationFrame. - * - * @name Phaser.DOM.RequestAnimationFrame#step - * @type {FrameRequestCallback} - * @since 3.0.0 - */ - this.step = function step () - { - // Because we cannot trust the time passed to this callback from the browser and need it kept in sync with event times - var timestamp = window.performance.now(); - - // DOMHighResTimeStamp - _this.lastTime = _this.tick; - - _this.tick = timestamp; - - _this.callback(timestamp); - - _this.timeOutID = window.requestAnimationFrame(step); - }; - - /** - * The SetTimeout step function. - * Updates the local tick value, invokes the callback and schedules another call to setTimeout. - * - * @name Phaser.DOM.RequestAnimationFrame#stepTimeout - * @type {function} - * @since 3.0.0 - */ - this.stepTimeout = function stepTimeout () - { - var d = Date.now(); - - var delay = Math.min(Math.max(_this.target * 2 + _this.tick - d, 0), _this.target); - - _this.lastTime = _this.tick; - - _this.tick = d; - - _this.callback(d); - - _this.timeOutID = window.setTimeout(stepTimeout, delay); - }; - }, - - /** - * Starts the requestAnimationFrame or setTimeout process running. - * - * @method Phaser.DOM.RequestAnimationFrame#start - * @since 3.0.0 - * - * @param {FrameRequestCallback} callback - The callback to invoke each step. - * @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available? - * @param {number} targetFPS - The target fps rate (in ms). Only used when setTimeout is used. - */ - start: function (callback, forceSetTimeOut, targetFPS) - { - if (this.isRunning) - { - return; - } - - this.callback = callback; - - this.isSetTimeOut = forceSetTimeOut; - - this.target = targetFPS; - - this.isRunning = true; - - this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); - }, - - /** - * Stops the requestAnimationFrame or setTimeout from running. - * - * @method Phaser.DOM.RequestAnimationFrame#stop - * @since 3.0.0 - */ - stop: function () - { - this.isRunning = false; - - if (this.isSetTimeOut) - { - clearTimeout(this.timeOutID); - } - else - { - window.cancelAnimationFrame(this.timeOutID); - } - }, - - /** - * Stops the step from running and clears the callback reference. - * - * @method Phaser.DOM.RequestAnimationFrame#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stop(); - - this.callback = NOOP; - } - -}); - -module.exports = RequestAnimationFrame; - - -/***/ }), -/* 365 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Events = __webpack_require__(22); - -/** - * The Visibility Handler is responsible for listening out for document level visibility change events. - * This includes `visibilitychange` if the browser supports it, and blur and focus events. It then uses - * the provided Event Emitter and fires the related events. - * - * @function Phaser.Core.VisibilityHandler - * @fires Phaser.Core.Events#BLUR - * @fires Phaser.Core.Events#FOCUS - * @fires Phaser.Core.Events#HIDDEN - * @fires Phaser.Core.Events#VISIBLE - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. - */ -var VisibilityHandler = function (game) -{ - var hiddenVar; - var eventEmitter = game.events; - - if (document.hidden !== undefined) - { - hiddenVar = 'visibilitychange'; - } - else - { - var vendors = [ 'webkit', 'moz', 'ms' ]; - - vendors.forEach(function (prefix) - { - if (document[prefix + 'Hidden'] !== undefined) - { - document.hidden = function () - { - return document[prefix + 'Hidden']; - }; - - hiddenVar = prefix + 'visibilitychange'; - } - - }); - } - - var onChange = function (event) - { - if (document.hidden || event.type === 'pause') - { - eventEmitter.emit(Events.HIDDEN); - } - else - { - eventEmitter.emit(Events.VISIBLE); - } - }; - - if (hiddenVar) - { - document.addEventListener(hiddenVar, onChange, false); - } - - window.onblur = function () - { - eventEmitter.emit(Events.BLUR); - }; - - window.onfocus = function () - { - eventEmitter.emit(Events.FOCUS); - }; - - // Automatically give the window focus unless config says otherwise - if (window.focus && game.config.autoFocus) - { - window.focus(); - } -}; - -module.exports = VisibilityHandler; - - -/***/ }), -/* 366 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Arne16 = __webpack_require__(367); -var CanvasPool = __webpack_require__(31); -var GetValue = __webpack_require__(6); - -/** - * Generates a texture based on the given Create configuration object. - * - * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the - * data cells map to a single color. For example, if the texture config looked like this: - * - * ```javascript - * var star = [ - * '.....828.....', - * '....72227....', - * '....82228....', - * '...7222227...', - * '2222222222222', - * '8222222222228', - * '.72222222227.', - * '..787777787..', - * '..877777778..', - * '.78778887787.', - * '.27887.78872.', - * '.787.....787.' - * ]; - * - * this.textures.generate('star', { data: star, pixelWidth: 4 }); - * ``` - * - * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array - * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color - * number 8 in the palette. If a cell contains a period character `.` then it is transparent. - * - * The default palette is Arne16, but you can specify your own using the `palette` property. - * - * @function Phaser.Create.GenerateTexture - * @since 3.0.0 - * - * @param {Phaser.Types.Create.GenerateTextureConfig} config - The Generate Texture Configuration object. - * - * @return {HTMLCanvasElement} An HTMLCanvasElement which contains the generated texture drawn to it. - */ -var GenerateTexture = function (config) -{ - var data = GetValue(config, 'data', []); - var canvas = GetValue(config, 'canvas', null); - var palette = GetValue(config, 'palette', Arne16); - var pixelWidth = GetValue(config, 'pixelWidth', 1); - var pixelHeight = GetValue(config, 'pixelHeight', pixelWidth); - var resizeCanvas = GetValue(config, 'resizeCanvas', true); - var clearCanvas = GetValue(config, 'clearCanvas', true); - var preRender = GetValue(config, 'preRender', null); - var postRender = GetValue(config, 'postRender', null); - - var width = Math.floor(Math.abs(data[0].length * pixelWidth)); - var height = Math.floor(Math.abs(data.length * pixelHeight)); - - if (!canvas) - { - canvas = CanvasPool.create2D(this, width, height); - resizeCanvas = false; - clearCanvas = false; - } - - if (resizeCanvas) - { - canvas.width = width; - canvas.height = height; - } - - var ctx = canvas.getContext('2d'); - - if (clearCanvas) - { - ctx.clearRect(0, 0, width, height); - } - - // preRender Callback? - if (preRender) - { - preRender(canvas, ctx); - } - - // Draw it - for (var y = 0; y < data.length; y++) - { - var row = data[y]; - - for (var x = 0; x < row.length; x++) - { - var d = row[x]; - - if (d !== '.' && d !== ' ') - { - ctx.fillStyle = palette[d]; - ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight); - } - } - } - - // postRender Callback? - if (postRender) - { - postRender(canvas, ctx); - } - - return canvas; -}; - -module.exports = GenerateTexture; - - -/***/ }), -/* 367 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * A 16 color palette by [Arne](http://androidarts.com/palette/16pal.htm) - * - * @name Phaser.Create.Palettes.ARNE16 - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.exports = { - 0: '#000', - 1: '#9D9D9D', - 2: '#FFF', - 3: '#BE2633', - 4: '#E06F8B', - 5: '#493C2B', - 6: '#A46422', - 7: '#EB8931', - 8: '#F7E26B', - 9: '#2F484E', - A: '#44891A', - B: '#A3CE27', - C: '#1B2632', - D: '#005784', - E: '#31A2F2', - F: '#B2DCEF' -}; - - -/***/ }), -/* 368 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var CubicBezier = __webpack_require__(352); -var Curve = __webpack_require__(89); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A higher-order Bézier curve constructed of four points. - * - * @class CubicBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector2[])} p0 - Start point, or an array of point pairs. - * @param {Phaser.Math.Vector2} p1 - Control Point 1. - * @param {Phaser.Math.Vector2} p2 - Control Point 2. - * @param {Phaser.Math.Vector2} p3 - End Point. - */ -var CubicBezierCurve = new Class({ - - Extends: Curve, - - initialize: - - function CubicBezierCurve (p0, p1, p2, p3) - { - Curve.call(this, 'CubicBezierCurve'); - - if (Array.isArray(p0)) - { - p3 = new Vector2(p0[6], p0[7]); - p2 = new Vector2(p0[4], p0[5]); - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The start point of this curve. - * - * @name Phaser.Curves.CubicBezier#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = p0; - - /** - * The first control point of this curve. - * - * @name Phaser.Curves.CubicBezier#p1 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p1 = p1; - - /** - * The second control point of this curve. - * - * @name Phaser.Curves.CubicBezier#p2 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p2 = p2; - - /** - * The end point of this curve. - * - * @name Phaser.Curves.CubicBezier#p3 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p3 = p3; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.CubicBezier#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Returns the resolution of this curve. - * - * @method Phaser.Curves.CubicBezier#getResolution - * @since 3.0.0 - * - * @param {number} divisions - The amount of divisions used by this curve. - * - * @return {number} The resolution of the curve. - */ - getResolution: function (divisions) - { - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.CubicBezier#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var p0 = this.p0; - var p1 = this.p1; - var p2 = this.p2; - var p3 = this.p3; - - return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y)); - }, - - /** - * Draws this curve to the specified graphics object. - * - * @method Phaser.Curves.CubicBezier#draw - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - The graphics object this curve should be drawn to. - * @param {number} [pointsTotal=32] - The number of intermediary points that make up this curve. A higher number of points will result in a smoother curve. - * - * @return {Phaser.GameObjects.Graphics} The graphics object this curve was drawn to. Useful for method chaining. - */ - draw: function (graphics, pointsTotal) - { - if (pointsTotal === undefined) { pointsTotal = 32; } - - var points = this.getPoints(pointsTotal); - - graphics.beginPath(); - graphics.moveTo(this.p0.x, this.p0.y); - - for (var i = 1; i < points.length; i++) - { - graphics.lineTo(points[i].x, points[i].y); - } - - graphics.strokePath(); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Returns a JSON object that describes this curve. - * - * @method Phaser.Curves.CubicBezier#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y, - this.p2.x, this.p2.y, - this.p3.x, this.p3.y - ] - }; - } - -}); - -/** - * Generates a curve from a JSON object. - * - * @function Phaser.Curves.CubicBezier.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.CubicBezier} The curve generated from the JSON object. - */ -CubicBezierCurve.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - var p2 = new Vector2(points[4], points[5]); - var p3 = new Vector2(points[6], points[7]); - - return new CubicBezierCurve(p0, p1, p2, p3); -}; - -module.exports = CubicBezierCurve; - - -/***/ }), -/* 369 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var DegToRad = __webpack_require__(33); -var GetValue = __webpack_require__(6); -var RadToDeg = __webpack_require__(192); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * An Elliptical Curve derived from the Base Curve class. - * - * See https://en.wikipedia.org/wiki/Elliptic_curve for more details. - * - * @class Ellipse - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(number|Phaser.Types.Curves.EllipseCurveConfig)} [x=0] - The x coordinate of the ellipse, or an Ellipse Curve configuration object. - * @param {number} [y=0] - The y coordinate of the ellipse. - * @param {number} [xRadius=0] - The horizontal radius of ellipse. - * @param {number} [yRadius=0] - The vertical radius of ellipse. - * @param {number} [startAngle=0] - The start angle of the ellipse, in degrees. - * @param {number} [endAngle=360] - The end angle of the ellipse, in degrees. - * @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`). - * @param {number} [rotation=0] - The rotation of the ellipse, in degrees. - */ -var EllipseCurve = new Class({ - - Extends: Curve, - - initialize: - - function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) - { - if (typeof x === 'object') - { - var config = x; - - x = GetValue(config, 'x', 0); - y = GetValue(config, 'y', 0); - xRadius = GetValue(config, 'xRadius', 0); - yRadius = GetValue(config, 'yRadius', xRadius); - startAngle = GetValue(config, 'startAngle', 0); - endAngle = GetValue(config, 'endAngle', 360); - clockwise = GetValue(config, 'clockwise', false); - rotation = GetValue(config, 'rotation', 0); - } - else - { - if (yRadius === undefined) { yRadius = xRadius; } - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 360; } - if (clockwise === undefined) { clockwise = false; } - if (rotation === undefined) { rotation = 0; } - } - - Curve.call(this, 'EllipseCurve'); - - // Center point - - /** - * The center point of the ellipse. Used for calculating rotation. - * - * @name Phaser.Curves.Ellipse#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = new Vector2(x, y); - - /** - * The horizontal radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#_xRadius - * @type {number} - * @private - * @since 3.0.0 - */ - this._xRadius = xRadius; - - /** - * The vertical radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#_yRadius - * @type {number} - * @private - * @since 3.0.0 - */ - this._yRadius = yRadius; - - // Radians - - /** - * The starting angle of the ellipse in radians. - * - * @name Phaser.Curves.Ellipse#_startAngle - * @type {number} - * @private - * @since 3.0.0 - */ - this._startAngle = DegToRad(startAngle); - - /** - * The end angle of the ellipse in radians. - * - * @name Phaser.Curves.Ellipse#_endAngle - * @type {number} - * @private - * @since 3.0.0 - */ - this._endAngle = DegToRad(endAngle); - - /** - * Anti-clockwise direction. - * - * @name Phaser.Curves.Ellipse#_clockwise - * @type {boolean} - * @private - * @since 3.0.0 - */ - this._clockwise = clockwise; - - /** - * The rotation of the arc. - * - * @name Phaser.Curves.Ellipse#_rotation - * @type {number} - * @private - * @since 3.0.0 - */ - this._rotation = DegToRad(rotation); - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Ellipse#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return this.getPoint(0, out); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.Ellipse#getResolution - * @since 3.0.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions * 2; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Ellipse#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var twoPi = Math.PI * 2; - var deltaAngle = this._endAngle - this._startAngle; - var samePoints = Math.abs(deltaAngle) < Number.EPSILON; - - // ensures that deltaAngle is 0 .. 2 PI - while (deltaAngle < 0) - { - deltaAngle += twoPi; - } - - while (deltaAngle > twoPi) - { - deltaAngle -= twoPi; - } - - if (deltaAngle < Number.EPSILON) - { - if (samePoints) - { - deltaAngle = 0; - } - else - { - deltaAngle = twoPi; - } - } - - if (this._clockwise && !samePoints) - { - if (deltaAngle === twoPi) - { - deltaAngle = - twoPi; - } - else - { - deltaAngle = deltaAngle - twoPi; - } - } - - var angle = this._startAngle + t * deltaAngle; - var x = this.p0.x + this._xRadius * Math.cos(angle); - var y = this.p0.y + this._yRadius * Math.sin(angle); - - if (this._rotation !== 0) - { - var cos = Math.cos(this._rotation); - var sin = Math.sin(this._rotation); - - var tx = x - this.p0.x; - var ty = y - this.p0.y; - - // Rotate the point about the center of the ellipse. - x = tx * cos - ty * sin + this.p0.x; - y = tx * sin + ty * cos + this.p0.y; - } - - return out.set(x, y); - }, - - /** - * Sets the horizontal radius of this curve. - * - * @method Phaser.Curves.Ellipse#setXRadius - * @since 3.0.0 - * - * @param {number} value - The horizontal radius of this curve. - * - * @return {this} This curve object. - */ - setXRadius: function (value) - { - this.xRadius = value; - - return this; - }, - - /** - * Sets the vertical radius of this curve. - * - * @method Phaser.Curves.Ellipse#setYRadius - * @since 3.0.0 - * - * @param {number} value - The vertical radius of this curve. - * - * @return {this} This curve object. - */ - setYRadius: function (value) - { - this.yRadius = value; - - return this; - }, - - /** - * Sets the width of this curve. - * - * @method Phaser.Curves.Ellipse#setWidth - * @since 3.0.0 - * - * @param {number} value - The width of this curve. - * - * @return {this} This curve object. - */ - setWidth: function (value) - { - this.xRadius = value / 2; - - return this; - }, - - /** - * Sets the height of this curve. - * - * @method Phaser.Curves.Ellipse#setHeight - * @since 3.0.0 - * - * @param {number} value - The height of this curve. - * - * @return {this} This curve object. - */ - setHeight: function (value) - { - this.yRadius = value / 2; - - return this; - }, - - /** - * Sets the start angle of this curve. - * - * @method Phaser.Curves.Ellipse#setStartAngle - * @since 3.0.0 - * - * @param {number} value - The start angle of this curve, in radians. - * - * @return {this} This curve object. - */ - setStartAngle: function (value) - { - this.startAngle = value; - - return this; - }, - - /** - * Sets the end angle of this curve. - * - * @method Phaser.Curves.Ellipse#setEndAngle - * @since 3.0.0 - * - * @param {number} value - The end angle of this curve, in radians. - * - * @return {this} This curve object. - */ - setEndAngle: function (value) - { - this.endAngle = value; - - return this; - }, - - /** - * Sets if this curve extends clockwise or anti-clockwise. - * - * @method Phaser.Curves.Ellipse#setClockwise - * @since 3.0.0 - * - * @param {boolean} value - The clockwise state of this curve. - * - * @return {this} This curve object. - */ - setClockwise: function (value) - { - this.clockwise = value; - - return this; - }, - - /** - * Sets the rotation of this curve. - * - * @method Phaser.Curves.Ellipse#setRotation - * @since 3.0.0 - * - * @param {number} value - The rotation of this curve, in radians. - * - * @return {this} This curve object. - */ - setRotation: function (value) - { - this.rotation = value; - - return this; - }, - - /** - * The x coordinate of the center of the ellipse. - * - * @name Phaser.Curves.Ellipse#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.p0.x; - }, - - set: function (value) - { - this.p0.x = value; - } - - }, - - /** - * The y coordinate of the center of the ellipse. - * - * @name Phaser.Curves.Ellipse#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.p0.y; - }, - - set: function (value) - { - this.p0.y = value; - } - - }, - - /** - * The horizontal radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#xRadius - * @type {number} - * @since 3.0.0 - */ - xRadius: { - - get: function () - { - return this._xRadius; - }, - - set: function (value) - { - this._xRadius = value; - } - - }, - - /** - * The vertical radius of the ellipse. - * - * @name Phaser.Curves.Ellipse#yRadius - * @type {number} - * @since 3.0.0 - */ - yRadius: { - - get: function () - { - return this._yRadius; - }, - - set: function (value) - { - this._yRadius = value; - } - - }, - - /** - * The start angle of the ellipse in degrees. - * - * @name Phaser.Curves.Ellipse#startAngle - * @type {number} - * @since 3.0.0 - */ - startAngle: { - - get: function () - { - return RadToDeg(this._startAngle); - }, - - set: function (value) - { - this._startAngle = DegToRad(value); - } - - }, - - /** - * The end angle of the ellipse in degrees. - * - * @name Phaser.Curves.Ellipse#endAngle - * @type {number} - * @since 3.0.0 - */ - endAngle: { - - get: function () - { - return RadToDeg(this._endAngle); - }, - - set: function (value) - { - this._endAngle = DegToRad(value); - } - - }, - - /** - * `true` if the ellipse rotation is clockwise or `false` if anti-clockwise. - * - * @name Phaser.Curves.Ellipse#clockwise - * @type {boolean} - * @since 3.0.0 - */ - clockwise: { - - get: function () - { - return this._clockwise; - }, - - set: function (value) - { - this._clockwise = value; - } - - }, - - /** - * The rotation of the ellipse, relative to the center, in degrees. - * - * @name Phaser.Curves.Ellipse#angle - * @type {number} - * @since 3.14.0 - */ - angle: { - - get: function () - { - return RadToDeg(this._rotation); - }, - - set: function (value) - { - this._rotation = DegToRad(value); - } - - }, - - /** - * The rotation of the ellipse, relative to the center, in radians. - * - * @name Phaser.Curves.Ellipse#rotation - * @type {number} - * @since 3.0.0 - */ - rotation: { - - get: function () - { - return this._rotation; - }, - - set: function (value) - { - this._rotation = value; - } - - }, - - /** - * JSON serialization of the curve. - * - * @method Phaser.Curves.Ellipse#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONEllipseCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - x: this.p0.x, - y: this.p0.y, - xRadius: this._xRadius, - yRadius: this._yRadius, - startAngle: RadToDeg(this._startAngle), - endAngle: RadToDeg(this._endAngle), - clockwise: this._clockwise, - rotation: RadToDeg(this._rotation) - }; - } - -}); - -/** - * Creates a curve from the provided Ellipse Curve Configuration object. - * - * @function Phaser.Curves.Ellipse.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. - */ -EllipseCurve.fromJSON = function (data) -{ - return new EllipseCurve(data); -}; - -module.exports = EllipseCurve; - - -/***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var FromPoints = __webpack_require__(194); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); - -var tmpVec2 = new Vector2(); - -/** - * @classdesc - * A LineCurve is a "curve" comprising exactly two points (a line segment). - * - * @class Line - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. - * @param {Phaser.Math.Vector2} [p1] - The second endpoint. - */ -var LineCurve = new Class({ - - Extends: Curve, - - initialize: - - // vec2s or array - function LineCurve (p0, p1) - { - Curve.call(this, 'LineCurve'); - - if (Array.isArray(p0)) - { - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The first endpoint. - * - * @name Phaser.Curves.Line#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = p0; - - /** - * The second endpoint. - * - * @name Phaser.Curves.Line#p1 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p1 = p1; - - // Override default Curve.arcLengthDivisions - - /** - * The quantity of arc length divisions within the curve. - * - * @name Phaser.Curves.Line#arcLengthDivisions - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.arcLengthDivisions = 1; - }, - - /** - * Returns a Rectangle where the position and dimensions match the bounds of this Curve. - * - * @method Phaser.Curves.Line#getBounds - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the bounds in. If not given a new Rectangle will be created. - * - * @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object. - */ - getBounds: function (out) - { - if (out === undefined) { out = new Rectangle(); } - - return FromPoints([ this.p0, this.p1 ], out); - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Line#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Gets the resolution of the line. - * - * @method Phaser.Curves.Line#getResolution - * @since 3.0.0 - * - * @param {number} [divisions=1] - The number of divisions to consider. - * - * @return {number} The resolution. Equal to the number of divisions. - */ - getResolution: function (divisions) - { - if (divisions === undefined) { divisions = 1; } - - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Line#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - if (t === 1) - { - return out.copy(this.p1); - } - - out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); - - return out; - }, - - // Line curve is linear, so we can overwrite default getPointAt - - /** - * Gets a point at a given position on the line. - * - * @method Phaser.Curves.Line#getPointAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPointAt: function (u, out) - { - return this.getPoint(u, out); - }, - - /** - * Gets the slope of the line as a unit vector. - * - * @method Phaser.Curves.Line#getTangent - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @return {Phaser.Math.Vector2} The tangent vector. - */ - getTangent: function () - { - var tangent = tmpVec2.copy(this.p1).subtract(this.p0); - - return tangent.normalize(); - }, - - /** - * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. - * - * @method Phaser.Curves.Line#getUtoTmapping - * @since 3.0.0 - * - * @param {number} u - A float between 0 and 1. - * @param {number} distance - The distance, in pixels. - * @param {number} [divisions] - Optional amount of divisions. - * - * @return {number} The equidistant value. - */ - getUtoTmapping: function (u, distance, divisions) - { - var t; - - if (distance) - { - var arcLengths = this.getLengths(divisions); - var lineLength = arcLengths[arcLengths.length - 1]; - - // Cannot overshoot the curve - var targetLineLength = Math.min(distance, lineLength); - - t = targetLineLength / lineLength; - } - else - { - t = u; - } - - return t; - }, - - // Override default Curve.draw because this is better than calling getPoints on a line! - - /** - * Draws this curve on the given Graphics object. - * - * The curve is drawn using `Graphics.lineBetween` so will be drawn at whatever the present Graphics line color is. - * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. - * - * @method Phaser.Curves.Line#draw - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn. - * - * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. - */ - draw: function (graphics) - { - graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Gets a JSON representation of the line. - * - * @method Phaser.Curves.Line#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y - ] - }; - } - -}); - -/** - * Configures this line from a JSON representation. - * - * @function Phaser.Curves.Line.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Line} A new LineCurve object. - */ -LineCurve.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - - return new LineCurve(p0, p1); -}; - -module.exports = LineCurve; - - -/***/ }), -/* 371 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A MoveTo Curve is a very simple curve consisting of only a single point. - * Its intended use is to move the ending point in a Path. - * - * @class MoveTo - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {number} [x=0] - `x` pixel coordinate. - * @param {number} [y=0] - `y` pixel coordinate. - */ -var MoveTo = new Class({ - - initialize: - - function MoveTo (x, y) - { - /** - * Denotes that this Curve does not influence the bounds, points, and drawing of its parent Path. Must be `false` or some methods in the parent Path will throw errors. - * - * @name Phaser.Curves.MoveTo#active - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.active = false; - - /** - * The lone point which this curve consists of. - * - * @name Phaser.Curves.MoveTo#p0 - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.p0 = new Vector2(x, y); - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.MoveTo#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Retrieves the point at given position in the curve. This will always return this curve's only point. - * - * @method Phaser.Curves.MoveTo#getPointAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The position in the path to retrieve, between 0 and 1. Not used. - * @param {Phaser.Math.Vector2} [out] - An optional vector in which to store the point. - * - * @return {Phaser.Math.Vector2} The modified `out` vector, or a new `Vector2` if none was provided. - */ - getPointAt: function (u, out) - { - return this.getPoint(u, out); - }, - - /** - * Gets the resolution of this curve. - * - * @method Phaser.Curves.MoveTo#getResolution - * @since 3.0.0 - * - * @return {number} The resolution of this curve. For a MoveTo the value is always 1. - */ - getResolution: function () - { - return 1; - }, - - /** - * Gets the length of this curve. - * - * @method Phaser.Curves.MoveTo#getLength - * @since 3.0.0 - * - * @return {number} The length of this curve. For a MoveTo the value is always 0. - */ - getLength: function () - { - return 0; - }, - - /** - * Converts this curve into a JSON-serializable object. - * - * @method Phaser.Curves.MoveTo#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} A primitive object with the curve's type and only point. - */ - toJSON: function () - { - return { - type: 'MoveTo', - points: [ - this.p0.x, this.p0.y - ] - }; - } - -}); - -module.exports = MoveTo; - - -/***/ }), -/* 372 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var QuadraticBezierInterpolation = __webpack_require__(353); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A quadratic Bézier curve constructed from two control points. - * - * @class QuadraticBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.2.0 - * - * @param {(Phaser.Math.Vector2|number[])} p0 - Start point, or an array of point pairs. - * @param {Phaser.Math.Vector2} p1 - Control Point 1. - * @param {Phaser.Math.Vector2} p2 - Control Point 2. - */ -var QuadraticBezier = new Class({ - - Extends: Curve, - - initialize: - - function QuadraticBezier (p0, p1, p2) - { - Curve.call(this, 'QuadraticBezier'); - - if (Array.isArray(p0)) - { - p2 = new Vector2(p0[4], p0[5]); - p1 = new Vector2(p0[2], p0[3]); - p0 = new Vector2(p0[0], p0[1]); - } - - /** - * The start point. - * - * @name Phaser.Curves.QuadraticBezier#p0 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p0 = p0; - - /** - * The first control point. - * - * @name Phaser.Curves.QuadraticBezier#p1 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p1 = p1; - - /** - * The second control point. - * - * @name Phaser.Curves.QuadraticBezier#p2 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 - */ - this.p2 = p2; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.QuadraticBezier#getStartPoint - * @since 3.2.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.p0); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.QuadraticBezier#getResolution - * @since 3.2.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.QuadraticBezier#getPoint - * @since 3.2.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var p0 = this.p0; - var p1 = this.p1; - var p2 = this.p2; - - return out.set( - QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x), - QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y) - ); - }, - - /** - * Draws this curve on the given Graphics object. - * - * The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is. - * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. - * - * @method Phaser.Curves.QuadraticBezier#draw - * @since 3.2.0 - * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] - * - * @param {Phaser.GameObjects.Graphics} graphics - `Graphics` object to draw onto. - * @param {number} [pointsTotal=32] - Number of points to be used for drawing the curve. Higher numbers result in smoother curve but require more processing. - * - * @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to. - */ - draw: function (graphics, pointsTotal) - { - if (pointsTotal === undefined) { pointsTotal = 32; } - - var points = this.getPoints(pointsTotal); - - graphics.beginPath(); - graphics.moveTo(this.p0.x, this.p0.y); - - for (var i = 1; i < points.length; i++) - { - graphics.lineTo(points[i].x, points[i].y); - } - - graphics.strokePath(); - - // So you can chain graphics calls - return graphics; - }, - - /** - * Converts the curve into a JSON compatible object. - * - * @method Phaser.Curves.QuadraticBezier#toJSON - * @since 3.2.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - return { - type: this.type, - points: [ - this.p0.x, this.p0.y, - this.p1.x, this.p1.y, - this.p2.x, this.p2.y - ] - }; - } - -}); - -/** - * Creates a curve from a JSON object, e. g. created by `toJSON`. - * - * @function Phaser.Curves.QuadraticBezier.fromJSON - * @since 3.2.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.QuadraticBezier} The created curve instance. - */ -QuadraticBezier.fromJSON = function (data) -{ - var points = data.points; - - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); - var p2 = new Vector2(points[4], points[5]); - - return new QuadraticBezier(p0, p1, p2); -}; - -module.exports = QuadraticBezier; - - -/***/ }), -/* 373 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) - -var CatmullRom = __webpack_require__(190); -var Class = __webpack_require__(0); -var Curve = __webpack_require__(89); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * Create a smooth 2d spline curve from a series of points. - * - * @class Spline - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2[]|number[]|number[][])} [points] - The points that configure the curve. - */ -var SplineCurve = new Class({ - - Extends: Curve, - - initialize: - - function SplineCurve (points) - { - if (points === undefined) { points = []; } - - Curve.call(this, 'SplineCurve'); - - /** - * The Vector2 points that configure the curve. - * - * @name Phaser.Curves.Spline#points - * @type {Phaser.Math.Vector2[]} - * @default [] - * @since 3.0.0 - */ - this.points = []; - - this.addPoints(points); - }, - - /** - * Add a list of points to the current list of Vector2 points of the curve. - * - * @method Phaser.Curves.Spline#addPoints - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve. - * - * @return {this} This curve object. - */ - addPoints: function (points) - { - for (var i = 0; i < points.length; i++) - { - var p = new Vector2(); - - if (typeof points[i] === 'number') - { - p.x = points[i]; - p.y = points[i + 1]; - i++; - } - else if (Array.isArray(points[i])) - { - // An array of arrays? - p.x = points[i][0]; - p.y = points[i][1]; - } - else - { - p.x = points[i].x; - p.y = points[i].y; - } - - this.points.push(p); - } - - return this; - }, - - /** - * Add a point to the current list of Vector2 points of the curve. - * - * @method Phaser.Curves.Spline#addPoint - * @since 3.0.0 - * - * @param {number} x - The x coordinate of this curve - * @param {number} y - The y coordinate of this curve - * - * @return {Phaser.Math.Vector2} The new Vector2 added to the curve - */ - addPoint: function (x, y) - { - var vec = new Vector2(x, y); - - this.points.push(vec); - - return vec; - }, - - /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Spline#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.points[0]); - }, - - /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.Spline#getResolution - * @since 3.0.0 - * - * @param {number} divisions - Optional divisions value. - * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions * this.points.length; - }, - - /** - * Get point at relative position in curve according to length. - * - * @method Phaser.Curves.Spline#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. - * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. - */ - getPoint: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var points = this.points; - - var point = (points.length - 1) * t; - - var intPoint = Math.floor(point); - - var weight = point - intPoint; - - var p0 = points[(intPoint === 0) ? intPoint : intPoint - 1]; - var p1 = points[intPoint]; - var p2 = points[(intPoint > points.length - 2) ? points.length - 1 : intPoint + 1]; - var p3 = points[(intPoint > points.length - 3) ? points.length - 1 : intPoint + 2]; - - return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); - }, - - /** - * Exports a JSON object containing this curve data. - * - * @method Phaser.Curves.Spline#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. - */ - toJSON: function () - { - var points = []; - - for (var i = 0; i < this.points.length; i++) - { - points.push(this.points[i].x); - points.push(this.points[i].y); - } - - return { - type: this.type, - points: points - }; - } - -}); - -/** - * Imports a JSON object containing this curve data. - * - * @function Phaser.Curves.Spline.fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. - * - * @return {Phaser.Curves.Spline} The spline curve created. - */ -SplineCurve.fromJSON = function (data) -{ - return new SplineCurve(data.points); -}; - -module.exports = SplineCurve; - - -/***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A BaseShader is a small resource class that contains the data required for a WebGL Shader to be created. - * - * It contains the raw source code to the fragment and vertex shader, as well as an object that defines - * the uniforms the shader requires, if any. - * - * BaseShaders are stored in the Shader Cache, available in a Scene via `this.cache.shaders` and are referenced - * by a unique key-based string. Retrieve them via `this.cache.shaders.get(key)`. - * - * BaseShaders are created automatically by the GLSL File Loader when loading an external shader resource. - * They can also be created at runtime, allowing you to use dynamically generated shader source code. - * - * Default fragment and vertex source is used if not provided in the constructor, setting-up a basic shader, - * suitable for debug rendering. - * - * @class BaseShader - * @memberof Phaser.Display - * @constructor - * @since 3.17.0 - * - * @param {string} key - The key of this shader. Must be unique within the shader cache. - * @param {string} [fragmentSrc] - The fragment source for the shader. - * @param {string} [vertexSrc] - The vertex source for the shader. - * @param {any} [uniforms] - Optional object defining the uniforms the shader uses. - */ -var BaseShader = new Class({ - - initialize: - - function BaseShader (key, fragmentSrc, vertexSrc, uniforms) - { - if (!fragmentSrc || fragmentSrc === '') - { - fragmentSrc = [ - 'precision mediump float;', - - 'uniform vec2 resolution;', - - 'varying vec2 fragCoord;', - - 'void main () {', - ' vec2 uv = fragCoord / resolution.xy;', - ' gl_FragColor = vec4(uv.xyx, 1.0);', - '}' - ].join('\n'); - } - - if (!vertexSrc || vertexSrc === '') - { - vertexSrc = [ - 'precision mediump float;', - - 'uniform mat4 uProjectionMatrix;', - 'uniform mat4 uViewMatrix;', - 'uniform vec2 uResolution;', - - 'attribute vec2 inPosition;', - - 'varying vec2 fragCoord;', - 'varying vec2 outTexCoord;', - - 'void main () {', - ' gl_Position = uProjectionMatrix * uViewMatrix * vec4(inPosition, 1.0, 1.0);', - ' fragCoord = vec2(inPosition.x, uResolution.y - inPosition.y);', - ' outTexCoord = vec2(inPosition.x / uResolution.x, fragCoord.y / uResolution.y);', - '}' - ].join('\n'); - } - - if (uniforms === undefined) { uniforms = null; } - - /** - * The key of this shader, unique within the shader cache of this Phaser game instance. - * - * @name Phaser.Display.BaseShader#key - * @type {string} - * @since 3.17.0 - */ - this.key = key; - - /** - * The source code, as a string, of the fragment shader being used. - * - * @name Phaser.Display.BaseShader#fragmentSrc - * @type {string} - * @since 3.17.0 - */ - this.fragmentSrc = fragmentSrc; - - /** - * The source code, as a string, of the vertex shader being used. - * - * @name Phaser.Display.BaseShader#vertexSrc - * @type {string} - * @since 3.17.0 - */ - this.vertexSrc = vertexSrc; - - /** - * The default uniforms for this shader. - * - * @name Phaser.Display.BaseShader#uniforms - * @type {?any} - * @since 3.17.0 - */ - this.uniforms = uniforms; - } - -}); - -module.exports = BaseShader; - - -/***/ }), -/* 375 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Color = __webpack_require__(35); - -Color.ColorSpectrum = __webpack_require__(905); -Color.ColorToRGBA = __webpack_require__(906); -Color.ComponentToHex = __webpack_require__(376); -Color.GetColor = __webpack_require__(100); -Color.GetColor32 = __webpack_require__(322); -Color.HexStringToColor = __webpack_require__(321); -Color.HSLToColor = __webpack_require__(907); -Color.HSVColorWheel = __webpack_require__(908); -Color.HSVToRGB = __webpack_require__(184); -Color.HueToComponent = __webpack_require__(377); -Color.IntegerToColor = __webpack_require__(185); -Color.IntegerToRGB = __webpack_require__(324); -Color.Interpolate = __webpack_require__(909); -Color.ObjectToColor = __webpack_require__(325); -Color.RandomRGB = __webpack_require__(910); -Color.RGBStringToColor = __webpack_require__(326); -Color.RGBToHSV = __webpack_require__(323); -Color.RGBToString = __webpack_require__(911); -Color.ValueToColor = __webpack_require__(183); - -module.exports = Color; - - -/***/ }), -/* 376 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns a string containing a hex representation of the given color component. - * - * @function Phaser.Display.Color.ComponentToHex - * @since 3.0.0 - * - * @param {number} color - The color channel to get the hex value for, must be a value between 0 and 255. - * - * @return {string} A string of length 2 characters, i.e. 255 = ff, 100 = 64. - */ -var ComponentToHex = function (color) -{ - var hex = color.toString(16); - - return (hex.length === 1) ? '0' + hex : hex; -}; - -module.exports = ComponentToHex; - - -/***/ }), -/* 377 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts a hue to an RGB color. - * Based on code by Michael Jackson (https://github.com/mjijackson) - * - * @function Phaser.Display.Color.HueToComponent - * @since 3.0.0 - * - * @param {number} p - * @param {number} q - * @param {number} t - * - * @return {number} The combined color value. - */ -var HueToComponent = function (p, q, t) -{ - if (t < 0) - { - t += 1; - } - - if (t > 1) - { - t -= 1; - } - - if (t < 1 / 6) - { - return p + (q - p) * 6 * t; - } - - if (t < 1 / 2) - { - return q; - } - - if (t < 2 / 3) - { - return p + (q - p) * (2 / 3 - t) * 6; - } - - return p; -}; - -module.exports = HueToComponent; - - -/***/ }), -/* 378 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var OS = __webpack_require__(102); - -/** - * @callback ContentLoadedCallback - */ - -/** - * Inspects the readyState of the document. If the document is already complete then it invokes the given callback. - * If not complete it sets up several event listeners such as `deviceready`, and once those fire, it invokes the callback. - * Called automatically by the Phaser.Game instance. Should not usually be accessed directly. - * - * @function Phaser.DOM.DOMContentLoaded - * @since 3.0.0 - * - * @param {ContentLoadedCallback} callback - The callback to be invoked when the device is ready and the DOM content is loaded. - */ -var DOMContentLoaded = function (callback) -{ - if (document.readyState === 'complete' || document.readyState === 'interactive') - { - callback(); - - return; - } - - var check = function () - { - document.removeEventListener('deviceready', check, true); - document.removeEventListener('DOMContentLoaded', check, true); - window.removeEventListener('load', check, true); - - callback(); - }; - - if (!document.body) - { - window.setTimeout(check, 20); - } - else if (OS.cordova) - { - // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready - document.addEventListener('deviceready', check, false); - } - else - { - document.addEventListener('DOMContentLoaded', check, true); - window.addEventListener('load', check, true); - } -}; - -module.exports = DOMContentLoaded; - - -/***/ }), -/* 379 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Attempts to determine the document inner height across iOS and standard devices. - * Based on code by @tylerjpeterson - * - * @function Phaser.DOM.GetInnerHeight - * @since 3.16.0 - * - * @param {boolean} iOS - Is this running on iOS? - * - * @return {number} The inner height value. - */ -var GetInnerHeight = function (iOS) -{ - - if (!iOS) - { - return window.innerHeight; - } - - var axis = Math.abs(window.orientation); - - var size = { w: 0, h: 0 }; - - var ruler = document.createElement('div'); - - ruler.setAttribute('style', 'position: fixed; height: 100vh; width: 0; top: 0'); - - document.documentElement.appendChild(ruler); - - size.w = (axis === 90) ? ruler.offsetHeight : window.innerWidth; - size.h = (axis === 90) ? window.innerWidth : ruler.offsetHeight; - - document.documentElement.removeChild(ruler); - - ruler = null; - - if (Math.abs(window.orientation) !== 90) - { - return size.h; - } - else - { - return size.w; - } -}; - -module.exports = GetInnerHeight; - - -/***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(196); - -/** - * Attempts to determine the screen orientation using the Orientation API. - * - * @function Phaser.DOM.GetScreenOrientation - * @since 3.16.0 - * - * @param {number} width - The width of the viewport. - * @param {number} height - The height of the viewport. - * - * @return {string} The orientation. - */ -var GetScreenOrientation = function (width, height) -{ - var screen = window.screen; - var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; - - if (orientation && typeof orientation.type === 'string') - { - // Screen Orientation API specification - return orientation.type; - } - else if (typeof orientation === 'string') - { - // moz / ms-orientation are strings - return orientation; - } - - if (typeof window.orientation === 'number') - { - // Do this check first, as iOS supports this, but also has an incomplete window.screen implementation - // This may change by device based on "natural" orientation. - return (window.orientation === 0 || window.orientation === 180) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; - } - else if (window.matchMedia) - { - if (window.matchMedia('(orientation: portrait)').matches) - { - return CONST.ORIENTATION.PORTRAIT; - } - else if (window.matchMedia('(orientation: landscape)').matches) - { - return CONST.ORIENTATION.LANDSCAPE; - } - } - else - { - return (height > width) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; - } -}; - -module.exports = GetScreenOrientation; - - -/***/ }), -/* 381 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for centering the game canvas. - * - * @namespace Phaser.Scale.Center - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for centering the game canvas. - * - * To find out what each mode does please see [Phaser.Scale.Center]{@link Phaser.Scale.Center}. - * - * @typedef {Phaser.Scale.Center} Phaser.Scale.CenterType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * The game canvas is not centered within the parent by Phaser. - * You can still center it yourself via CSS. - * - * @name Phaser.Scale.Center.NO_CENTER - * @type {number} - * @const - * @since 3.16.0 - */ - NO_CENTER: 0, - - /** - * The game canvas is centered both horizontally and vertically within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_BOTH - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_BOTH: 1, - - /** - * The game canvas is centered horizontally within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_HORIZONTALLY - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_HORIZONTALLY: 2, - - /** - * The game canvas is centered both vertically within the parent. - * To do this, the parent has to have a bounds that can be calculated and not be empty. - * - * Centering is achieved by setting the margin left and top properties of the - * game canvas, and does not factor in any other CSS styles you may have applied. - * - * @name Phaser.Scale.Center.CENTER_VERTICALLY - * @type {number} - * @const - * @since 3.16.0 - */ - CENTER_VERTICALLY: 3 - -}; - - -/***/ }), -/* 382 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for orientation. - * - * @namespace Phaser.Scale.Orientation - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for orientation. - * - * To find out what each mode does please see [Phaser.Scale.Orientation]{@link Phaser.Scale.Orientation}. - * - * @typedef {Phaser.Scale.Orientation} Phaser.Scale.OrientationType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * A landscape orientation. - * - * @name Phaser.Scale.Orientation.LANDSCAPE - * @type {string} - * @const - * @since 3.16.0 - */ - LANDSCAPE: 'landscape-primary', - - /** - * A portrait orientation. - * - * @name Phaser.Scale.Orientation.PORTRAIT - * @type {string} - * @const - * @since 3.16.0 - */ - PORTRAIT: 'portrait-primary' - -}; - - -/***/ }), -/* 383 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for the different scale modes available. - * - * @namespace Phaser.Scale.ScaleModes - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for the different scale modes available. - * - * To find out what each mode does please see [Phaser.Scale.ScaleModes]{@link Phaser.Scale.ScaleModes}. - * - * @typedef {Phaser.Scale.ScaleModes} Phaser.Scale.ScaleModeType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * No scaling happens at all. The canvas is set to the size given in the game config and Phaser doesn't change it - * again from that point on. If you change the canvas size, either via CSS, or directly via code, then you need - * to call the Scale Managers `resize` method to give the new dimensions, or input events will stop working. - * - * @name Phaser.Scale.ScaleModes.NONE - * @type {number} - * @const - * @since 3.16.0 - */ - NONE: 0, - - /** - * The height is automatically adjusted based on the width. - * - * @name Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT - * @type {number} - * @const - * @since 3.16.0 - */ - WIDTH_CONTROLS_HEIGHT: 1, - - /** - * The width is automatically adjusted based on the height. - * - * @name Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH - * @type {number} - * @const - * @since 3.16.0 - */ - HEIGHT_CONTROLS_WIDTH: 2, - - /** - * The width and height are automatically adjusted to fit inside the given target area, - * while keeping the aspect ratio. Depending on the aspect ratio there may be some space - * inside the area which is not covered. - * - * @name Phaser.Scale.ScaleModes.FIT - * @type {number} - * @const - * @since 3.16.0 - */ - FIT: 3, - - /** - * The width and height are automatically adjusted to make the size cover the entire target - * area while keeping the aspect ratio. This may extend further out than the target size. - * - * @name Phaser.Scale.ScaleModes.ENVELOP - * @type {number} - * @const - * @since 3.16.0 - */ - ENVELOP: 4, - - /** - * The Canvas is resized to fit all available _parent_ space, regardless of aspect ratio. - * - * @name Phaser.Scale.ScaleModes.RESIZE - * @type {number} - * @const - * @since 3.16.0 - */ - RESIZE: 5 - -}; - - -/***/ }), -/* 384 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Phaser Scale Manager constants for zoom modes. - * - * @namespace Phaser.Scale.Zoom - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -/** - * Phaser Scale Manager constants for zoom modes. - * - * To find out what each mode does please see [Phaser.Scale.Zoom]{@link Phaser.Scale.Zoom}. - * - * @typedef {Phaser.Scale.Zoom} Phaser.Scale.ZoomType - * @memberof Phaser.Scale - * @since 3.16.0 - */ - -module.exports = { - - /** - * The game canvas will not be zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.NO_ZOOM - * @type {number} - * @const - * @since 3.16.0 - */ - NO_ZOOM: 1, - - /** - * The game canvas will be 2x zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.ZOOM_2X - * @type {number} - * @const - * @since 3.16.0 - */ - ZOOM_2X: 2, - - /** - * The game canvas will be 4x zoomed by Phaser. - * - * @name Phaser.Scale.Zoom.ZOOM_4X - * @type {number} - * @const - * @since 3.16.0 - */ - ZOOM_4X: 4, - - /** - * Calculate the zoom value based on the maximum multiplied game size that will - * fit into the parent, or browser window if no parent is set. - * - * @name Phaser.Scale.Zoom.MAX_ZOOM - * @type {number} - * @const - * @since 3.16.0 - */ - MAX_ZOOM: -1 - -}; - - -/***/ }), -/* 385 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Attempts to get the target DOM element based on the given value, which can be either - * a string, in which case it will be looked-up by ID, or an element node. If nothing - * can be found it will return a reference to the document.body. - * - * @function Phaser.DOM.GetTarget - * @since 3.16.0 - * - * @param {HTMLElement} element - The DOM element to look-up. - */ -var GetTarget = function (element) -{ - var target; - - if (element !== '') - { - if (typeof element === 'string') - { - // Hopefully an element ID - target = document.getElementById(element); - } - else if (element && element.nodeType === 1) - { - // Quick test for a HTMLElement - target = element; - } - } - - // Fallback to the document body. Covers an invalid ID and a non HTMLElement object. - if (!target) - { - // Use the full window - target = document.body; - } - - return target; -}; - -module.exports = GetTarget; - - -/***/ }), -/* 386 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Takes the given data string and parses it as XML. - * First tries to use the window.DOMParser and reverts to the Microsoft.XMLDOM if that fails. - * The parsed XML object is returned, or `null` if there was an error while parsing the data. - * - * @function Phaser.DOM.ParseXML - * @since 3.0.0 - * - * @param {string} data - The XML source stored in a string. - * - * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. - */ -var ParseXML = function (data) -{ - var xml = ''; - - try - { - if (window['DOMParser']) - { - var domparser = new DOMParser(); - xml = domparser.parseFromString(data, 'text/xml'); - } - else - { - xml = new ActiveXObject('Microsoft.XMLDOM'); - xml.loadXML(data); - } - } - catch (e) - { - xml = null; - } - - if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) - { - return null; - } - else - { - return xml; - } -}; - -module.exports = ParseXML; - - -/***/ }), -/* 387 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(198); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(49); -var GameEvents = __webpack_require__(22); -var Keyboard = __webpack_require__(388); -var Mouse = __webpack_require__(389); -var Pointer = __webpack_require__(390); -var Touch = __webpack_require__(391); -var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(173); - -/** - * @classdesc - * The Input Manager is responsible for handling the pointer related systems in a single Phaser Game instance. - * - * Based on the Game Config it will create handlers for mouse and touch support. - * - * Keyboard and Gamepad are plugins, handled directly by the InputPlugin class. - * - * It then manages the events, pointer creation and general hit test related operations. - * - * You rarely need to interact with the Input Manager directly, and as such, all of its properties and methods - * should be considered private. Instead, you should use the Input Plugin, which is a Scene level system, responsible - * for dealing with all input events for a Scene. - * - * @class InputManager - * @memberof Phaser.Input - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Game instance that owns the Input Manager. - * @param {object} config - The Input Configuration object, as set in the Game Config. - */ -var InputManager = new Class({ - - initialize: - - function InputManager (game, config) - { - /** - * The Game instance that owns the Input Manager. - * A Game only maintains on instance of the Input Manager at any time. - * - * @name Phaser.Input.InputManager#game - * @type {Phaser.Game} - * @readonly - * @since 3.0.0 - */ - this.game = game; - - /** - * A reference to the global Game Scale Manager. - * Used for all bounds checks and pointer scaling. - * - * @name Phaser.Input.InputManager#scaleManager - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.0 - */ - this.scaleManager; - - /** - * The Canvas that is used for all DOM event input listeners. - * - * @name Phaser.Input.InputManager#canvas - * @type {HTMLCanvasElement} - * @since 3.0.0 - */ - this.canvas; - - /** - * The Game Configuration object, as set during the game boot. - * - * @name Phaser.Input.InputManager#config - * @type {Phaser.Core.Config} - * @since 3.0.0 - */ - this.config = config; - - /** - * If set, the Input Manager will run its update loop every frame. - * - * @name Phaser.Input.InputManager#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * The Event Emitter instance that the Input Manager uses to emit events from. - * - * @name Phaser.Input.InputManager#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = new EventEmitter(); - - /** - * Are any mouse or touch pointers currently over the game canvas? - * This is updated automatically by the canvas over and out handlers. - * - * @name Phaser.Input.InputManager#isOver - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - this.isOver = true; - - /** - * The default CSS cursor to be used when interacting with your game. - * - * See the `setDefaultCursor` method for more details. - * - * @name Phaser.Input.InputManager#defaultCursor - * @type {string} - * @since 3.10.0 - */ - this.defaultCursor = ''; - - /** - * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. - * - * @name Phaser.Input.InputManager#keyboard - * @type {?Phaser.Input.Keyboard.KeyboardManager} - * @since 3.16.0 - */ - this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; - - /** - * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. - * - * @name Phaser.Input.InputManager#mouse - * @type {?Phaser.Input.Mouse.MouseManager} - * @since 3.0.0 - */ - this.mouse = (config.inputMouse) ? new Mouse(this) : null; - - /** - * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. - * - * @name Phaser.Input.InputManager#touch - * @type {Phaser.Input.Touch.TouchManager} - * @since 3.0.0 - */ - this.touch = (config.inputTouch) ? new Touch(this) : null; - - /** - * An array of Pointers that have been added to the game. - * The first entry is reserved for the Mouse Pointer, the rest are Touch Pointers. - * - * By default there is 1 touch pointer enabled. If you need more use the `addPointer` method to start them, - * or set the `input.activePointers` property in the Game Config. - * - * @name Phaser.Input.InputManager#pointers - * @type {Phaser.Input.Pointer[]} - * @since 3.10.0 - */ - this.pointers = []; - - /** - * The number of touch objects activated and being processed each update. - * - * You can change this by either calling `addPointer` at run-time, or by - * setting the `input.activePointers` property in the Game Config. - * - * @name Phaser.Input.InputManager#pointersTotal - * @type {number} - * @readonly - * @since 3.10.0 - */ - this.pointersTotal = config.inputActivePointers; - - if (config.inputTouch && this.pointersTotal === 1) - { - this.pointersTotal = 2; - } - - for (var i = 0; i <= this.pointersTotal; i++) - { - var pointer = new Pointer(this, i); - - pointer.smoothFactor = config.inputSmoothFactor; - - this.pointers.push(pointer); - } - - /** - * The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_. - * If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer` - * which will always map to the most recently interacted pointer. - * - * @name Phaser.Input.InputManager#mousePointer - * @type {?Phaser.Input.Pointer} - * @since 3.10.0 - */ - this.mousePointer = (config.inputMouse) ? this.pointers[0] : null; - - /** - * The most recently active Pointer object. - * - * If you've only 1 Pointer in your game then this will accurately be either the first finger touched, or the mouse. - * - * If your game doesn't need to support multi-touch then you can safely use this property in all of your game - * code and it will adapt to be either the mouse or the touch, based on device. - * - * @name Phaser.Input.InputManager#activePointer - * @type {Phaser.Input.Pointer} - * @since 3.0.0 - */ - this.activePointer = this.pointers[0]; - - /** - * If the top-most Scene in the Scene List receives an input it will stop input from - * propagating any lower down the scene list, i.e. if you have a UI Scene at the top - * and click something on it, that click will not then be passed down to any other - * Scene below. Disable this to have input events passed through all Scenes, all the time. - * - * @name Phaser.Input.InputManager#globalTopOnly - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.globalTopOnly = true; - - /** - * The time this Input Manager was last updated. - * This value is populated by the Game Step each frame. - * - * @name Phaser.Input.InputManager#time - * @type {number} - * @readonly - * @since 3.16.2 - */ - this.time = 0; - - /** - * A re-cycled point-like object to store hit test values in. - * - * @name Phaser.Input.InputManager#_tempPoint - * @type {{x:number, y:number}} - * @private - * @since 3.0.0 - */ - this._tempPoint = { x: 0, y: 0 }; - - /** - * A re-cycled array to store hit results in. - * - * @name Phaser.Input.InputManager#_tempHitTest - * @type {array} - * @private - * @default [] - * @since 3.0.0 - */ - this._tempHitTest = []; - - /** - * A re-cycled matrix used in hit test calculations. - * - * @name Phaser.Input.InputManager#_tempMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.4.0 - */ - this._tempMatrix = new TransformMatrix(); - - /** - * A re-cycled matrix used in hit test calculations. - * - * @name Phaser.Input.InputManager#_tempMatrix2 - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - /** - * An internal private var that records Scenes aborting event processing. - * - * @name Phaser.Input.InputManager#_tempSkip - * @type {boolean} - * @private - * @since 3.18.0 - */ - this._tempSkip = false; - - /** - * An internal private array that avoids needing to create a new array on every DOM mouse event. - * - * @name Phaser.Input.InputManager#mousePointerContainer - * @type {Phaser.Input.Pointer[]} - * @private - * @since 3.18.0 - */ - this.mousePointerContainer = [ this.mousePointer ]; - - game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot handler is called by Phaser.Game when it first starts up. - * The renderer is available by now. - * - * @method Phaser.Input.InputManager#boot - * @protected - * @fires Phaser.Input.Events#MANAGER_BOOT - * @since 3.0.0 - */ - boot: function () - { - this.canvas = this.game.canvas; - - this.scaleManager = this.game.scale; - - this.events.emit(Events.MANAGER_BOOT); - - this.game.events.on(GameEvents.PRE_RENDER, this.preRender, this); - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * Internal canvas state change, called automatically by the Mouse Manager. - * - * @method Phaser.Input.InputManager#setCanvasOver - * @fires Phaser.Input.Events#GAME_OVER - * @private - * @since 3.16.0 - * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. - */ - setCanvasOver: function (event) - { - this.isOver = true; - - this.events.emit(Events.GAME_OVER, event); - }, - - /** - * Internal canvas state change, called automatically by the Mouse Manager. - * - * @method Phaser.Input.InputManager#setCanvasOut - * @fires Phaser.Input.Events#GAME_OUT - * @private - * @since 3.16.0 - * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. - */ - setCanvasOut: function (event) - { - this.isOver = false; - - this.events.emit(Events.GAME_OUT, event); - }, - - /** - * Internal update, called automatically by the Game Step right at the start. - * - * @method Phaser.Input.InputManager#preRender - * @private - * @since 3.18.0 - */ - preRender: function () - { - var time = this.game.loop.now; - var delta = this.game.loop.delta; - var scenes = this.game.scene.getScenes(true, true); - - this.time = time; - - this.events.emit(Events.MANAGER_UPDATE); - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene.sys.input && scene.sys.input.updatePoll(time, delta) && this.globalTopOnly) - { - // If the Scene returns true, it means it captured some input that no other Scene should get, so we bail out - return; - } - } - }, - - /** - * Tells the Input system to set a custom cursor. - * - * This cursor will be the default cursor used when interacting with the game canvas. - * - * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. - * - * Any valid CSS cursor value is allowed, including paths to image files, i.e.: - * - * ```javascript - * this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer'); - * ``` - * - * Please read about the differences between browsers when it comes to the file formats and sizes they support: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor - * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property - * - * It's up to you to pick a suitable cursor format that works across the range of browsers you need to support. - * - * @method Phaser.Input.InputManager#setDefaultCursor - * @since 3.10.0 - * - * @param {string} cursor - The CSS to be used when setting the default cursor. - */ - setDefaultCursor: function (cursor) - { - this.defaultCursor = cursor; - - if (this.canvas.style.cursor !== cursor) - { - this.canvas.style.cursor = cursor; - } - }, - - /** - * Called by the InputPlugin when processing over and out events. - * - * Tells the Input Manager to set a custom cursor during its postUpdate step. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor - * - * @method Phaser.Input.InputManager#setCursor - * @private - * @since 3.10.0 - * - * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. - */ - setCursor: function (interactiveObject) - { - if (interactiveObject.cursor) - { - this.canvas.style.cursor = interactiveObject.cursor; - } - }, - - /** - * Called by the InputPlugin when processing over and out events. - * - * Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step. - * - * @method Phaser.Input.InputManager#resetCursor - * @private - * @since 3.10.0 - * - * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. - */ - resetCursor: function (interactiveObject) - { - if (interactiveObject.cursor && this.canvas) - { - this.canvas.style.cursor = this.defaultCursor; - } - }, - - /** - * Adds new Pointer objects to the Input Manager. - * - * By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`. - * - * You can create more either by calling this method, or by setting the `input.activePointers` property - * in the Game Config, up to a maximum of 10 pointers. - * - * The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added - * via this method. - * - * @method Phaser.Input.InputManager#addPointer - * @since 3.10.0 - * - * @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total. - * - * @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created. - */ - addPointer: function (quantity) - { - if (quantity === undefined) { quantity = 1; } - - var output = []; - - if (this.pointersTotal + quantity > 10) - { - quantity = 10 - this.pointersTotal; - } - - for (var i = 0; i < quantity; i++) - { - var id = this.pointers.length; - - var pointer = new Pointer(this, id); - - pointer.smoothFactor = this.config.inputSmoothFactor; - - this.pointers.push(pointer); - - this.pointersTotal++; - - output.push(pointer); - } - - return output; - }, - - /** - * Internal method that gets a list of all the active Input Plugins in the game - * and updates each of them in turn, in reverse order (top to bottom), to allow - * for DOM top-level event handling simulation. - * - * @method Phaser.Input.InputManager#updateInputPlugins - * @since 3.16.0 - * - * @param {number} type - The type of event to process. - * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. - */ - updateInputPlugins: function (type, pointers) - { - var scenes = this.game.scene.getScenes(true, true); - - this._tempSkip = false; - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene.sys.input) - { - var capture = scene.sys.input.update(type, pointers); - - if ((capture && this.globalTopOnly) || this._tempSkip) - { - // If the Scene returns true, or called stopPropagation, it means it captured some input that no other Scene should get, so we bail out - return; - } - } - } - }, - - // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element) - // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element - // event.changedTouches = the touches that CHANGED in this event, not the total number of them - - /** - * Processes a touch start event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchStart - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchStart: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (!pointer.active) - { - pointer.touchstart(changedTouch, event); - - this.activePointer = pointer; - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_START, changed); - }, - - /** - * Processes a touch move event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchMove - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchMove: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchmove(changedTouch, event); - - this.activePointer = pointer; - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_MOVE, changed); - }, - - // For touch end its a list of the touch points that have been removed from the surface - // https://developer.mozilla.org/en-US/docs/DOM/TouchList - // event.changedTouches = the touches that CHANGED in this event, not the total number of them - - /** - * Processes a touch end event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchEnd - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchEnd: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchend(changedTouch, event); - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_END, changed); - }, - - /** - * Processes a touch cancel event, as passed in by the TouchManager. - * - * @method Phaser.Input.InputManager#onTouchCancel - * @private - * @since 3.18.0 - * - * @param {TouchEvent} event - The native DOM Touch event. - */ - onTouchCancel: function (event) - { - var pointers = this.pointers; - var changed = []; - - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; - - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; - - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchcancel(changedTouch, event); - - changed.push(pointer); - - break; - } - } - } - - this.updateInputPlugins(CONST.TOUCH_CANCEL, changed); - }, - - /** - * Processes a mouse down event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseDown - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseDown: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.down(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer); - }, - - /** - * Processes a mouse move event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseMove - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseMove: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.move(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer); - }, - - /** - * Processes a mouse up event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseUp - * @private - * @since 3.18.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onMouseUp: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.up(event); - - mousePointer.updateMotion(); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); - }, - - /** - * Processes a mouse wheel event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onMouseWheel - * @private - * @since 3.18.0 - * - * @param {WheelEvent} event - The native DOM Wheel event. - */ - onMouseWheel: function (event) - { - var mousePointer = this.mousePointer; - - mousePointer.wheel(event); - - this.activePointer = mousePointer; - - this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer); - }, - - /** - * Processes a pointer lock change event, as passed in by the MouseManager. - * - * @method Phaser.Input.InputManager#onPointerLockChange - * @fires Phaser.Input.Events#POINTERLOCK_CHANGE - * @private - * @since 3.19.0 - * - * @param {MouseEvent} event - The native DOM Mouse event. - */ - onPointerLockChange: function (event) - { - var isLocked = this.mouse.locked; - - this.mousePointer.locked = isLocked; - - this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked); - }, - - /** - * Checks if the given Game Object should be considered as a candidate for input or not. - * - * Checks if the Game Object has an input component that is enabled, that it will render, - * and finally, if it has a parent, that the parent parent, or any ancestor, is visible or not. - * - * @method Phaser.Input.InputManager#inputCandidate - * @private - * @since 3.10.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to test. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * - * @return {boolean} `true` if the Game Object should be considered for input, otherwise `false`. - */ - inputCandidate: function (gameObject, camera) - { - var input = gameObject.input; - - if (!input || !input.enabled || (!input.alwaysEnabled && !gameObject.willRender(camera))) - { - return false; - } - - var visible = true; - var parent = gameObject.parentContainer; - - if (parent) - { - do - { - if (!parent.willRender(camera)) - { - visible = false; - break; - } - - parent = parent.parentContainer; - - } while (parent); - } - - return visible; - }, - - /** - * Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects. - * - * The Game Objects are culled against the camera, and then the coordinates are translated into the local camera space - * and used to determine if they fall within the remaining Game Objects hit areas or not. - * - * If nothing is matched an empty array is returned. - * - * This method is called automatically by InputPlugin.hitTestPointer and doesn't usually need to be invoked directly. - * - * @method Phaser.Input.InputManager#hitTest - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to test against. - * @param {array} gameObjects - An array of interactive Game Objects to check. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * @param {array} [output] - An array to store the results in. If not given, a new empty array is created. - * - * @return {array} An array of the Game Objects that were hit during this hit test. - */ - hitTest: function (pointer, gameObjects, camera, output) - { - if (output === undefined) { output = this._tempHitTest; } - - var tempPoint = this._tempPoint; - - var csx = camera.scrollX; - var csy = camera.scrollY; - - output.length = 0; - - var x = pointer.x; - var y = pointer.y; - - // Stores the world point inside of tempPoint - camera.getWorldPoint(x, y, tempPoint); - - pointer.worldX = tempPoint.x; - pointer.worldY = tempPoint.y; - - var point = { x: 0, y: 0 }; - - var matrix = this._tempMatrix; - var parentMatrix = this._tempMatrix2; - - for (var i = 0; i < gameObjects.length; i++) - { - var gameObject = gameObjects[i]; - - // Checks if the Game Object can receive input (isn't being ignored by the camera, invisible, etc) - // and also checks all of its parents, if any - if (!this.inputCandidate(gameObject, camera)) - { - continue; - } - - var px = tempPoint.x + (csx * gameObject.scrollFactorX) - csx; - var py = tempPoint.y + (csy * gameObject.scrollFactorY) - csy; - - if (gameObject.parentContainer) - { - gameObject.getWorldTransformMatrix(matrix, parentMatrix); - - matrix.applyInverse(px, py, point); - } - else - { - TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); - } - - if (this.pointWithinHitArea(gameObject, point.x, point.y)) - { - output.push(gameObject); - } - } - - return output; - }, - - /** - * Checks if the given x and y coordinate are within the hit area of the Game Object. - * - * This method assumes that the coordinate values have already been translated into the space of the Game Object. - * - * If the coordinates are within the hit area they are set into the Game Objects Input `localX` and `localY` properties. - * - * @method Phaser.Input.InputManager#pointWithinHitArea - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object to check against. - * @param {number} x - The translated x coordinate for the hit test. - * @param {number} y - The translated y coordinate for the hit test. - * - * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. - */ - pointWithinHitArea: function (gameObject, x, y) - { - // Normalize the origin - x += gameObject.displayOriginX; - y += gameObject.displayOriginY; - - var input = gameObject.input; - - if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) - { - input.localX = x; - input.localY = y; - - return true; - } - else - { - return false; - } - }, - - /** - * Checks if the given x and y coordinate are within the hit area of the Interactive Object. - * - * This method assumes that the coordinate values have already been translated into the space of the Interactive Object. - * - * If the coordinates are within the hit area they are set into the Interactive Objects Input `localX` and `localY` properties. - * - * @method Phaser.Input.InputManager#pointWithinInteractiveObject - * @since 3.0.0 - * - * @param {Phaser.Types.Input.InteractiveObject} object - The Interactive Object to check against. - * @param {number} x - The translated x coordinate for the hit test. - * @param {number} y - The translated y coordinate for the hit test. - * - * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. - */ - pointWithinInteractiveObject: function (object, x, y) - { - if (!object.hitArea) - { - return false; - } - - // Normalize the origin - x += object.gameObject.displayOriginX; - y += object.gameObject.displayOriginY; - - object.localX = x; - object.localY = y; - - return object.hitAreaCallback(object.hitArea, x, y, object); - }, - - /** - * Transforms the pageX and pageY values of a Pointer into the scaled coordinate space of the Input Manager. - * - * @method Phaser.Input.InputManager#transformPointer - * @since 3.10.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to transform the values for. - * @param {number} pageX - The Page X value. - * @param {number} pageY - The Page Y value. - * @param {boolean} wasMove - Are we transforming the Pointer from a move event, or an up / down event? - */ - transformPointer: function (pointer, pageX, pageY, wasMove) - { - var p0 = pointer.position; - var p1 = pointer.prevPosition; - - // Store previous position - p1.x = p0.x; - p1.y = p0.y; - - // Translate coordinates - var x = this.scaleManager.transformX(pageX); - var y = this.scaleManager.transformY(pageY); - - var a = pointer.smoothFactor; - - if (!wasMove || a === 0) - { - // Set immediately - p0.x = x; - p0.y = y; - } - else - { - // Apply smoothing - p0.x = x * a + p1.x * (1 - a); - p0.y = y * a + p1.y * (1 - a); - } - }, - - /** - * Destroys the Input Manager and all of its systems. - * - * There is no way to recover from doing this. - * - * @method Phaser.Input.InputManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.events.removeAllListeners(); - - this.game.events.off(GameEvents.PRE_RENDER); - - if (this.keyboard) - { - this.keyboard.destroy(); - } - - if (this.mouse) - { - this.mouse.destroy(); - } - - if (this.touch) - { - this.touch.destroy(); - } - - for (var i = 0; i < this.pointers.length; i++) - { - this.pointers[i].destroy(); - } - - this.pointers = []; - this._tempHitTest = []; - this._tempMatrix.destroy(); - this.canvas = null; - this.game = null; - } - -}); - -module.exports = InputManager; - - -/***/ }), -/* 388 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArrayRemove = __webpack_require__(88); -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var InputEvents = __webpack_require__(49); -var KeyCodes = __webpack_require__(140); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * The Keyboard Manager is a helper class that belongs to the global Input Manager. - * - * Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically if keyboard - * input has been enabled in the Game Config. - * - * @class KeyboardManager - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.16.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var KeyboardManager = new Class({ - - initialize: - - function KeyboardManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Keyboard.KeyboardManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.16.0 - */ - this.manager = inputManager; - - /** - * An internal event queue. - * - * @name Phaser.Input.Keyboard.KeyboardManager#queue - * @type {KeyboardEvent[]} - * @private - * @since 3.16.0 - */ - this.queue = []; - - /** - * A flag that controls if the non-modified keys, matching those stored in the `captures` array, - * have `preventDefault` called on them or not. - * - * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are - * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). - * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. - * However, if the user presses just the r key on its own, it will have its event prevented. - * - * If you wish to stop capturing the keys, for example switching out to a DOM based element, then - * you can toggle this property at run-time. - * - * @name Phaser.Input.Keyboard.KeyboardManager#preventDefault - * @type {boolean} - * @since 3.16.0 - */ - this.preventDefault = true; - - /** - * An array of Key Code values that will automatically have `preventDefault` called on them, - * as long as the `KeyboardManager.preventDefault` boolean is set to `true`. - * - * By default the array is empty. - * - * The key must be non-modified when pressed in order to be captured. - * - * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are - * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). - * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. - * However, if the user presses just the r key on its own, it will have its event prevented. - * - * If you wish to stop capturing the keys, for example switching out to a DOM based element, then - * you can toggle the `KeyboardManager.preventDefault` boolean at run-time. - * - * If you need more specific control, you can create Key objects and set the flag on each of those instead. - * - * This array can be populated via the Game Config by setting the `input.keyboard.capture` array, or you - * can call the `addCapture` method. See also `removeCapture` and `clearCaptures`. - * - * @name Phaser.Input.Keyboard.KeyboardManager#captures - * @type {number[]} - * @since 3.16.0 - */ - this.captures = []; - - /** - * A boolean that controls if the Keyboard Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Keyboard.KeyboardManager#enabled - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.enabled = false; - - /** - * The Keyboard Event target, as defined in the Game Config. - * Typically the window in which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Keyboard.KeyboardManager#target - * @type {any} - * @since 3.16.0 - */ - this.target; - - /** - * The Key Down Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyDown - * @type {function} - * @since 3.16.00 - */ - this.onKeyDown = NOOP; - - /** - * The Key Up Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp - * @type {function} - * @since 3.16.00 - */ - this.onKeyUp = NOOP; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Keyboard Manager boot process. - * - * @method Phaser.Input.Keyboard.KeyboardManager#boot - * @private - * @since 3.16.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputKeyboard; - this.target = config.inputKeyboardEventTarget; - - this.addCapture(config.inputKeyboardCapture); - - if (!this.target && window) - { - this.target = window; - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - - this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, this); - }, - - /** - * Starts the Keyboard Event listeners running. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Keyboard.KeyboardManager#startListeners - * @since 3.16.0 - */ - startListeners: function () - { - var _this = this; - - this.onKeyDown = function (event) - { - if (event.defaultPrevented || !_this.enabled || !_this.manager) - { - // Do nothing if event already handled - return; - } - - _this.queue.push(event); - - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); - - var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); - - if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) - { - event.preventDefault(); - } - }; - - this.onKeyUp = function (event) - { - if (event.defaultPrevented || !_this.enabled || !_this.manager) - { - // Do nothing if event already handled - return; - } - - _this.queue.push(event); - - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); - - var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); - - if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) - { - event.preventDefault(); - } - }; - - var target = this.target; - - if (target) - { - target.addEventListener('keydown', this.onKeyDown, false); - target.addEventListener('keyup', this.onKeyUp, false); - - this.enabled = true; - } - }, - - /** - * Stops the Key Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Keyboard.KeyboardManager#stopListeners - * @since 3.16.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('keydown', this.onKeyDown, false); - target.removeEventListener('keyup', this.onKeyUp, false); - - this.enabled = false; - }, - - /** - * Clears the event queue. - * Called automatically by the Input Manager. - * - * @method Phaser.Input.Keyboard.KeyboardManager#postUpdate - * @private - * @since 3.16.0 - */ - postUpdate: function () - { - this.queue = []; - }, - - /** - * By default when a key is pressed Phaser will not stop the event from propagating up to the browser. - * There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll. - * - * This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser - * and cause the default browser behavior. - * - * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent - * the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one. - * - * You can pass in a single key code value, or an array of key codes, or a string: - * - * ```javascript - * this.input.keyboard.addCapture(62); - * ``` - * - * An array of key codes: - * - * ```javascript - * this.input.keyboard.addCapture([ 62, 63, 64 ]); - * ``` - * - * Or a string: - * - * ```javascript - * this.input.keyboard.addCapture('W,S,A,D'); - * ``` - * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. - * - * You can also provide an array mixing both strings and key code integers. - * - * If there are active captures after calling this method, the `preventDefault` property is set to `true`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#addCapture - * @since 3.16.0 - * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser. - */ - addCapture: function (keycode) - { - if (typeof keycode === 'string') - { - keycode = keycode.split(','); - } - - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } - - var captures = this.captures; - - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; - - if (typeof code === 'string') - { - code = KeyCodes[code.trim().toUpperCase()]; - } - - if (captures.indexOf(code) === -1) - { - captures.push(code); - } - } - - this.preventDefault = captures.length > 0; - }, - - /** - * Removes an existing key capture. - * - * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove - * the capture of a key, then it will remove it for any Scene in your game, not just the calling one. - * - * You can pass in a single key code value, or an array of key codes, or a string: - * - * ```javascript - * this.input.keyboard.removeCapture(62); - * ``` - * - * An array of key codes: - * - * ```javascript - * this.input.keyboard.removeCapture([ 62, 63, 64 ]); - * ``` - * - * Or a string: - * - * ```javascript - * this.input.keyboard.removeCapture('W,S,A,D'); - * ``` - * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. - * - * You can also provide an array mixing both strings and key code integers. - * - * If there are no captures left after calling this method, the `preventDefault` property is set to `false`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#removeCapture - * @since 3.16.0 - * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again. - */ - removeCapture: function (keycode) - { - if (typeof keycode === 'string') - { - keycode = keycode.split(','); - } - - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } - - var captures = this.captures; - - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; - - if (typeof code === 'string') - { - code = KeyCodes[code.toUpperCase()]; - } - - ArrayRemove(captures, code); - } - - this.preventDefault = captures.length > 0; - }, - - /** - * Removes all keyboard captures and sets the `preventDefault` property to `false`. - * - * @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures - * @since 3.16.0 - */ - clearCaptures: function () - { - this.captures = []; - - this.preventDefault = false; - }, - - /** - * Destroys this Keyboard Manager instance. - * - * @method Phaser.Input.Keyboard.KeyboardManager#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.stopListeners(); - - this.clearCaptures(); - - this.queue = []; - - this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = KeyboardManager; - - -/***/ }), -/* 389 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Features = __webpack_require__(187); -var InputEvents = __webpack_require__(49); -var NOOP = __webpack_require__(1); - -// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent -// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md - -/** - * @classdesc - * The Mouse Manager is a helper class that belongs to the Input Manager. - * - * Its role is to listen for native DOM Mouse Events and then pass them onto the Input Manager for further processing. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically. - * - * @class MouseManager - * @memberof Phaser.Input.Mouse - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var MouseManager = new Class({ - - initialize: - - function MouseManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Mouse.MouseManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = inputManager; - - /** - * If `true` the DOM `mousedown` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultDown - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultDown = true; - - /** - * If `true` the DOM `mouseup` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultUp - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultUp = true; - - /** - * If `true` the DOM `mousemove` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultMove - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultMove = true; - - /** - * If `true` the DOM `wheel` event will have `preventDefault` set. - * - * @name Phaser.Input.Mouse.MouseManager#preventDefaultWheel - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.preventDefaultWheel = false; - - /** - * A boolean that controls if the Mouse Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Mouse.MouseManager#enabled - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.enabled = false; - - /** - * The Mouse target, as defined in the Game Config. - * Typically the canvas to which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Mouse.MouseManager#target - * @type {any} - * @since 3.0.0 - */ - this.target; - - /** - * If the mouse has been pointer locked successfully this will be set to true. - * - * @name Phaser.Input.Mouse.MouseManager#locked - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.locked = false; - - /** - * The Mouse Move Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseMove - * @type {function} - * @since 3.10.0 - */ - this.onMouseMove = NOOP; - - /** - * The Mouse Down Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseDown - * @type {function} - * @since 3.10.0 - */ - this.onMouseDown = NOOP; - - /** - * The Mouse Up Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseUp - * @type {function} - * @since 3.10.0 - */ - this.onMouseUp = NOOP; - - /** - * The Mouse Down Event handler specifically for events on the Window. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseDownWindow - * @type {function} - * @since 3.17.0 - */ - this.onMouseDownWindow = NOOP; - - /** - * The Mouse Up Event handler specifically for events on the Window. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseUpWindow - * @type {function} - * @since 3.17.0 - */ - this.onMouseUpWindow = NOOP; - - /** - * The Mouse Over Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseOver - * @type {function} - * @since 3.16.0 - */ - this.onMouseOver = NOOP; - - /** - * The Mouse Out Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseOut - * @type {function} - * @since 3.16.0 - */ - this.onMouseOut = NOOP; - - /** - * The Mouse Wheel Event handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#onMouseWheel - * @type {function} - * @since 3.18.0 - */ - this.onMouseWheel = NOOP; - - /** - * Internal pointerLockChange handler. - * This function is sent the native DOM MouseEvent. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Mouse.MouseManager#pointerLockChange - * @type {function} - * @since 3.0.0 - */ - this.pointerLockChange = NOOP; - - /** - * Are the event listeners hooked into `window.top` or `window`? - * - * This is set during the `boot` sequence. If the browser does not have access to `window.top`, - * such as in cross-origin iframe environments, this property gets set to `false` and the events - * are hooked into `window` instead. - * - * @name Phaser.Input.Mouse.MouseManager#isTop - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.isTop = true; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Touch Manager boot process. - * - * @method Phaser.Input.Mouse.MouseManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputMouse; - this.target = config.inputMouseEventTarget; - this.passive = config.inputMousePassive; - - this.preventDefaultDown = config.inputMousePreventDefaultDown; - this.preventDefaultUp = config.inputMousePreventDefaultUp; - this.preventDefaultMove = config.inputMousePreventDefaultMove; - this.preventDefaultWheel = config.inputMousePreventDefaultWheel; - - if (!this.target) - { - this.target = this.manager.game.canvas; - } - else if (typeof this.target === 'string') - { - this.target = document.getElementById(this.target); - } - - if (config.disableContextMenu) - { - this.disableContextMenu(); - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - }, - - /** - * Attempts to disable the context menu from appearing if you right-click on the browser. - * - * Works by listening for the `contextmenu` event and prevent defaulting it. - * - * Use this if you need to enable right-button mouse support in your game, and the browser - * menu keeps getting in the way. - * - * @method Phaser.Input.Mouse.MouseManager#disableContextMenu - * @since 3.0.0 - * - * @return {this} This Mouse Manager instance. - */ - disableContextMenu: function () - { - document.body.addEventListener('contextmenu', function (event) - { - event.preventDefault(); - return false; - }); - - return this; - }, - - /** - * If the browser supports it, you can request that the pointer be locked to the browser window. - * - * This is classically known as 'FPS controls', where the pointer can't leave the browser until - * the user presses an exit key. - * - * If the browser successfully enters a locked state, a `POINTER_LOCK_CHANGE_EVENT` will be dispatched, - * from the games Input Manager, with an `isPointerLocked` property. - * - * It is important to note that pointer lock can only be enabled after an 'engagement gesture', - * see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture. - * - * Note for Firefox: There is a bug in certain Firefox releases that cause native DOM events like - * `mousemove` to fire continuously when in pointer lock mode. You can get around this by setting - * `this.preventDefaultMove` to `false` in this class. You may also need to do the same for - * `preventDefaultDown` and/or `preventDefaultUp`. Please test combinations of these if you encounter - * the error. - * - * @method Phaser.Input.Mouse.MouseManager#requestPointerLock - * @since 3.0.0 - */ - requestPointerLock: function () - { - if (Features.pointerLock) - { - var element = this.target; - - element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; - - element.requestPointerLock(); - } - }, - - /** - * If the browser supports pointer lock, this will request that the pointer lock is released. If - * the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be - * dispatched - from the game's input manager - with an `isPointerLocked` property. - * - * @method Phaser.Input.Mouse.MouseManager#releasePointerLock - * @since 3.0.0 - */ - releasePointerLock: function () - { - if (Features.pointerLock) - { - document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; - document.exitPointerLock(); - } - }, - - /** - * Starts the Mouse Event listeners running. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Mouse.MouseManager#startListeners - * @since 3.0.0 - */ - startListeners: function () - { - var target = this.target; - - if (!target) - { - return; - } - - var _this = this; - var manager = this.manager; - var canvas = manager.canvas; - var autoFocus = (window && window.focus && manager.game.config.autoFocus); - - this.onMouseMove = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseMove(event); - - if (_this.preventDefaultMove) - { - event.preventDefault(); - } - } - }; - - this.onMouseDown = function (event) - { - if (autoFocus) - { - window.focus(); - } - - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseDown(event); - - if (_this.preventDefaultDown && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onMouseDownWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - manager.onMouseDown(event); - } - }; - - this.onMouseUp = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseUp(event); - - if (_this.preventDefaultUp && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onMouseUpWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - manager.onMouseUp(event); - } - }; - - this.onMouseOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOver(event); - } - }; - - this.onMouseOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOut(event); - } - }; - - this.onMouseWheel = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseWheel(event); - } - - if (_this.preventDefaultWheel && event.target === canvas) - { - event.preventDefault(); - } - }; - - var passive = { passive: true }; - - target.addEventListener('mousemove', this.onMouseMove); - target.addEventListener('mousedown', this.onMouseDown); - target.addEventListener('mouseup', this.onMouseUp); - target.addEventListener('mouseover', this.onMouseOver, passive); - target.addEventListener('mouseout', this.onMouseOut, passive); - - if (this.preventDefaultWheel) - { - target.addEventListener('wheel', this.onMouseWheel, { passive: false }); - } - else - { - target.addEventListener('wheel', this.onMouseWheel, passive); - } - - if (window && manager.game.config.inputWindowEvents) - { - try - { - window.top.addEventListener('mousedown', this.onMouseDownWindow, passive); - window.top.addEventListener('mouseup', this.onMouseUpWindow, passive); - } - catch (exception) - { - window.addEventListener('mousedown', this.onMouseDownWindow, passive); - window.addEventListener('mouseup', this.onMouseUpWindow, passive); - - this.isTop = false; - } - } - - if (Features.pointerLock) - { - this.pointerLockChange = function (event) - { - var element = _this.target; - - _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; - - manager.onPointerLockChange(event); - }; - - document.addEventListener('pointerlockchange', this.pointerLockChange, true); - document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); - } - - this.enabled = true; - }, - - /** - * Stops the Mouse Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Mouse.MouseManager#stopListeners - * @since 3.0.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('mousemove', this.onMouseMove); - target.removeEventListener('mousedown', this.onMouseDown); - target.removeEventListener('mouseup', this.onMouseUp); - target.removeEventListener('mouseover', this.onMouseOver); - target.removeEventListener('mouseout', this.onMouseOut); - - if (window) - { - target = (this.isTop) ? window.top : window; - - target.removeEventListener('mousedown', this.onMouseDownWindow); - target.removeEventListener('mouseup', this.onMouseUpWindow); - } - - if (Features.pointerLock) - { - document.removeEventListener('pointerlockchange', this.pointerLockChange, true); - document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); - } - }, - - /** - * Destroys this Mouse Manager instance. - * - * @method Phaser.Input.Mouse.MouseManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stopListeners(); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = MouseManager; - - -/***/ }), -/* 390 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Angle = __webpack_require__(343); -var Class = __webpack_require__(0); -var Distance = __webpack_require__(48); -var FuzzyEqual = __webpack_require__(121); -var SmoothStepInterpolation = __webpack_require__(354); -var Vector2 = __webpack_require__(3); -var OS = __webpack_require__(102); - -/** - * @classdesc - * A Pointer object encapsulates both mouse and touch input within Phaser. - * - * By default, Phaser will create 2 pointers for your game to use. If you require more, i.e. for a multi-touch - * game, then use the `InputPlugin.addPointer` method to do so, rather than instantiating this class directly, - * otherwise it won't be managed by the input system. - * - * You can reference the current active pointer via `InputPlugin.activePointer`. You can also use the properties - * `InputPlugin.pointer1` through to `pointer10`, for each pointer you have enabled in your game. - * - * The properties of this object are set by the Input Plugin during processing. This object is then sent in all - * input related events that the Input Plugin emits, so you can reference properties from it directly in your - * callbacks. - * - * @class Pointer - * @memberof Phaser.Input - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} manager - A reference to the Input Manager. - * @param {number} id - The internal ID of this Pointer. - */ -var Pointer = new Class({ - - initialize: - - function Pointer (manager, id) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Pointer#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * The internal ID of this Pointer. - * - * @name Phaser.Input.Pointer#id - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.id = id; - - /** - * The most recent native DOM Event this Pointer has processed. - * - * @name Phaser.Input.Pointer#event - * @type {(TouchEvent|MouseEvent)} - * @since 3.0.0 - */ - this.event; - - /** - * The DOM element the Pointer was pressed down on, taken from the DOM event. - * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. - * - * @name Phaser.Input.Pointer#downElement - * @type {any} - * @readonly - * @since 3.16.0 - */ - this.downElement; - - /** - * The DOM element the Pointer was released on, taken from the DOM event. - * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. - * - * @name Phaser.Input.Pointer#upElement - * @type {any} - * @readonly - * @since 3.16.0 - */ - this.upElement; - - /** - * The camera the Pointer interacted with during its last update. - * - * A Pointer can only ever interact with one camera at once, which will be the top-most camera - * in the list should multiple cameras be positioned on-top of each other. - * - * @name Phaser.Input.Pointer#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @default null - * @since 3.0.0 - */ - this.camera = null; - - /** - * A read-only property that indicates which button was pressed, or released, on the pointer - * during the most recent event. It is only set during `up` and `down` events. - * - * On Touch devices the value is always 0. - * - * Users may change the configuration of buttons on their pointing device so that if an event's button property - * is zero, it may not have been caused by the button that is physically left–most on the pointing device; - * however, it should behave as if the left button was clicked in the standard button layout. - * - * @name Phaser.Input.Pointer#button - * @type {number} - * @readonly - * @default 0 - * @since 3.18.0 - */ - this.button = 0; - - /** - * 0: No button or un-initialized - * 1: Left button - * 2: Right button - * 4: Wheel button or middle button - * 8: 4th button (typically the "Browser Back" button) - * 16: 5th button (typically the "Browser Forward" button) - * - * For a mouse configured for left-handed use, the button actions are reversed. - * In this case, the values are read from right to left. - * - * @name Phaser.Input.Pointer#buttons - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.buttons = 0; - - /** - * The position of the Pointer in screen space. - * - * @name Phaser.Input.Pointer#position - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.position = new Vector2(); - - /** - * The previous position of the Pointer in screen space. - * - * The old x and y values are stored in here during the InputManager.transformPointer call. - * - * Use the properties `velocity`, `angle` and `distance` to create your own gesture recognition. - * - * @name Phaser.Input.Pointer#prevPosition - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.11.0 - */ - this.prevPosition = new Vector2(); - - /** - * An internal vector used for calculations of the pointer speed and angle. - * - * @name Phaser.Input.Pointer#midPoint - * @type {Phaser.Math.Vector2} - * @private - * @since 3.16.0 - */ - this.midPoint = new Vector2(-1, -1); - - /** - * The current velocity of the Pointer, based on its current and previous positions. - * - * This value is smoothed out each frame, according to the `motionFactor` property. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * @name Phaser.Input.Pointer#velocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.16.0 - */ - this.velocity = new Vector2(); - - /** - * The current angle the Pointer is moving, in radians, based on its previous and current position. - * - * The angle is based on the old position facing to the current position. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * @name Phaser.Input.Pointer#angle - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.angle = 0; - - /** - * The distance the Pointer has moved, based on its previous and current position. - * - * This value is smoothed out each frame, according to the `motionFactor` property. - * - * This property is updated whenever the Pointer moves, regardless of any button states. In other words, - * it changes based on movement alone - a button doesn't have to be pressed first. - * - * If you need the total distance travelled since the primary buttons was pressed down, - * then use the `Pointer.getDistance` method. - * - * @name Phaser.Input.Pointer#distance - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.distance = 0; - - /** - * The smoothing factor to apply to the Pointer position. - * - * Due to their nature, pointer positions are inherently noisy. While this is fine for lots of games, if you need cleaner positions - * then you can set this value to apply an automatic smoothing to the positions as they are recorded. - * - * The default value of zero means 'no smoothing'. - * Set to a small value, such as 0.2, to apply an average level of smoothing between positions. You can do this by changing this - * value directly, or by setting the `input.smoothFactor` property in the Game Config. - * - * Positions are only smoothed when the pointer moves. If the primary button on this Pointer enters an Up or Down state, then the position - * is always precise, and not smoothed. - * - * @name Phaser.Input.Pointer#smoothFactor - * @type {number} - * @default 0 - * @since 3.16.0 - */ - this.smoothFactor = 0; - - /** - * The factor applied to the motion smoothing each frame. - * - * This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, - * angle and distance of the Pointer. It's applied every frame, until the midPoint reaches the current - * position of the Pointer. 0.2 provides a good average but can be increased if you need a - * quicker update and are working in a high performance environment. Never set this value to - * zero. - * - * @name Phaser.Input.Pointer#motionFactor - * @type {number} - * @default 0.2 - * @since 3.16.0 - */ - this.motionFactor = 0.2; - - /** - * The x position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. - * - * If you wish to use this value _outside_ of an input event handler then you should update it first by calling - * the `Pointer.updateWorldPoint` method. - * - * @name Phaser.Input.Pointer#worldX - * @type {number} - * @default 0 - * @since 3.10.0 - */ - this.worldX = 0; - - /** - * The y position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. - * - * If you wish to use this value _outside_ of an input event handler then you should update it first by calling - * the `Pointer.updateWorldPoint` method. - * - * @name Phaser.Input.Pointer#worldY - * @type {number} - * @default 0 - * @since 3.10.0 - */ - this.worldY = 0; - - /** - * Time when this Pointer was most recently moved (regardless of the state of its buttons, if any) - * - * @name Phaser.Input.Pointer#moveTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.moveTime = 0; - - /** - * X coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. - * - * @name Phaser.Input.Pointer#downX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downX = 0; - - /** - * Y coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. - * - * @name Phaser.Input.Pointer#downY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downY = 0; - - /** - * The Event timestamp when the first button, or Touch input, was pressed. Used for dragging objects. - * - * @name Phaser.Input.Pointer#downTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.downTime = 0; - - /** - * X coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. - * - * @name Phaser.Input.Pointer#upX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upX = 0; - - /** - * Y coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. - * - * @name Phaser.Input.Pointer#upY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upY = 0; - - /** - * The Event timestamp when the final button, or Touch input, was released. Used for dragging objects. - * - * @name Phaser.Input.Pointer#upTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.upTime = 0; - - /** - * Is the primary button down? (usually button 0, the left mouse button) - * - * @name Phaser.Input.Pointer#primaryDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.primaryDown = false; - - /** - * Is _any_ button on this pointer considered as being down? - * - * @name Phaser.Input.Pointer#isDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isDown = false; - - /** - * Did the previous input event come from a Touch input (true) or Mouse? (false) - * - * @name Phaser.Input.Pointer#wasTouch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.wasTouch = false; - - /** - * Did this Pointer get canceled by a touchcancel event? - * - * Note: "canceled" is the American-English spelling of "cancelled". Please don't submit PRs correcting it! - * - * @name Phaser.Input.Pointer#wasCanceled - * @type {boolean} - * @default false - * @since 3.15.0 - */ - this.wasCanceled = false; - - /** - * If the mouse is locked, the horizontal relative movement of the Pointer in pixels since last frame. - * - * @name Phaser.Input.Pointer#movementX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.movementX = 0; - - /** - * If the mouse is locked, the vertical relative movement of the Pointer in pixels since last frame. - * - * @name Phaser.Input.Pointer#movementY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.movementY = 0; - - /** - * The identifier property of the Pointer as set by the DOM event when this Pointer is started. - * - * @name Phaser.Input.Pointer#identifier - * @type {number} - * @since 3.10.0 - */ - this.identifier = 0; - - /** - * The pointerId property of the Pointer as set by the DOM event when this Pointer is started. - * The browser can and will recycle this value. - * - * @name Phaser.Input.Pointer#pointerId - * @type {number} - * @since 3.10.0 - */ - this.pointerId = null; - - /** - * An active Pointer is one that is currently pressed down on the display. - * A Mouse is always considered as active. - * - * @name Phaser.Input.Pointer#active - * @type {boolean} - * @since 3.10.0 - */ - this.active = (id === 0) ? true : false; - - /** - * Is this pointer Pointer Locked? - * - * Only a mouse pointer can be locked and it only becomes locked when requested via - * the browsers Pointer Lock API. - * - * You can request this by calling the `this.input.mouse.requestPointerLock()` method from - * a `pointerdown` or `pointerup` event handler. - * - * @name Phaser.Input.Pointer#locked - * @readonly - * @type {boolean} - * @since 3.19.0 - */ - this.locked = false; - - /** - * The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * - * @name Phaser.Input.Pointer#deltaX - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaX = 0; - - /** - * The vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * This value will typically be less than 0 if the user scrolls up and greater than zero if scrolling down. - * - * @name Phaser.Input.Pointer#deltaY - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaY = 0; - - /** - * The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * - * @name Phaser.Input.Pointer#deltaZ - * @type {number} - * @default 0 - * @since 3.18.0 - */ - this.deltaZ = 0; - }, - - /** - * Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are - * the result of a translation through the given Camera. - * - * Note that the values will be automatically replaced the moment the Pointer is - * updated by an input event, such as a mouse move, so should be used immediately. - * - * @method Phaser.Input.Pointer#updateWorldPoint - * @since 3.19.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. - * - * @return {this} This Pointer object. - */ - updateWorldPoint: function (camera) - { - // Stores the world point inside of tempPoint - var temp = camera.getWorldPoint(this.x, this.y); - - this.worldX = temp.x; - this.worldY = temp.y; - - return this; - }, - - /** - * Takes a Camera and returns a Vector2 containing the translated position of this Pointer - * within that Camera. This can be used to convert this Pointers position into camera space. - * - * @method Phaser.Input.Pointer#positionToCamera - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the translation. - * @param {(Phaser.Math.Vector2|object)} [output] - A Vector2-like object in which to store the translated position. - * - * @return {(Phaser.Math.Vector2|object)} A Vector2 containing the translated coordinates of this Pointer, based on the given camera. - */ - positionToCamera: function (camera, output) - { - return camera.getWorldPoint(this.x, this.y, output); - }, - - /** - * Calculates the motion of this Pointer, including its velocity and angle of movement. - * This method is called automatically each frame by the Input Manager. - * - * @method Phaser.Input.Pointer#updateMotion - * @private - * @since 3.16.0 - */ - updateMotion: function () - { - var cx = this.position.x; - var cy = this.position.y; - - var mx = this.midPoint.x; - var my = this.midPoint.y; - - if (cx === mx && cy === my) - { - // Nothing to do here - return; - } - - // Moving towards our goal ... - var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); - var vy = SmoothStepInterpolation(this.motionFactor, my, cy); - - if (FuzzyEqual(vx, cx, 0.1)) - { - vx = cx; - } - - if (FuzzyEqual(vy, cy, 0.1)) - { - vy = cy; - } - - this.midPoint.set(vx, vy); - - var dx = cx - vx; - var dy = cy - vy; - - this.velocity.set(dx, dy); - - this.angle = Angle(vx, vy, cx, cy); - - this.distance = Math.sqrt(dx * dx + dy * dy); - }, - - /** - * Internal method to handle a Mouse Up Event. - * - * @method Phaser.Input.Pointer#up - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - up: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - this.button = event.button; - - this.upElement = event.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - // 0: Main button pressed, usually the left button or the un-initialized state - if (event.button === 0) - { - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - } - - if (this.buttons === 0) - { - // No more buttons are still down - this.isDown = false; - - this.upTime = event.timeStamp; - - this.wasTouch = false; - } - }, - - /** - * Internal method to handle a Mouse Down Event. - * - * @method Phaser.Input.Pointer#down - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - down: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - this.button = event.button; - - this.downElement = event.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - // 0: Main button pressed, usually the left button or the un-initialized state - if (event.button === 0) - { - this.primaryDown = true; - this.downX = this.x; - this.downY = this.y; - } - - if (OS.macOS && event.ctrlKey) - { - // Override button settings on macOS - this.buttons = 2; - this.primaryDown = false; - } - - if (!this.isDown) - { - this.isDown = true; - - this.downTime = event.timeStamp; - } - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Mouse Move Event. - * - * @method Phaser.Input.Pointer#move - * @private - * @since 3.0.0 - * - * @param {MouseEvent} event - The Mouse Event to process. - */ - move: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, true); - - if (this.locked) - { - // Multiple DOM events may occur within one frame, but only one Phaser event will fire - this.movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; - this.movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; - } - - this.moveTime = event.timeStamp; - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Mouse Wheel Event. - * - * @method Phaser.Input.Pointer#wheel - * @private - * @since 3.18.0 - * - * @param {WheelEvent} event - The Wheel Event to process. - */ - wheel: function (event) - { - if ('buttons' in event) - { - this.buttons = event.buttons; - } - - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); - - this.deltaX = event.deltaX; - this.deltaY = event.deltaY; - this.deltaZ = event.deltaZ; - - this.wasTouch = false; - }, - - /** - * Internal method to handle a Touch Start Event. - * - * @method Phaser.Input.Pointer#touchstart - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchstart: function (touch, event) - { - if (touch['pointerId']) - { - this.pointerId = touch.pointerId; - } - - this.identifier = touch.identifier; - this.target = touch.target; - this.active = true; - - this.buttons = 1; - - this.event = event; - - this.downElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = true; - this.downX = this.x; - this.downY = this.y; - this.downTime = event.timeStamp; - - this.isDown = true; - - this.wasTouch = true; - this.wasCanceled = false; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch Move Event. - * - * @method Phaser.Input.Pointer#touchmove - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchmove: function (touch, event) - { - this.event = event; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, true); - - this.moveTime = event.timeStamp; - - this.wasTouch = true; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch End Event. - * - * @method Phaser.Input.Pointer#touchend - * @private - * @since 3.0.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchend: function (touch, event) - { - this.buttons = 0; - - this.event = event; - - this.upElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - this.upTime = event.timeStamp; - - this.isDown = false; - - this.wasTouch = true; - this.wasCanceled = false; - - this.active = false; - - this.updateMotion(); - }, - - /** - * Internal method to handle a Touch Cancel Event. - * - * @method Phaser.Input.Pointer#touchcancel - * @private - * @since 3.15.0 - * - * @param {Touch} touch - The Changed Touch from the Touch Event. - * @param {TouchEvent} event - The full Touch Event. - */ - touchcancel: function (touch, event) - { - this.buttons = 0; - - this.event = event; - - this.upElement = touch.target; - - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - - this.primaryDown = false; - this.upX = this.x; - this.upY = this.y; - this.upTime = event.timeStamp; - - this.isDown = false; - - this.wasTouch = true; - this.wasCanceled = true; - - this.active = false; - }, - - /** - * Checks to see if any buttons are being held down on this Pointer. - * - * @method Phaser.Input.Pointer#noButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if no buttons are being held down. - */ - noButtonDown: function () - { - return (this.buttons === 0); - }, - - /** - * Checks to see if the left button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#leftButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the left button is being held down. - */ - leftButtonDown: function () - { - return (this.buttons & 1) ? true : false; - }, - - /** - * Checks to see if the right button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#rightButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the right button is being held down. - */ - rightButtonDown: function () - { - return (this.buttons & 2) ? true : false; - }, - - /** - * Checks to see if the middle button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#middleButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the middle button is being held down. - */ - middleButtonDown: function () - { - return (this.buttons & 4) ? true : false; - }, - - /** - * Checks to see if the back button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#backButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the back button is being held down. - */ - backButtonDown: function () - { - return (this.buttons & 8) ? true : false; - }, - - /** - * Checks to see if the forward button is being held down on this Pointer. - * - * @method Phaser.Input.Pointer#forwardButtonDown - * @since 3.0.0 - * - * @return {boolean} `true` if the forward button is being held down. - */ - forwardButtonDown: function () - { - return (this.buttons & 16) ? true : false; - }, - - /** - * Checks to see if the left button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#leftButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the left button was just released. - */ - leftButtonReleased: function () - { - return (this.button === 0 && !this.isDown); - }, - - /** - * Checks to see if the right button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#rightButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the right button was just released. - */ - rightButtonReleased: function () - { - return (this.button === 2 && !this.isDown); - }, - - /** - * Checks to see if the middle button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#middleButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the middle button was just released. - */ - middleButtonReleased: function () - { - return (this.button === 1 && !this.isDown); - }, - - /** - * Checks to see if the back button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#backButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the back button was just released. - */ - backButtonReleased: function () - { - return (this.button === 3 && !this.isDown); - }, - - /** - * Checks to see if the forward button was just released on this Pointer. - * - * @method Phaser.Input.Pointer#forwardButtonReleased - * @since 3.18.0 - * - * @return {boolean} `true` if the forward button was just released. - */ - forwardButtonReleased: function () - { - return (this.button === 4 && !this.isDown); - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded distance, based on where - * the Pointer was when the button was released. - * - * If you wish to get the distance being travelled currently, based on the velocity of the Pointer, - * then see the `Pointer.distance` property. - * - * @method Phaser.Input.Pointer#getDistance - * @since 3.13.0 - * - * @return {number} The distance the Pointer moved. - */ - getDistance: function () - { - if (this.isDown) - { - return Distance(this.downX, this.downY, this.x, this.y); - } - else - { - return Distance(this.downX, this.downY, this.upX, this.upY); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * horizontal distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded horizontal distance, based on where - * the Pointer was when the button was released. - * - * @method Phaser.Input.Pointer#getDistanceX - * @since 3.16.0 - * - * @return {number} The horizontal distance the Pointer moved. - */ - getDistanceX: function () - { - if (this.isDown) - { - return Math.abs(this.downX - this.x); - } - else - { - return Math.abs(this.downX - this.upX); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * vertical distance between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded vertical distance, based on where - * the Pointer was when the button was released. - * - * @method Phaser.Input.Pointer#getDistanceY - * @since 3.16.0 - * - * @return {number} The vertical distance the Pointer moved. - */ - getDistanceY: function () - { - if (this.isDown) - { - return Math.abs(this.downY - this.y); - } - else - { - return Math.abs(this.downY - this.upY); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * duration since the button was pressed down. - * - * If no button is held down, it will return the last recorded duration, based on the time - * the last button on the Pointer was released. - * - * @method Phaser.Input.Pointer#getDuration - * @since 3.16.0 - * - * @return {number} The duration the Pointer was held down for in milliseconds. - */ - getDuration: function () - { - if (this.isDown) - { - return (this.manager.time - this.downTime); - } - else - { - return (this.upTime - this.downTime); - } - }, - - /** - * If the Pointer has a button pressed down at the time this method is called, it will return the - * angle between the Pointer's `downX` and `downY` values and the current position. - * - * If no button is held down, it will return the last recorded angle, based on where - * the Pointer was when the button was released. - * - * The angle is based on the old position facing to the current position. - * - * If you wish to get the current angle, based on the velocity of the Pointer, then - * see the `Pointer.angle` property. - * - * @method Phaser.Input.Pointer#getAngle - * @since 3.16.0 - * - * @return {number} The angle between the Pointer's coordinates in radians. - */ - getAngle: function () - { - if (this.isDown) - { - return Angle(this.downX, this.downY, this.x, this.y); - } - else - { - return Angle(this.downX, this.downY, this.upX, this.upY); - } - }, - - /** - * Takes the previous and current Pointer positions and then generates an array of interpolated values between - * the two. The array will be populated up to the size of the `steps` argument. - * - * ```javaScript - * var points = pointer.getInterpolatedPosition(4); - * - * // points[0] = { x: 0, y: 0 } - * // points[1] = { x: 2, y: 1 } - * // points[2] = { x: 3, y: 2 } - * // points[3] = { x: 6, y: 3 } - * ``` - * - * Use this if you need to get smoothed values between the previous and current pointer positions. DOM pointer - * events can often fire faster than the main browser loop, and this will help you avoid janky movement - * especially if you have an object following a Pointer. - * - * Note that if you provide an output array it will only be populated up to the number of steps provided. - * It will not clear any previous data that may have existed beyond the range of the steps count. - * - * Internally it uses the Smooth Step interpolation calculation. - * - * @method Phaser.Input.Pointer#getInterpolatedPosition - * @since 3.11.0 - * - * @param {number} [steps=10] - The number of interpolation steps to use. - * @param {array} [out] - An array to store the results in. If not provided a new one will be created. - * - * @return {array} An array of interpolated values. - */ - getInterpolatedPosition: function (steps, out) - { - if (steps === undefined) { steps = 10; } - if (out === undefined) { out = []; } - - var prevX = this.prevPosition.x; - var prevY = this.prevPosition.y; - - var curX = this.position.x; - var curY = this.position.y; - - for (var i = 0; i < steps; i++) - { - var t = (1 / steps) * i; - - out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; - } - - return out; - }, - - /** - * Destroys this Pointer instance and resets its external references. - * - * @method Phaser.Input.Pointer#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.camera = null; - this.manager = null; - this.position = null; - }, - - /** - * The x position of this Pointer. - * The value is in screen space. - * See `worldX` to get a camera converted position. - * - * @name Phaser.Input.Pointer#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.position.x = value; - } - - }, - - /** - * The y position of this Pointer. - * The value is in screen space. - * See `worldY` to get a camera converted position. - * - * @name Phaser.Input.Pointer#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.position.y = value; - } - - }, - - /** - * Time when this Pointer was most recently updated by a DOM Event. - * This comes directly from the `event.timeStamp` property. - * If no event has yet taken place, it will return zero. - * - * @name Phaser.Input.Pointer#time - * @type {number} - * @readonly - * @since 3.16.0 - */ - time: { - - get: function () - { - return (this.event) ? this.event.timeStamp : 0; - } - - } - -}); - -module.exports = Pointer; - - -/***/ }), -/* 391 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var InputEvents = __webpack_require__(49); -var NOOP = __webpack_require__(1); - -// https://developer.mozilla.org/en-US/docs/Web/API/Touch_events -// https://patrickhlauke.github.io/touch/tests/results/ -// https://www.html5rocks.com/en/mobile/touch/ - -/** - * @classdesc - * The Touch Manager is a helper class that belongs to the Input Manager. - * - * Its role is to listen for native DOM Touch Events and then pass them onto the Input Manager for further processing. - * - * You do not need to create this class directly, the Input Manager will create an instance of it automatically. - * - * @class TouchManager - * @memberof Phaser.Input.Touch - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. - */ -var TouchManager = new Class({ - - initialize: - - function TouchManager (inputManager) - { - /** - * A reference to the Input Manager. - * - * @name Phaser.Input.Touch.TouchManager#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = inputManager; - - /** - * If true the DOM events will have event.preventDefault applied to them, if false they will propagate fully. - * - * @name Phaser.Input.Touch.TouchManager#capture - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.capture = true; - - /** - * A boolean that controls if the Touch Manager is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Touch.TouchManager#enabled - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.enabled = false; - - /** - * The Touch Event target, as defined in the Game Config. - * Typically the canvas to which the game is rendering, but can be any interactive DOM element. - * - * @name Phaser.Input.Touch.TouchManager#target - * @type {any} - * @since 3.0.0 - */ - this.target; - - /** - * The Touch Start event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchStart - * @type {function} - * @since 3.0.0 - */ - this.onTouchStart = NOOP; - - /** - * The Touch Start event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchStartWindow - * @type {function} - * @since 3.17.0 - */ - this.onTouchStartWindow = NOOP; - - /** - * The Touch Move event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchMove - * @type {function} - * @since 3.0.0 - */ - this.onTouchMove = NOOP; - - /** - * The Touch End event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchEnd - * @type {function} - * @since 3.0.0 - */ - this.onTouchEnd = NOOP; - - /** - * The Touch End event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchEndWindow - * @type {function} - * @since 3.17.0 - */ - this.onTouchEndWindow = NOOP; - - /** - * The Touch Cancel event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchCancel - * @type {function} - * @since 3.15.0 - */ - this.onTouchCancel = NOOP; - - /** - * The Touch Cancel event handler function specifically for events on the Window. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchCancelWindow - * @type {function} - * @since 3.18.0 - */ - this.onTouchCancelWindow = NOOP; - - /** - * The Touch Over event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchOver - * @type {function} - * @since 3.16.0 - */ - this.onTouchOver = NOOP; - - /** - * The Touch Out event handler function. - * Initially empty and bound in the `startListeners` method. - * - * @name Phaser.Input.Touch.TouchManager#onTouchOut - * @type {function} - * @since 3.16.0 - */ - this.onTouchOut = NOOP; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, - - /** - * The Touch Manager boot process. - * - * @method Phaser.Input.Touch.TouchManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - var config = this.manager.config; - - this.enabled = config.inputTouch; - this.target = config.inputTouchEventTarget; - this.capture = config.inputTouchCapture; - - if (!this.target) - { - this.target = this.manager.game.canvas; - } - - if (config.disableContextMenu) - { - this.disableContextMenu(); - } - - if (this.enabled && this.target) - { - this.startListeners(); - } - }, - - /** - * Attempts to disable the context menu from appearing if you touch-hold on the browser. - * - * Works by listening for the `contextmenu` event and prevent defaulting it. - * - * Use this if you need to disable the OS context menu on mobile. - * - * @method Phaser.Input.Touch.TouchManager#disableContextMenu - * @since 3.20.0 - * - * @return {this} This Touch Manager instance. - */ - disableContextMenu: function () - { - document.body.addEventListener('contextmenu', function (event) - { - event.preventDefault(); - return false; - }); - - return this; - }, - - /** - * Starts the Touch Event listeners running as long as an input target is set. - * - * This method is called automatically if Touch Input is enabled in the game config, - * which it is by default. However, you can call it manually should you need to - * delay input capturing until later in the game. - * - * @method Phaser.Input.Touch.TouchManager#startListeners - * @since 3.0.0 - */ - startListeners: function () - { - var _this = this; - var canvas = this.manager.canvas; - var autoFocus = (window && window.focus && this.manager.game.config.autoFocus); - - this.onTouchStart = function (event) - { - if (autoFocus) - { - window.focus(); - } - - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchStart(event); - - if (_this.capture && event.cancelable && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onTouchStartWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - _this.manager.onTouchStart(event); - } - }; - - this.onTouchMove = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchMove(event); - - if (_this.capture && event.cancelable) - { - event.preventDefault(); - } - } - }; - - this.onTouchEnd = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchEnd(event); - - if (_this.capture && event.cancelable && event.target === canvas) - { - event.preventDefault(); - } - } - }; - - this.onTouchEndWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) - { - // Only process the event if the target isn't the canvas - _this.manager.onTouchEnd(event); - } - }; - - this.onTouchCancel = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchCancel(event); - - if (_this.capture) - { - event.preventDefault(); - } - } - }; - - this.onTouchCancelWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchCancel(event); - } - }; - - this.onTouchOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.setCanvasOver(event); - } - }; - - this.onTouchOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.setCanvasOut(event); - } - }; - - var target = this.target; - - if (!target) - { - return; - } - - var passive = { passive: true }; - var nonPassive = { passive: false }; - - target.addEventListener('touchstart', this.onTouchStart, (this.capture) ? nonPassive : passive); - target.addEventListener('touchmove', this.onTouchMove, (this.capture) ? nonPassive : passive); - target.addEventListener('touchend', this.onTouchEnd, (this.capture) ? nonPassive : passive); - target.addEventListener('touchcancel', this.onTouchCancel, (this.capture) ? nonPassive : passive); - target.addEventListener('touchover', this.onTouchOver, (this.capture) ? nonPassive : passive); - target.addEventListener('touchout', this.onTouchOut, (this.capture) ? nonPassive : passive); - - if (window && this.manager.game.config.inputWindowEvents) - { - window.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); - window.addEventListener('touchend', this.onTouchEndWindow, nonPassive); - window.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); - } - - this.enabled = true; - }, - - /** - * Stops the Touch Event listeners. - * This is called automatically and does not need to be manually invoked. - * - * @method Phaser.Input.Touch.TouchManager#stopListeners - * @since 3.0.0 - */ - stopListeners: function () - { - var target = this.target; - - target.removeEventListener('touchstart', this.onTouchStart); - target.removeEventListener('touchmove', this.onTouchMove); - target.removeEventListener('touchend', this.onTouchEnd); - target.removeEventListener('touchcancel', this.onTouchCancel); - target.removeEventListener('touchover', this.onTouchOver); - target.removeEventListener('touchout', this.onTouchOut); - - if (window) - { - window.removeEventListener('touchstart', this.onTouchStartWindow); - window.removeEventListener('touchend', this.onTouchEndWindow); - } - }, - - /** - * Destroys this Touch Manager instance. - * - * @method Phaser.Input.Touch.TouchManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stopListeners(); - - this.target = null; - this.enabled = false; - this.manager = null; - } - -}); - -module.exports = TouchManager; - - -/***/ }), -/* 392 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var EventEmitter = __webpack_require__(9); -var FileTypesManager = __webpack_require__(8); -var GameObjectCreator = __webpack_require__(16); -var GameObjectFactory = __webpack_require__(5); -var GetFastValue = __webpack_require__(2); -var PluginCache = __webpack_require__(24); -var Remove = __webpack_require__(88); - -/** - * @classdesc - * The PluginManager is responsible for installing and adding plugins to Phaser. - * - * It is a global system and therefore belongs to the Game instance, not a specific Scene. - * - * It works in conjunction with the PluginCache. Core internal plugins automatically register themselves - * with the Cache, but it's the Plugin Manager that is responsible for injecting them into the Scenes. - * - * There are two types of plugin: - * - * 1. A Global Plugin - * 2. A Scene Plugin - * - * A Global Plugin is a plugin that lives within the Plugin Manager rather than a Scene. You can get - * access to it by calling `PluginManager.get` and providing a key. Any Scene that requests a plugin in - * this way will all get access to the same plugin instance, allowing you to use a single plugin across - * multiple Scenes. - * - * A Scene Plugin is a plugin dedicated to running within a Scene. These are different to Global Plugins - * in that their instances do not live within the Plugin Manager, but within the Scene Systems class instead. - * And that every Scene created is given its own unique instance of a Scene Plugin. Examples of core Scene - * Plugins include the Input Plugin, the Tween Plugin and the physics Plugins. - * - * You can add a plugin to Phaser in three different ways: - * - * 1. Preload it - * 2. Include it in your source code and install it via the Game Config - * 3. Include it in your source code and install it within a Scene - * - * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. - * - * For information on creating your own plugin please see the Phaser 3 Plugin Template. - * - * @class PluginManager - * @memberof Phaser.Plugins - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. - */ -var PluginManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function PluginManager (game) - { - EventEmitter.call(this); - - /** - * The game instance that owns this Plugin Manager. - * - * @name Phaser.Plugins.PluginManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * The global plugins currently running and managed by this Plugin Manager. - * A plugin must have been started at least once in order to appear in this list. - * - * @name Phaser.Plugins.PluginManager#plugins - * @type {Phaser.Types.Plugins.GlobalPlugin[]} - * @since 3.8.0 - */ - this.plugins = []; - - /** - * A list of plugin keys that should be installed into Scenes as well as the Core Plugins. - * - * @name Phaser.Plugins.PluginManager#scenePlugins - * @type {string[]} - * @since 3.8.0 - */ - this.scenePlugins = []; - - /** - * A temporary list of plugins to install when the game has booted. - * - * @name Phaser.Plugins.PluginManager#_pendingGlobal - * @private - * @type {array} - * @since 3.8.0 - */ - this._pendingGlobal = []; - - /** - * A temporary list of scene plugins to install when the game has booted. - * - * @name Phaser.Plugins.PluginManager#_pendingScene - * @private - * @type {array} - * @since 3.8.0 - */ - this._pendingScene = []; - - if (game.isBooted) - { - this.boot(); - } - else - { - game.events.once(GameEvents.BOOT, this.boot, this); - } - }, - - /** - * Run once the game has booted and installs all of the plugins configured in the Game Config. - * - * @method Phaser.Plugins.PluginManager#boot - * @protected - * @since 3.0.0 - */ - boot: function () - { - var i; - var entry; - var key; - var plugin; - var start; - var mapping; - var data; - var config = this.game.config; - - // Any plugins to install? - var list = config.installGlobalPlugins; - - // Any plugins added outside of the game config, but before the game booted? - list = list.concat(this._pendingGlobal); - - for (i = 0; i < list.length; i++) - { - entry = list[i]; - - // { key: 'TestPlugin', plugin: TestPlugin, start: true, mapping: 'test', data: { msg: 'The plugin is alive' } } - - key = GetFastValue(entry, 'key', null); - plugin = GetFastValue(entry, 'plugin', null); - start = GetFastValue(entry, 'start', false); - mapping = GetFastValue(entry, 'mapping', null); - data = GetFastValue(entry, 'data', null); - - if (key) - { - if (plugin) - { - this.install(key, plugin, start, mapping, data); - } - else - { - console.warn('Missing `plugin` for key: ' + key); - } - - } - } - - // Any scene plugins to install? - list = config.installScenePlugins; - - // Any plugins added outside of the game config, but before the game booted? - list = list.concat(this._pendingScene); - - for (i = 0; i < list.length; i++) - { - entry = list[i]; - - // { key: 'moveSpritePlugin', plugin: MoveSpritePlugin, , mapping: 'move' } - - key = GetFastValue(entry, 'key', null); - plugin = GetFastValue(entry, 'plugin', null); - mapping = GetFastValue(entry, 'mapping', null); - - if (key) - { - if (plugin) - { - this.installScenePlugin(key, plugin, mapping); - } - else - { - console.warn('Missing `plugin` for key: ' + key); - } - } - } - - this._pendingGlobal = []; - this._pendingScene = []; - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * Called by the Scene Systems class. Tells the plugin manager to install all Scene plugins into it. - * - * First it will install global references, i.e. references from the Game systems into the Scene Systems (and Scene if mapped.) - * Then it will install Core Scene Plugins followed by Scene Plugins registered with the PluginManager. - * Finally it will install any references to Global Plugins that have a Scene mapping property into the Scene itself. - * - * @method Phaser.Plugins.PluginManager#addToScene - * @protected - * @since 3.8.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems class to install all the plugins in to. - * @param {array} globalPlugins - An array of global plugins to install. - * @param {array} scenePlugins - An array of scene plugins to install. - */ - addToScene: function (sys, globalPlugins, scenePlugins) - { - var i; - var pluginKey; - var pluginList; - var game = this.game; - var scene = sys.scene; - var map = sys.settings.map; - var isBooted = sys.settings.isBooted; - - // Reference the GlobalPlugins from Game into Scene.Systems - for (i = 0; i < globalPlugins.length; i++) - { - pluginKey = globalPlugins[i]; - - if (game[pluginKey]) - { - sys[pluginKey] = game[pluginKey]; - - // Scene level injection - if (map.hasOwnProperty(pluginKey)) - { - scene[map[pluginKey]] = sys[pluginKey]; - } - } - else if (pluginKey === 'game' && map.hasOwnProperty(pluginKey)) - { - scene[map[pluginKey]] = game; - } - } - - for (var s = 0; s < scenePlugins.length; s++) - { - pluginList = scenePlugins[s]; - - for (i = 0; i < pluginList.length; i++) - { - pluginKey = pluginList[i]; - - if (!PluginCache.hasCore(pluginKey)) - { - continue; - } - - var source = PluginCache.getCore(pluginKey); - - var plugin = new source.plugin(scene, this); - - sys[source.mapping] = plugin; - - // Scene level injection - if (source.custom) - { - scene[source.mapping] = plugin; - } - else if (map.hasOwnProperty(source.mapping)) - { - scene[map[source.mapping]] = plugin; - } - - // Scene is already booted, usually because this method is being called at run-time, so boot the plugin - if (isBooted) - { - plugin.boot(); - } - } - } - - // And finally, inject any 'global scene plugins' - pluginList = this.plugins; - - for (i = 0; i < pluginList.length; i++) - { - var entry = pluginList[i]; - - if (entry.mapping) - { - scene[entry.mapping] = entry.plugin; - } - } - }, - - /** - * Called by the Scene Systems class. Returns a list of plugins to be installed. - * - * @method Phaser.Plugins.PluginManager#getDefaultScenePlugins - * @protected - * @since 3.8.0 - * - * @return {string[]} A list keys of all the Scene Plugins to install. - */ - getDefaultScenePlugins: function () - { - var list = this.game.config.defaultPlugins; - - // Merge in custom Scene plugins - list = list.concat(this.scenePlugins); - - return list; - }, - - /** - * Installs a new Scene Plugin into the Plugin Manager and optionally adds it - * to the given Scene as well. A Scene Plugin added to the manager in this way - * will be automatically installed into all new Scenes using the key and mapping given. - * - * The `key` property is what the plugin is injected into Scene.Systems as. - * The `mapping` property is optional, and if specified is what the plugin is installed into - * the Scene as. For example: - * - * ```javascript - * this.plugins.installScenePlugin('powerupsPlugin', pluginCode, 'powerups'); - * - * // and from within the scene: - * this.sys.powerupsPlugin; // key value - * this.powerups; // mapping value - * ``` - * - * This method is called automatically by Phaser if you install your plugins using either the - * Game Configuration object, or by preloading them via the Loader. - * - * @method Phaser.Plugins.PluginManager#installScenePlugin - * @since 3.8.0 - * - * @param {string} key - The property key that will be used to add this plugin to Scene.Systems. - * @param {function} plugin - The plugin code. This should be the non-instantiated version. - * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. - * @param {Phaser.Scene} [addToScene] - Optionally automatically add this plugin to the given Scene. - * @param {boolean} [fromLoader=false] - Is this being called by the Loader? - */ - installScenePlugin: function (key, plugin, mapping, addToScene, fromLoader) - { - if (fromLoader === undefined) { fromLoader = false; } - - if (typeof plugin !== 'function') - { - console.warn('Invalid Scene Plugin: ' + key); - return; - } - - if (!PluginCache.hasCore(key)) - { - // Plugin is freshly loaded - PluginCache.register(key, plugin, mapping, true); - - this.scenePlugins.push(key); - } - else if (!fromLoader && PluginCache.hasCore(key)) - { - // Plugin wasn't from the loader but already exists - console.warn('Scene Plugin key in use: ' + key); - return; - } - - if (addToScene) - { - var instance = new plugin(addToScene, this); - - addToScene.sys[key] = instance; - - if (mapping && mapping !== '') - { - addToScene[mapping] = instance; - } - - instance.boot(); - } - }, - - /** - * Installs a new Global Plugin into the Plugin Manager and optionally starts it running. - * A global plugin belongs to the Plugin Manager, rather than a specific Scene, and can be accessed - * and used by all Scenes in your game. - * - * The `key` property is what you use to access this plugin from the Plugin Manager. - * - * ```javascript - * this.plugins.install('powerupsPlugin', pluginCode); - * - * // and from within the scene: - * this.plugins.get('powerupsPlugin'); - * ``` - * - * This method is called automatically by Phaser if you install your plugins using either the - * Game Configuration object, or by preloading them via the Loader. - * - * The same plugin can be installed multiple times into the Plugin Manager by simply giving each - * instance its own unique key. - * - * @method Phaser.Plugins.PluginManager#install - * @since 3.8.0 - * - * @param {string} key - The unique handle given to this plugin within the Plugin Manager. - * @param {function} plugin - The plugin code. This should be the non-instantiated version. - * @param {boolean} [start=false] - Automatically start the plugin running? This is always `true` if you provide a mapping value. - * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. - * @param {any} [data] - A value passed to the plugin's `init` method. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if `start` was false, or game isn't yet booted. - */ - install: function (key, plugin, start, mapping, data) - { - if (start === undefined) { start = false; } - if (mapping === undefined) { mapping = null; } - if (data === undefined) { data = null; } - - if (typeof plugin !== 'function') - { - console.warn('Invalid Plugin: ' + key); - return null; - } - - if (PluginCache.hasCustom(key)) - { - console.warn('Plugin key in use: ' + key); - return null; - } - - if (mapping !== null) - { - start = true; - } - - if (!this.game.isBooted) - { - this._pendingGlobal.push({ key: key, plugin: plugin, start: start, mapping: mapping, data: data }); - } - else - { - // Add it to the plugin store - PluginCache.registerCustom(key, plugin, mapping, data); - - if (start) - { - return this.start(key); - } - } - - return null; - }, - - /** - * Gets an index of a global plugin based on the given key. - * - * @method Phaser.Plugins.PluginManager#getIndex - * @protected - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {number} The index of the plugin within the plugins array. - */ - getIndex: function (key) - { - var list = this.plugins; - - for (var i = 0; i < list.length; i++) - { - var entry = list[i]; - - if (entry.key === key) - { - return i; - } - } - - return -1; - }, - - /** - * Gets a global plugin based on the given key. - * - * @method Phaser.Plugins.PluginManager#getEntry - * @protected - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {Phaser.Types.Plugins.GlobalPlugin} The plugin entry. - */ - getEntry: function (key) - { - var idx = this.getIndex(key); - - if (idx !== -1) - { - return this.plugins[idx]; - } - }, - - /** - * Checks if the given global plugin, based on its key, is active or not. - * - * @method Phaser.Plugins.PluginManager#isActive - * @since 3.8.0 - * - * @param {string} key - The unique plugin key. - * - * @return {boolean} `true` if the plugin is active, otherwise `false`. - */ - isActive: function (key) - { - var entry = this.getEntry(key); - - return (entry && entry.active); - }, - - /** - * Starts a global plugin running. - * - * If the plugin was previously active then calling `start` will reset it to an active state and then - * call its `start` method. - * - * If the plugin has never been run before a new instance of it will be created within the Plugin Manager, - * its active state set and then both of its `init` and `start` methods called, in that order. - * - * If the plugin is already running under the given key then nothing happens. - * - * @method Phaser.Plugins.PluginManager#start - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to start. - * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given or plugin is already stopped. - */ - start: function (key, runAs) - { - if (runAs === undefined) { runAs = key; } - - var entry = this.getEntry(runAs); - - // Plugin already running under this key? - if (entry && !entry.active) - { - // It exists, we just need to start it up again - entry.active = true; - entry.plugin.start(); - } - else if (!entry) - { - entry = this.createEntry(key, runAs); - } - - return (entry) ? entry.plugin : null; - }, - - /** - * Creates a new instance of a global plugin, adds an entry into the plugins array and returns it. - * - * @method Phaser.Plugins.PluginManager#createEntry - * @private - * @since 3.9.0 - * - * @param {string} key - The key of the plugin to create an instance of. - * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. - * - * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given. - */ - createEntry: function (key, runAs) - { - var entry = PluginCache.getCustom(key); - - if (entry) - { - var instance = new entry.plugin(this); - - entry = { - key: runAs, - plugin: instance, - active: true, - mapping: entry.mapping, - data: entry.data - }; - - this.plugins.push(entry); - - instance.init(entry.data); - instance.start(); - } - - return entry; - }, - - /** - * Stops a global plugin from running. - * - * If the plugin is active then its active state will be set to false and the plugins `stop` method - * will be called. - * - * If the plugin is not already running, nothing will happen. - * - * @method Phaser.Plugins.PluginManager#stop - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to stop. - * - * @return {this} The Plugin Manager. - */ - stop: function (key) - { - var entry = this.getEntry(key); - - if (entry && entry.active) - { - entry.active = false; - entry.plugin.stop(); - } - - return this; - }, - - /** - * Gets a global plugin from the Plugin Manager based on the given key and returns it. - * - * If it cannot find an active plugin based on the key, but there is one in the Plugin Cache with the same key, - * then it will create a new instance of the cached plugin and return that. - * - * @method Phaser.Plugins.PluginManager#get - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to get. - * @param {boolean} [autoStart=true] - Automatically start a new instance of the plugin if found in the cache, but not actively running. - * - * @return {?(Phaser.Plugins.BasePlugin|function)} The plugin, or `null` if no plugin was found matching the key. - */ - get: function (key, autoStart) - { - if (autoStart === undefined) { autoStart = true; } - - var entry = this.getEntry(key); - - if (entry) - { - return entry.plugin; - } - else - { - var plugin = this.getClass(key); - - if (plugin && autoStart) - { - entry = this.createEntry(key, key); - - return (entry) ? entry.plugin : null; - } - else if (plugin) - { - return plugin; - } - } - - return null; - }, - - /** - * Returns the plugin class from the cache. - * Used internally by the Plugin Manager. - * - * @method Phaser.Plugins.PluginManager#getClass - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to get. - * - * @return {Phaser.Plugins.BasePlugin} A Plugin object - */ - getClass: function (key) - { - return PluginCache.getCustomClass(key); - }, - - /** - * Removes a global plugin from the Plugin Manager and Plugin Cache. - * - * It is up to you to remove all references to this plugin that you may hold within your game code. - * - * @method Phaser.Plugins.PluginManager#removeGlobalPlugin - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to remove. - */ - removeGlobalPlugin: function (key) - { - var entry = this.getEntry(key); - - if (entry) - { - Remove(this.plugins, entry); - } - - PluginCache.removeCustom(key); - }, - - /** - * Removes a scene plugin from the Plugin Manager and Plugin Cache. - * - * This will not remove the plugin from any active Scenes that are already using it. - * - * It is up to you to remove all references to this plugin that you may hold within your game code. - * - * @method Phaser.Plugins.PluginManager#removeScenePlugin - * @since 3.8.0 - * - * @param {string} key - The key of the plugin to remove. - */ - removeScenePlugin: function (key) - { - Remove(this.scenePlugins, key); - - PluginCache.remove(key); - }, - - /** - * Registers a new type of Game Object with the global Game Object Factory and / or Creator. - * This is usually called from within your Plugin code and is a helpful short-cut for creating - * new Game Objects. - * - * The key is the property that will be injected into the factories and used to create the - * Game Object. For example: - * - * ```javascript - * this.plugins.registerGameObject('clown', clownFactoryCallback, clownCreatorCallback); - * // later in your game code: - * this.add.clown(); - * this.make.clown(); - * ``` - * - * The callbacks are what are called when the factories try to create a Game Object - * matching the given key. It's important to understand that the callbacks are invoked within - * the context of the GameObjectFactory. In this context there are several properties available - * to use: - * - * this.scene - A reference to the Scene that owns the GameObjectFactory. - * this.displayList - A reference to the Display List the Scene owns. - * this.updateList - A reference to the Update List the Scene owns. - * - * See the GameObjectFactory and GameObjectCreator classes for more details. - * Any public property or method listed is available from your callbacks under `this`. - * - * @method Phaser.Plugins.PluginManager#registerGameObject - * @since 3.8.0 - * - * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. - * @param {function} [factoryCallback] - The callback to invoke when the Game Object Factory is called. - * @param {function} [creatorCallback] - The callback to invoke when the Game Object Creator is called. - */ - registerGameObject: function (key, factoryCallback, creatorCallback) - { - if (factoryCallback) - { - GameObjectFactory.register(key, factoryCallback); - } - - if (creatorCallback) - { - GameObjectCreator.register(key, creatorCallback); - } - - return this; - }, - - /** - * Removes a previously registered Game Object from the global Game Object Factory and / or Creator. - * This is usually called from within your Plugin destruction code to help clean-up after your plugin has been removed. - * - * @method Phaser.Plugins.PluginManager#removeGameObject - * @since 3.19.0 - * - * @param {string} key - The key of the Game Object to be removed from the factories. - * @param {boolean} [removeFromFactory=true] - Should the Game Object be removed from the Game Object Factory? - * @param {boolean} [removeFromCreator=true] - Should the Game Object be removed from the Game Object Creator? - */ - removeGameObject: function (key, removeFromFactory, removeFromCreator) - { - if (removeFromFactory === undefined) { removeFromFactory = true; } - if (removeFromCreator === undefined) { removeFromCreator = true; } - - if (removeFromFactory) - { - GameObjectFactory.remove(key); - } - - if (removeFromCreator) - { - GameObjectCreator.remove(key); - } - - return this; - }, - - /** - * Registers a new file type with the global File Types Manager, making it available to all Loader - * Plugins created after this. - * - * This is usually called from within your Plugin code and is a helpful short-cut for creating - * new loader file types. - * - * The key is the property that will be injected into the Loader Plugin and used to load the - * files. For example: - * - * ```javascript - * this.plugins.registerFileType('wad', doomWadLoaderCallback); - * // later in your preload code: - * this.load.wad(); - * ``` - * - * The callback is what is called when the loader tries to load a file matching the given key. - * It's important to understand that the callback is invoked within - * the context of the LoaderPlugin. In this context there are several properties / methods available - * to use: - * - * this.addFile - A method to add the new file to the load queue. - * this.scene - The Scene that owns the Loader Plugin instance. - * - * See the LoaderPlugin class for more details. Any public property or method listed is available from - * your callback under `this`. - * - * @method Phaser.Plugins.PluginManager#registerFileType - * @since 3.8.0 - * - * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. - * @param {function} callback - The callback to invoke when the Game Object Factory is called. - * @param {Phaser.Scene} [addToScene] - Optionally add this file type into the Loader Plugin owned by the given Scene. - */ - registerFileType: function (key, callback, addToScene) - { - FileTypesManager.register(key, callback); - - if (addToScene && addToScene.sys.load) - { - addToScene.sys.load[key] = callback; - } - }, - - /** - * Destroys this Plugin Manager and all associated plugins. - * It will iterate all plugins found and call their `destroy` methods. - * - * The PluginCache will remove all custom plugins. - * - * @method Phaser.Plugins.PluginManager#destroy - * @since 3.8.0 - */ - destroy: function () - { - for (var i = 0; i < this.plugins.length; i++) - { - this.plugins[i].plugin.destroy(); - } - - PluginCache.destroyCustomPlugins(); - - if (this.game.noReturn) - { - PluginCache.destroyCorePlugins(); - } - - this.game = null; - this.plugins = []; - this.scenePlugins = []; - } - -}); - -/* - * "Sometimes, the elegant implementation is just a function. - * Not a method. Not a class. Not a framework. Just a function." - * -- John Carmack - */ - -module.exports = PluginManager; - - -/***/ }), -/* 393 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(196); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(101); -var GameEvents = __webpack_require__(22); -var GetInnerHeight = __webpack_require__(379); -var GetTarget = __webpack_require__(385); -var GetScreenOrientation = __webpack_require__(380); -var NOOP = __webpack_require__(1); -var Rectangle = __webpack_require__(10); -var Size = __webpack_require__(394); -var SnapFloor = __webpack_require__(76); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * The Scale Manager handles the scaling, resizing and alignment of the game canvas. - * - * The way scaling is handled is by setting the game canvas to a fixed size, which is defined in the - * game configuration. You also define the parent container in the game config. If no parent is given, - * it will default to using the document body. The Scale Manager will then look at the available space - * within the _parent_ and scale the canvas accordingly. Scaling is handled by setting the canvas CSS - * width and height properties, leaving the width and height of the canvas element itself untouched. - * Scaling is therefore achieved by keeping the core canvas the same size and 'stretching' - * it via its CSS properties. This gives the same result and speed as using the `transform-scale` CSS - * property, without the need for browser prefix handling. - * - * The calculations for the scale are heavily influenced by the bounding parent size, which is the computed - * dimensions of the canvas's parent. The CSS rules of the parent element play an important role in the - * operation of the Scale Manager. For example, if the parent has no defined width or height, then actions - * like auto-centering will fail to achieve the required result. The Scale Manager works in tandem with the - * CSS you set-up on the page hosting your game, rather than taking control of it. - * - * #### Parent and Display canvas containment guidelines: - * - * - Style the Parent element (of the game canvas) to control the Parent size and thus the games size and layout. - * - * - The Parent element's CSS styles should _effectively_ apply maximum (and minimum) bounding behavior. - * - * - The Parent element should _not_ apply a padding as this is not accounted for. - * If a padding is required apply it to the Parent's parent or apply a margin to the Parent. - * If you need to add a border, margin or any other CSS around your game container, then use a parent element and - * apply the CSS to this instead, otherwise you'll be constantly resizing the shape of the game container. - * - * - The Display canvas layout CSS styles (i.e. margins, size) should not be altered / specified as - * they may be updated by the Scale Manager. - * - * #### Scale Modes - * - * The way the scaling is handled is determined by the `scaleMode` property. The default is `NONE`, - * which prevents Phaser from scaling or touching the canvas, or its parent, at all. In this mode, you are - * responsible for all scaling. The other scaling modes afford you automatic scaling. - * - * If you wish to scale your game so that it always fits into the available space within the parent, you - * should use the scale mode `FIT`. Look at the documentation for other scale modes to see what options are - * available. Here is a basic config showing how to set this scale mode: - * - * ```javascript - * scale: { - * parent: 'yourgamediv', - * mode: Phaser.Scale.FIT, - * width: 800, - * height: 600 - * } - * ``` - * - * Place the `scale` config object within your game config. - * - * If you wish for the canvas to be resized directly, so that the canvas itself fills the available space - * (i.e. it isn't scaled, it's resized) then use the `RESIZE` scale mode. This will give you a 1:1 mapping - * of canvas pixels to game size. In this mode CSS isn't used to scale the canvas, it's literally adjusted - * to fill all available space within the parent. You should be extremely careful about the size of the - * canvas you're creating when doing this, as the larger the area, the more work the GPU has to do and it's - * very easy to hit fill-rate limits quickly. - * - * For complex, custom-scaling requirements, you should probably consider using the `RESIZE` scale mode, - * with your own limitations in place re: canvas dimensions and managing the scaling with the game scenes - * yourself. For the vast majority of games, however, the `FIT` mode is likely to be the most used. - * - * Please appreciate that the Scale Manager cannot perform miracles. All it does is scale your game canvas - * as best it can, based on what it can infer from its surrounding area. There are all kinds of environments - * where it's up to you to guide and help the canvas position itself, especially when built into rendering - * frameworks like React and Vue. If your page requires meta tags to prevent user scaling gestures, or such - * like, then it's up to you to ensure they are present in the html. - * - * #### Centering - * - * You can also have the game canvas automatically centered. Again, this relies heavily on the parent being - * properly configured and styled, as the centering offsets are based entirely on the available space - * within the parent element. Centering is disabled by default, or can be applied horizontally, vertically, - * or both. Here's an example: - * - * ```javascript - * scale: { - * parent: 'yourgamediv', - * autoCenter: Phaser.Scale.CENTER_BOTH, - * width: 800, - * height: 600 - * } - * ``` - * - * #### Fullscreen API - * - * If the browser supports it, you can send your game into fullscreen mode. In this mode, the game will fill - * the entire display, removing all browser UI and anything else present on the screen. It will remain in this - * mode until your game either disables it, or until the user tabs out or presses ESCape if on desktop. It's a - * great way to achieve a desktop-game like experience from the browser, but it does require a modern browser - * to handle it. Some mobile browsers also support this. - * - * @class ScaleManager - * @memberof Phaser.Scale - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.16.0 - * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance. - */ -var ScaleManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function ScaleManager (game) - { - EventEmitter.call(this); - - /** - * A reference to the Phaser.Game instance. - * - * @name Phaser.Scale.ScaleManager#game - * @type {Phaser.Game} - * @readonly - * @since 3.15.0 - */ - this.game = game; - - /** - * A reference to the HTML Canvas Element that Phaser uses to render the game. - * - * @name Phaser.Scale.ScaleManager#canvas - * @type {HTMLCanvasElement} - * @since 3.16.0 - */ - this.canvas; - - /** - * The DOM bounds of the canvas element. - * - * @name Phaser.Scale.ScaleManager#canvasBounds - * @type {Phaser.Geom.Rectangle} - * @since 3.16.0 - */ - this.canvasBounds = new Rectangle(); - - /** - * The parent object of the Canvas. Often a div, or the browser window, or nothing in non-browser environments. - * - * This is set in the Game Config as the `parent` property. If undefined (or just not present), it will default - * to use the document body. If specifically set to `null` Phaser will ignore all parent operations. - * - * @name Phaser.Scale.ScaleManager#parent - * @type {?any} - * @since 3.16.0 - */ - this.parent = null; - - /** - * Is the parent element the browser window? - * - * @name Phaser.Scale.ScaleManager#parentIsWindow - * @type {boolean} - * @since 3.16.0 - */ - this.parentIsWindow = false; - - /** - * The Parent Size component. - * - * @name Phaser.Scale.ScaleManager#parentSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.parentSize = new Size(); - - /** - * The Game Size component. - * - * The un-modified game size, as requested in the game config (the raw width / height), - * as used for world bounds, cameras, etc - * - * @name Phaser.Scale.ScaleManager#gameSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.gameSize = new Size(); - - /** - * The Base Size component. - * - * The modified game size, which is the auto-rounded gameSize, used to set the canvas width and height - * (but not the CSS style) - * - * @name Phaser.Scale.ScaleManager#baseSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.baseSize = new Size(); - - /** - * The Display Size component. - * - * The size used for the canvas style, factoring in the scale mode, parent and other values. - * - * @name Phaser.Scale.ScaleManager#displaySize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.displaySize = new Size(); - - /** - * The game scale mode. - * - * @name Phaser.Scale.ScaleManager#scaleMode - * @type {Phaser.Scale.ScaleModeType} - * @since 3.16.0 - */ - this.scaleMode = CONST.SCALE_MODE.NONE; - - /** - * The game zoom factor. - * - * This value allows you to multiply your games base size by the given zoom factor. - * This is then used when calculating the display size, even in `NONE` situations. - * If you don't want Phaser to touch the canvas style at all, this value should be 1. - * - * Can also be set to `MAX_ZOOM` in which case the zoom value will be derived based - * on the game size and available space within the parent. - * - * @name Phaser.Scale.ScaleManager#zoom - * @type {number} - * @since 3.16.0 - */ - this.zoom = 1; - - /** - * Internal flag set when the game zoom factor is modified. - * - * @name Phaser.Scale.ScaleManager#_resetZoom - * @type {boolean} - * @readonly - * @since 3.19.0 - */ - this._resetZoom = false; - - /** - * The scale factor between the baseSize and the canvasBounds. - * - * @name Phaser.Scale.ScaleManager#displayScale - * @type {Phaser.Math.Vector2} - * @since 3.16.0 - */ - this.displayScale = new Vector2(1, 1); - - /** - * If set, the canvas sizes will be automatically passed through Math.floor. - * This results in rounded pixel display values, which is important for performance on legacy - * and low powered devices, but at the cost of not achieving a 'perfect' fit in some browser windows. - * - * @name Phaser.Scale.ScaleManager#autoRound - * @type {boolean} - * @since 3.16.0 - */ - this.autoRound = false; - - /** - * Automatically center the canvas within the parent? The different centering modes are: - * - * 1. No centering. - * 2. Center both horizontally and vertically. - * 3. Center horizontally. - * 4. Center vertically. - * - * Please be aware that in order to center the game canvas, you must have specified a parent - * that has a size set, or the canvas parent is the document.body. - * - * @name Phaser.Scale.ScaleManager#autoCenter - * @type {Phaser.Scale.CenterType} - * @since 3.16.0 - */ - this.autoCenter = CONST.CENTER.NO_CENTER; - - /** - * The current device orientation. - * - * Orientation events are dispatched via the Device Orientation API, typically only on mobile browsers. - * - * @name Phaser.Scale.ScaleManager#orientation - * @type {Phaser.Scale.OrientationType} - * @since 3.16.0 - */ - this.orientation = CONST.ORIENTATION.LANDSCAPE; - - /** - * A reference to the Device.Fullscreen object. - * - * @name Phaser.Scale.ScaleManager#fullscreen - * @type {Phaser.Device.Fullscreen} - * @since 3.16.0 - */ - this.fullscreen; - - /** - * The DOM Element which is sent into fullscreen mode. - * - * @name Phaser.Scale.ScaleManager#fullscreenTarget - * @type {?any} - * @since 3.16.0 - */ - this.fullscreenTarget = null; - - /** - * Did Phaser create the fullscreen target div, or was it provided in the game config? - * - * @name Phaser.Scale.ScaleManager#_createdFullscreenTarget - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._createdFullscreenTarget = false; - - /** - * The dirty state of the Scale Manager. - * Set if there is a change between the parent size and the current size. - * - * @name Phaser.Scale.ScaleManager#dirty - * @type {boolean} - * @since 3.16.0 - */ - this.dirty = false; - - /** - * How many milliseconds should elapse before checking if the browser size has changed? - * - * Most modern browsers dispatch a 'resize' event, which the Scale Manager will listen for. - * However, older browsers fail to do this, or do it consistently, so we fall back to a - * more traditional 'size check' based on a time interval. You can control how often it is - * checked here. - * - * @name Phaser.Scale.ScaleManager#resizeInterval - * @type {number} - * @since 3.16.0 - */ - this.resizeInterval = 500; - - /** - * Internal size interval tracker. - * - * @name Phaser.Scale.ScaleManager#_lastCheck - * @type {number} - * @private - * @since 3.16.0 - */ - this._lastCheck = 0; - - /** - * Internal flag to check orientation state. - * - * @name Phaser.Scale.ScaleManager#_checkOrientation - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._checkOrientation = false; - - /** - * Internal object containing our defined event listeners. - * - * @name Phaser.Scale.ScaleManager#listeners - * @type {object} - * @private - * @since 3.16.0 - */ - this.listeners = { - - orientationChange: NOOP, - windowResize: NOOP, - fullScreenChange: NOOP, - fullScreenError: NOOP - - }; - }, - - /** - * Called _before_ the canvas object is created and added to the DOM. - * - * @method Phaser.Scale.ScaleManager#preBoot - * @protected - * @listens Phaser.Core.Events#BOOT - * @since 3.16.0 - */ - preBoot: function () - { - // Parse the config to get the scaling values we need - this.parseConfig(this.game.config); - - this.game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot handler is called by Phaser.Game when it first starts up. - * The renderer is available by now and the canvas has been added to the DOM. - * - * @method Phaser.Scale.ScaleManager#boot - * @protected - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - */ - boot: function () - { - var game = this.game; - - this.canvas = game.canvas; - - this.fullscreen = game.device.fullscreen; - - if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) - { - this.displaySize.setAspectMode(this.scaleMode); - } - - if (this.scaleMode === CONST.SCALE_MODE.NONE) - { - this.resize(this.width, this.height); - } - else - { - this.getParentBounds(); - - // Only set the parent bounds if the parent has an actual size - if (this.parentSize.width > 0 && this.parentSize.height > 0) - { - this.displaySize.setParent(this.parentSize); - } - - this.refresh(); - } - - game.events.on(GameEvents.PRE_STEP, this.step, this); - game.events.once(GameEvents.READY, this.refresh, this); - game.events.once(GameEvents.DESTROY, this.destroy, this); - - this.startListeners(); - }, - - /** - * Parses the game configuration to set-up the scale defaults. - * - * @method Phaser.Scale.ScaleManager#parseConfig - * @protected - * @since 3.16.0 - * - * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. - */ - parseConfig: function (config) - { - // Get the parent element, if any - this.getParent(config); - - // Get the size of the parent element - // This can often set a height of zero (especially for un-styled divs) - this.getParentBounds(); - - var width = config.width; - var height = config.height; - var scaleMode = config.scaleMode; - var zoom = config.zoom; - var autoRound = config.autoRound; - - // If width = '100%', or similar value - if (typeof width === 'string') - { - // If we have a parent with a height, we'll work it out from that - var parentWidth = this.parentSize.width; - - if (parentWidth === 0) - { - parentWidth = window.innerWidth; - } - - var parentScaleX = parseInt(width, 10) / 100; - - width = Math.floor(parentWidth * parentScaleX); - } - - // If height = '100%', or similar value - if (typeof height === 'string') - { - // If we have a parent with a height, we'll work it out from that - var parentHeight = this.parentSize.height; - - if (parentHeight === 0) - { - parentHeight = window.innerHeight; - } - - var parentScaleY = parseInt(height, 10) / 100; - - height = Math.floor(parentHeight * parentScaleY); - } - - this.scaleMode = scaleMode; - - this.autoRound = autoRound; - - this.autoCenter = config.autoCenter; - - this.resizeInterval = config.resizeInterval; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.setSize(width, height); - - if (zoom === CONST.ZOOM.MAX_ZOOM) - { - zoom = this.getMaxZoom(); - } - - this.zoom = zoom; - - if (zoom !== 1) - { - this._resetZoom = true; - } - - // The modified game size - this.baseSize.setSize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - if (config.minWidth > 0) - { - this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom); - } - - if (config.maxWidth > 0) - { - this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) - this.displaySize.setSize(width, height); - - this.orientation = GetScreenOrientation(width, height); - }, - - /** - * Determines the parent element of the game canvas, if any, based on the game configuration. - * - * @method Phaser.Scale.ScaleManager#getParent - * @since 3.16.0 - * - * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. - */ - getParent: function (config) - { - var parent = config.parent; - - if (parent === null) - { - // User is responsible for managing the parent - return; - } - - this.parent = GetTarget(parent); - this.parentIsWindow = (this.parent === document.body); - - if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) - { - var DOMRect = this.parent.getBoundingClientRect(); - - if (this.parentIsWindow || DOMRect.height === 0) - { - document.documentElement.style.height = '100%'; - document.body.style.height = '100%'; - - DOMRect = this.parent.getBoundingClientRect(); - - // The parent STILL has no height, clearly no CSS - // has been set on it even though we fixed the body :( - if (!this.parentIsWindow && DOMRect.height === 0) - { - this.parent.style.overflow = 'hidden'; - this.parent.style.width = '100%'; - this.parent.style.height = '100%'; - } - } - } - - // And now get the fullscreenTarget - if (config.fullscreenTarget && !this.fullscreenTarget) - { - this.fullscreenTarget = GetTarget(config.fullscreenTarget); - } - }, - - /** - * Calculates the size of the parent bounds and updates the `parentSize` component, if the canvas has a dom parent. - * - * @method Phaser.Scale.ScaleManager#getParentBounds - * @since 3.16.0 - * - * @return {boolean} `true` if the parent bounds have changed size, otherwise `false`. - */ - getParentBounds: function () - { - if (!this.parent) - { - return false; - } - - var parentSize = this.parentSize; - - // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect - - var DOMRect = this.parent.getBoundingClientRect(); - - if (this.parentIsWindow && this.game.device.os.iOS) - { - DOMRect.height = GetInnerHeight(true); - } - - var newWidth = DOMRect.width; - var newHeight = DOMRect.height; - - if (parentSize.width !== newWidth || parentSize.height !== newHeight) - { - parentSize.setSize(newWidth, newHeight); - - return true; - } - else - { - return false; - } - }, - - /** - * Attempts to lock the orientation of the web browser using the Screen Orientation API. - * - * This API is only available on modern mobile browsers. - * See https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation for details. - * - * @method Phaser.Scale.ScaleManager#lockOrientation - * @since 3.16.0 - * - * @param {string} orientation - The orientation you'd like to lock the browser in. Should be an API string such as 'landscape', 'landscape-primary', 'portrait', etc. - * - * @return {boolean} `true` if the orientation was successfully locked, otherwise `false`. - */ - lockOrientation: function (orientation) - { - var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation; - - if (lock) - { - return lock.call(screen, orientation); - } - - return false; - }, - - /** - * This method will set the size of the Parent Size component, which is used in scaling - * and centering calculations. You only need to call this method if you have explicitly - * disabled the use of a parent in your game config, but still wish to take advantage of - * other Scale Manager features. - * - * @method Phaser.Scale.ScaleManager#setParentSize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the parent. - * @param {number} height - The new height of the parent. - * - * @return {this} The Scale Manager instance. - */ - setParentSize: function (width, height) - { - this.parentSize.setSize(width, height); - - return this.refresh(); - }, - - /** - * This method will set a new size for your game. - * - * It should only be used if you're looking to change the base size of your game and are using - * one of the Scale Manager scaling modes, i.e. `FIT`. If you're using `NONE` and wish to - * change the game and canvas size directly, then please use the `resize` method instead. - * - * @method Phaser.Scale.ScaleManager#setGameSize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the game. - * @param {number} height - The new height of the game. - * - * @return {this} The Scale Manager instance. - */ - setGameSize: function (width, height) - { - var autoRound = this.autoRound; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - var previousWidth = this.width; - var previousHeight = this.height; - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.resize(width, height); - - // The modified game size - this.baseSize.resize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // Update the aspect ratio - this.displaySize.setAspectRatio(width / height); - - this.canvas.width = this.baseSize.width; - this.canvas.height = this.baseSize.height; - - return this.refresh(previousWidth, previousHeight); - }, - - /** - * Call this to modify the size of the Phaser canvas element directly. - * You should only use this if you are using the `NONE` scale mode, - * it will update all internal components completely. - * - * If all you want to do is change the size of the parent, see the `setParentSize` method. - * - * If all you want is to change the base size of the game, but still have the Scale Manager - * manage all the scaling (i.e. you're **not** using `NONE`), then see the `setGameSize` method. - * - * This method will set the `gameSize`, `baseSize` and `displaySize` components to the given - * dimensions. It will then resize the canvas width and height to the values given, by - * directly setting the properties. Finally, if you have set the Scale Manager zoom value - * to anything other than 1 (the default), it will set the canvas CSS width and height to - * be the given size multiplied by the zoom factor (the canvas pixel size remains untouched). - * - * If you have enabled `autoCenter`, it is then passed to the `updateCenter` method and - * the margins are set, allowing the canvas to be centered based on its parent element - * alone. Finally, the `displayScale` is adjusted and the RESIZE event dispatched. - * - * @method Phaser.Scale.ScaleManager#resize - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} width - The new width of the game. - * @param {number} height - The new height of the game. - * - * @return {this} The Scale Manager instance. - */ - resize: function (width, height) - { - var zoom = this.zoom; - var autoRound = this.autoRound; - - if (autoRound) - { - width = Math.floor(width); - height = Math.floor(height); - } - - var previousWidth = this.width; - var previousHeight = this.height; - - // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc - this.gameSize.resize(width, height); - - // The modified game size - this.baseSize.resize(width, height); - - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } - - // The size used for the canvas style, factoring in the scale mode and parent and zoom value - // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) - this.displaySize.setSize((width * zoom), (height * zoom)); - - this.canvas.width = this.baseSize.width; - this.canvas.height = this.baseSize.height; - - var style = this.canvas.style; - - var styleWidth = width * zoom; - var styleHeight = height * zoom; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - if (styleWidth !== width || styleHeight !== height) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } - - return this.refresh(previousWidth, previousHeight); - }, - - /** - * Sets the zoom value of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#setZoom - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} value - The new zoom value of the game. - * - * @return {this} The Scale Manager instance. - */ - setZoom: function (value) - { - this.zoom = value; - this._resetZoom = true; - - return this.refresh(); - }, - - /** - * Sets the zoom to be the maximum possible based on the _current_ parent size. - * - * @method Phaser.Scale.ScaleManager#setMaxZoom - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @return {this} The Scale Manager instance. - */ - setMaxZoom: function () - { - this.zoom = this.getMaxZoom(); - this._resetZoom = true; - - return this.refresh(); - }, - - /** - * Refreshes the internal scale values, bounds sizes and orientation checks. - * - * Once finished, dispatches the resize event. - * - * This is called automatically by the Scale Manager when the browser window size changes, - * as long as it is using a Scale Mode other than 'NONE'. - * - * @method Phaser.Scale.ScaleManager#refresh - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {number} [previousWidth] - The previous width of the game. Only set if the gameSize has changed. - * @param {number} [previousHeight] - The previous height of the game. Only set if the gameSize has changed. - * - * @return {this} The Scale Manager instance. - */ - refresh: function (previousWidth, previousHeight) - { - if (previousWidth === undefined) { previousWidth = this.width; } - if (previousHeight === undefined) { previousHeight = this.height; } - - this.updateScale(); - this.updateBounds(); - this.updateOrientation(); - - this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); - - var domContainer = this.game.domContainer; - - if (domContainer) - { - this.baseSize.setCSS(domContainer); - - var canvasStyle = this.canvas.style; - var domStyle = domContainer.style; - - domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; - - domStyle.marginLeft = canvasStyle.marginLeft; - domStyle.marginTop = canvasStyle.marginTop; - } - - this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); - - return this; - }, - - /** - * Internal method that checks the current screen orientation, only if the internal check flag is set. - * - * If the orientation has changed it updates the orientation property and then dispatches the orientation change event. - * - * @method Phaser.Scale.ScaleManager#updateOrientation - * @fires Phaser.Scale.Events#ORIENTATION_CHANGE - * @since 3.16.0 - */ - updateOrientation: function () - { - if (this._checkOrientation) - { - this._checkOrientation = false; - - var newOrientation = GetScreenOrientation(this.width, this.height); - - if (newOrientation !== this.orientation) - { - this.orientation = newOrientation; - - this.emit(Events.ORIENTATION_CHANGE, newOrientation); - } - } - }, - - /** - * Internal method that manages updating the size components based on the scale mode. - * - * @method Phaser.Scale.ScaleManager#updateScale - * @since 3.16.0 - */ - updateScale: function () - { - var style = this.canvas.style; - - var width = this.gameSize.width; - var height = this.gameSize.height; - - var styleWidth; - var styleHeight; - - var zoom = this.zoom; - var autoRound = this.autoRound; - - if (this.scaleMode === CONST.SCALE_MODE.NONE) - { - // No scale - this.displaySize.setSize((width * zoom), (height * zoom)); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - if (this._resetZoom) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - - this._resetZoom = false; - } - } - else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) - { - // Resize to match parent - - // This will constrain using min/max - this.displaySize.setSize(this.parentSize.width, this.parentSize.height); - - this.gameSize.setSize(this.displaySize.width, this.displaySize.height); - - this.baseSize.setSize(this.displaySize.width, this.displaySize.height); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - this.canvas.width = styleWidth; - this.canvas.height = styleHeight; - } - else - { - // All other scale modes - this.displaySize.setSize(this.parentSize.width, this.parentSize.height); - - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; - - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } - - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } - - // Update the parentSize in case the canvas / style change modified it - this.getParentBounds(); - - // Finally, update the centering - this.updateCenter(); - }, - - /** - * Calculates and returns the largest possible zoom factor, based on the current - * parent and game sizes. If the parent has no dimensions (i.e. an unstyled div), - * or is smaller than the un-zoomed game, then this will return a value of 1 (no zoom) - * - * @method Phaser.Scale.ScaleManager#getMaxZoom - * @since 3.16.0 - * - * @return {number} The maximum possible zoom factor. At a minimum this value is always at least 1. - */ - getMaxZoom: function () - { - var zoomH = SnapFloor(this.parentSize.width, this.gameSize.width, 0, true); - var zoomV = SnapFloor(this.parentSize.height, this.gameSize.height, 0, true); - - return Math.max(Math.min(zoomH, zoomV), 1); - }, - - /** - * Calculates and updates the canvas CSS style in order to center it within the - * bounds of its parent. If you have explicitly set parent to be `null` in your - * game config then this method will likely give incorrect results unless you have called the - * `setParentSize` method first. - * - * It works by modifying the canvas CSS `marginLeft` and `marginTop` properties. - * - * If they have already been set by your own style sheet, or code, this will overwrite them. - * - * To prevent the Scale Manager from centering the canvas, either do not set the - * `autoCenter` property in your game config, or make sure it is set to `NO_CENTER`. - * - * @method Phaser.Scale.ScaleManager#updateCenter - * @since 3.16.0 - */ - updateCenter: function () - { - var autoCenter = this.autoCenter; - - if (autoCenter === CONST.CENTER.NO_CENTER) - { - return; - } - - var canvas = this.canvas; - - var style = canvas.style; - - var bounds = canvas.getBoundingClientRect(); - - // var width = parseInt(canvas.style.width, 10) || canvas.width; - // var height = parseInt(canvas.style.height, 10) || canvas.height; - - var width = bounds.width; - var height = bounds.height; - - var offsetX = Math.floor((this.parentSize.width - width) / 2); - var offsetY = Math.floor((this.parentSize.height - height) / 2); - - if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) - { - offsetY = 0; - } - else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) - { - offsetX = 0; - } - - style.marginLeft = offsetX + 'px'; - style.marginTop = offsetY + 'px'; - }, - - /** - * Updates the `canvasBounds` rectangle to match the bounding client rectangle of the - * canvas element being used to track input events. - * - * @method Phaser.Scale.ScaleManager#updateBounds - * @since 3.16.0 - */ - updateBounds: function () - { - var bounds = this.canvasBounds; - var clientRect = this.canvas.getBoundingClientRect(); - - bounds.x = clientRect.left + (window.pageXOffset || 0) - (document.documentElement.clientLeft || 0); - bounds.y = clientRect.top + (window.pageYOffset || 0) - (document.documentElement.clientTop || 0); - bounds.width = clientRect.width; - bounds.height = clientRect.height; - }, - - /** - * Transforms the pageX value into the scaled coordinate space of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#transformX - * @since 3.16.0 - * - * @param {number} pageX - The DOM pageX value. - * - * @return {number} The translated value. - */ - transformX: function (pageX) - { - return (pageX - this.canvasBounds.left) * this.displayScale.x; - }, - - /** - * Transforms the pageY value into the scaled coordinate space of the Scale Manager. - * - * @method Phaser.Scale.ScaleManager#transformY - * @since 3.16.0 - * - * @param {number} pageY - The DOM pageY value. - * - * @return {number} The translated value. - */ - transformY: function (pageY) - { - return (pageY - this.canvasBounds.top) * this.displayScale.y; - }, - - /** - * Sends a request to the browser to ask it to go in to full screen mode, using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API Fullscreen API}. - * - * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. - * - * This method _must_ be called from a `pointerup` user-input gesture (**not** `pointerdown`). You cannot launch - * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked - * from fullscreen unless the iframe has the `allowfullscreen` attribute. - * - * On touch devices, such as Android and iOS Safari, you should always use `pointerup` and NOT `pointerdown`, - * otherwise the request will fail unless the document in which your game is embedded has already received - * some form of touch input, which you cannot guarantee. Activating fullscreen via `pointerup` circumvents - * this issue. - * - * Performing an action that navigates to another page, or opens another tab, will automatically cancel - * fullscreen mode, as will the user pressing the ESC key. To cancel fullscreen mode directly from your game, - * i.e. by clicking an icon, call the `stopFullscreen` method. - * - * A browser can only send one DOM element into fullscreen. You can control which element this is by - * setting the `fullscreenTarget` property in your game config, or changing the property in the Scale Manager. - * Note that the game canvas _must_ be a child of the target. If you do not give a target, Phaser will - * automatically create a blank `
` element and move the canvas into it, before going fullscreen. - * When it leaves fullscreen, the div will be removed. - * - * @method Phaser.Scale.ScaleManager#startFullscreen - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_FAILED - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. - */ - startFullscreen: function (fullscreenOptions) - { - if (fullscreenOptions === undefined) { fullscreenOptions = { navigationUI: 'hide' }; } - - var fullscreen = this.fullscreen; - - if (!fullscreen.available) - { - this.emit(Events.FULLSCREEN_UNSUPPORTED); - - return; - } - - if (!fullscreen.active) - { - var fsTarget = this.getFullscreenTarget(); - - if (fullscreen.keyboard) - { - fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); - } - else - { - fsTarget[fullscreen.request](fullscreenOptions); - } - } - }, - - /** - * The browser has successfully entered fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#fullscreenSuccessHandler - * @private - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#RESIZE - * @since 3.17.0 - */ - fullscreenSuccessHandler: function () - { - this.getParentBounds(); - - this.refresh(); - - this.emit(Events.ENTER_FULLSCREEN); - }, - - /** - * The browser failed to enter fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#fullscreenErrorHandler - * @private - * @fires Phaser.Scale.Events#FULLSCREEN_FAILED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.17.0 - * - * @param {any} error - The DOM error event. - */ - fullscreenErrorHandler: function (error) - { - this.removeFullscreenTarget(); - - this.emit(Events.FULLSCREEN_FAILED, error); - }, - - /** - * An internal method that gets the target element that is used when entering fullscreen mode. - * - * @method Phaser.Scale.ScaleManager#getFullscreenTarget - * @since 3.16.0 - * - * @return {object} The fullscreen target element. - */ - getFullscreenTarget: function () - { - if (!this.fullscreenTarget) - { - var fsTarget = document.createElement('div'); - - fsTarget.style.margin = '0'; - fsTarget.style.padding = '0'; - fsTarget.style.width = '100%'; - fsTarget.style.height = '100%'; - - this.fullscreenTarget = fsTarget; - - this._createdFullscreenTarget = true; - } - - if (this._createdFullscreenTarget) - { - var canvasParent = this.canvas.parentNode; - - canvasParent.insertBefore(this.fullscreenTarget, this.canvas); - - this.fullscreenTarget.appendChild(this.canvas); - } - - return this.fullscreenTarget; - }, - - /** - * Removes the fullscreen target that was added to the DOM. - * - * @method Phaser.Scale.ScaleManager#removeFullscreenTarget - * @since 3.17.0 - */ - removeFullscreenTarget: function () - { - if (this._createdFullscreenTarget) - { - var fsTarget = this.fullscreenTarget; - - if (fsTarget && fsTarget.parentNode) - { - var parent = fsTarget.parentNode; - - parent.insertBefore(this.canvas, fsTarget); - - parent.removeChild(fsTarget); - } - } - }, - - /** - * Calling this method will cancel fullscreen mode, if the browser has entered it. - * - * @method Phaser.Scale.ScaleManager#stopFullscreen - * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @since 3.16.0 - */ - stopFullscreen: function () - { - var fullscreen = this.fullscreen; - - if (!fullscreen.available) - { - this.emit(Events.FULLSCREEN_UNSUPPORTED); - - return false; - } - - if (fullscreen.active) - { - document[fullscreen.cancel](); - } - - this.removeFullscreenTarget(); - - // Get the parent size again as it will have changed - this.getParentBounds(); - - this.emit(Events.LEAVE_FULLSCREEN); - - this.refresh(); - }, - - /** - * Toggles the fullscreen mode. If already in fullscreen, calling this will cancel it. - * If not in fullscreen, this will request the browser to enter fullscreen mode. - * - * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. - * - * This method _must_ be called from a user-input gesture, such as `pointerdown`. You cannot launch - * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked - * from fullscreen unless the iframe has the `allowfullscreen` attribute. - * - * @method Phaser.Scale.ScaleManager#toggleFullscreen - * @fires Phaser.Scale.Events#ENTER_FULLSCREEN - * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN - * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @fires Phaser.Scale.Events#RESIZE - * @since 3.16.0 - * - * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. - */ - toggleFullscreen: function (fullscreenOptions) - { - if (this.fullscreen.active) - { - this.stopFullscreen(); - } - else - { - this.startFullscreen(fullscreenOptions); - } - }, - - /** - * An internal method that starts the different DOM event listeners running. - * - * @method Phaser.Scale.ScaleManager#startListeners - * @since 3.16.0 - */ - startListeners: function () - { - var _this = this; - var listeners = this.listeners; - - listeners.orientationChange = function () - { - _this.updateBounds(); - - _this._checkOrientation = true; - _this.dirty = true; - }; - - listeners.windowResize = function () - { - _this.updateBounds(); - - _this.dirty = true; - }; - - // Only dispatched on mobile devices - window.addEventListener('orientationchange', listeners.orientationChange, false); - - window.addEventListener('resize', listeners.windowResize, false); - - if (this.fullscreen.available) - { - listeners.fullScreenChange = function (event) - { - return _this.onFullScreenChange(event); - }; - - listeners.fullScreenError = function (event) - { - return _this.onFullScreenError(event); - }; - - var vendors = [ 'webkit', 'moz', '' ]; - - vendors.forEach(function (prefix) - { - document.addEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.addEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); - - // MS Specific - document.addEventListener('MSFullscreenChange', listeners.fullScreenChange, false); - document.addEventListener('MSFullscreenError', listeners.fullScreenError, false); - } - }, - - /** - * Triggered when a fullscreenchange event is dispatched by the DOM. - * - * @method Phaser.Scale.ScaleManager#onFullScreenChange - * @protected - * @since 3.16.0 - */ - onFullScreenChange: function () - { - if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) - { - this.fullscreenSuccessHandler(); - } - else - { - // They pressed ESC while in fullscreen mode - this.stopFullscreen(); - } - }, - - /** - * Triggered when a fullscreenerror event is dispatched by the DOM. - * - * @method Phaser.Scale.ScaleManager#onFullScreenError - * @since 3.16.0 - */ - onFullScreenError: function () - { - this.removeFullscreenTarget(); - }, - - /** - * Internal method, called automatically by the game step. - * Monitors the elapsed time and resize interval to see if a parent bounds check needs to take place. - * - * @method Phaser.Scale.ScaleManager#step - * @since 3.16.0 - * - * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). - * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. - */ - step: function (time, delta) - { - if (!this.parent) - { - return; - } - - this._lastCheck += delta; - - if (this.dirty || this._lastCheck > this.resizeInterval) - { - // Returns true if the parent bounds have changed size - if (this.getParentBounds()) - { - this.refresh(); - } - - this.dirty = false; - this._lastCheck = 0; - } - }, - - /** - * Stops all DOM event listeners. - * - * @method Phaser.Scale.ScaleManager#stopListeners - * @since 3.16.0 - */ - stopListeners: function () - { - var listeners = this.listeners; - - window.removeEventListener('orientationchange', listeners.orientationChange, false); - window.removeEventListener('resize', listeners.windowResize, false); - - var vendors = [ 'webkit', 'moz', '' ]; - - vendors.forEach(function (prefix) - { - document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); - - // MS Specific - document.removeEventListener('MSFullscreenChange', listeners.fullScreenChange, false); - document.removeEventListener('MSFullscreenError', listeners.fullScreenError, false); - }, - - /** - * Destroys this Scale Manager, releasing all references to external resources. - * Once destroyed, the Scale Manager cannot be used again. - * - * @method Phaser.Scale.ScaleManager#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.stopListeners(); - - this.game = null; - this.canvas = null; - this.canvasBounds = null; - this.parent = null; - this.fullscreenTarget = null; - - this.parentSize.destroy(); - this.gameSize.destroy(); - this.baseSize.destroy(); - this.displaySize.destroy(); - }, - - /** - * Is the browser currently in fullscreen mode or not? - * - * @name Phaser.Scale.ScaleManager#isFullscreen - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isFullscreen: { - - get: function () - { - return this.fullscreen.active; - } - - }, - - /** - * The game width. - * - * This is typically the size given in the game configuration. - * - * @name Phaser.Scale.ScaleManager#width - * @type {number} - * @readonly - * @since 3.16.0 - */ - width: { - - get: function () - { - return this.gameSize.width; - } - - }, - - /** - * The game height. - * - * This is typically the size given in the game configuration. - * - * @name Phaser.Scale.ScaleManager#height - * @type {number} - * @readonly - * @since 3.16.0 - */ - height: { - - get: function () - { - return this.gameSize.height; - } - - }, - - /** - * Is the device in a portrait orientation as reported by the Orientation API? - * This value is usually only available on mobile devices. - * - * @name Phaser.Scale.ScaleManager#isPortrait - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isPortrait: { - - get: function () - { - return (this.orientation === CONST.ORIENTATION.PORTRAIT); - } - - }, - - /** - * Is the device in a landscape orientation as reported by the Orientation API? - * This value is usually only available on mobile devices. - * - * @name Phaser.Scale.ScaleManager#isLandscape - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isLandscape: { - - get: function () - { - return (this.orientation === CONST.ORIENTATION.LANDSCAPE); - } - - }, - - /** - * Are the game dimensions portrait? (i.e. taller than they are wide) - * - * This is different to the device itself being in a portrait orientation. - * - * @name Phaser.Scale.ScaleManager#isGamePortrait - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isGamePortrait: { - - get: function () - { - return (this.height > this.width); - } - - }, - - /** - * Are the game dimensions landscape? (i.e. wider than they are tall) - * - * This is different to the device itself being in a landscape orientation. - * - * @name Phaser.Scale.ScaleManager#isGameLandscape - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isGameLandscape: { - - get: function () - { - return (this.width > this.height); - } - - } - -}); - -module.exports = ScaleManager; - - -/***/ }), -/* 394 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Clamp = __webpack_require__(17); -var Class = __webpack_require__(0); -var SnapFloor = __webpack_require__(76); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * The Size component allows you to set `width` and `height` properties and define the relationship between them. - * - * The component can automatically maintain the aspect ratios between the two values, and clamp them - * to a defined min-max range. You can also control the dominant axis. When dimensions are given to the Size component - * that would cause it to exceed its min-max range, the dimensions are adjusted based on the dominant axis. - * - * @class Size - * @memberof Phaser.Structs - * @constructor - * @since 3.16.0 - * - * @param {number} [width=0] - The width of the Size component. - * @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`. - * @param {number} [aspectMode=0] - The aspect mode of the Size component. Defaults to 0, no mode. - * @param {any} [parent=null] - The parent of this Size component. Can be any object with public `width` and `height` properties. Dimensions are clamped to keep them within the parent bounds where possible. - */ -var Size = new Class({ - - initialize: - - function Size (width, height, aspectMode, parent) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - if (aspectMode === undefined) { aspectMode = 0; } - if (parent === undefined) { parent = null; } - - /** - * Internal width value. - * - * @name Phaser.Structs.Size#_width - * @type {number} - * @private - * @since 3.16.0 - */ - this._width = width; - - /** - * Internal height value. - * - * @name Phaser.Structs.Size#_height - * @type {number} - * @private - * @since 3.16.0 - */ - this._height = height; - - /** - * Internal parent reference. - * - * @name Phaser.Structs.Size#_parent - * @type {any} - * @private - * @since 3.16.0 - */ - this._parent = parent; - - /** - * The aspect mode this Size component will use when calculating its dimensions. - * This property is read-only. To change it use the `setAspectMode` method. - * - * @name Phaser.Structs.Size#aspectMode - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.aspectMode = aspectMode; - - /** - * The proportional relationship between the width and height. - * - * This property is read-only and is updated automatically when either the `width` or `height` properties are changed, - * depending on the aspect mode. - * - * @name Phaser.Structs.Size#aspectRatio - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.aspectRatio = (height === 0) ? 1 : width / height; - - /** - * The minimum allowed width. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. - * - * @name Phaser.Structs.Size#minWidth - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.minWidth = 0; - - /** - * The minimum allowed height. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. - * - * @name Phaser.Structs.Size#minHeight - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.minHeight = 0; - - /** - * The maximum allowed width. - * This value is read-only. To change it see the `setMax` method. - * - * @name Phaser.Structs.Size#maxWidth - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.maxWidth = Number.MAX_VALUE; - - /** - * The maximum allowed height. - * This value is read-only. To change it see the `setMax` method. - * - * @name Phaser.Structs.Size#maxHeight - * @type {number} - * @readonly - * @since 3.16.0 - */ - this.maxHeight = Number.MAX_VALUE; - - /** - * A Vector2 containing the horizontal and vertical snap values, which the width and height are snapped to during resizing. - * - * By default this is disabled. - * - * This property is read-only. To change it see the `setSnap` method. - * - * @name Phaser.Structs.Size#snapTo - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.16.0 - */ - this.snapTo = new Vector2(); - }, - - /** - * Sets the aspect mode of this Size component. - * - * The aspect mode controls what happens when you modify the `width` or `height` properties, or call `setSize`. - * - * It can be a number from 0 to 4, or a Size constant: - * - * 0. NONE = Do not make the size fit the aspect ratio. Change the ratio when the size changes. - * 1. WIDTH_CONTROLS_HEIGHT = The height is automatically adjusted based on the width. - * 2. HEIGHT_CONTROLS_WIDTH = The width is automatically adjusted based on the height. - * 3. FIT = The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. - * 4. ENVELOP = The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. - * - * Calling this method automatically recalculates the `width` and the `height`, if required. - * - * @method Phaser.Structs.Size#setAspectMode - * @since 3.16.0 - * - * @param {number} [value=0] - The aspect mode value. - * - * @return {this} This Size component instance. - */ - setAspectMode: function (value) - { - if (value === undefined) { value = 0; } - - this.aspectMode = value; - - return this.setSize(this._width, this._height); - }, - - /** - * By setting a Snap To value when this Size component is modified its dimensions will automatically - * by snapped to the nearest grid slice, using floor. For example, if you have snap value of 16, - * and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored) - * - * Note that snapping takes place before adjustments by the parent, or the min / max settings. If these - * values are not multiples of the given snap values, then this can result in un-snapped dimensions. - * - * Call this method with no arguments to reset the snap values. - * - * Calling this method automatically recalculates the `width` and the `height`, if required. - * - * @method Phaser.Structs.Size#setSnap - * @since 3.16.0 - * - * @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero. - * @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero. - * - * @return {this} This Size component instance. - */ - setSnap: function (snapWidth, snapHeight) - { - if (snapWidth === undefined) { snapWidth = 0; } - if (snapHeight === undefined) { snapHeight = snapWidth; } - - this.snapTo.set(snapWidth, snapHeight); - - return this.setSize(this._width, this._height); - }, - - /** - * Sets, or clears, the parent of this Size component. - * - * To clear the parent call this method with no arguments. - * - * The parent influences the maximum extents to which this Size component can expand, - * based on the aspect mode: - * - * NONE - The parent clamps both the width and height. - * WIDTH_CONTROLS_HEIGHT - The parent clamps just the width. - * HEIGHT_CONTROLS_WIDTH - The parent clamps just the height. - * FIT - The parent clamps whichever axis is required to ensure the size fits within it. - * ENVELOP - The parent is used to ensure the size fully envelops the parent. - * - * Calling this method automatically calls `setSize`. - * - * @method Phaser.Structs.Size#setParent - * @since 3.16.0 - * - * @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent. - * - * @return {this} This Size component instance. - */ - setParent: function (parent) - { - this._parent = parent; - - return this.setSize(this._width, this._height); - }, - - /** - * Set the minimum width and height values this Size component will allow. - * - * The minimum values can never be below zero, or greater than the maximum values. - * - * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. - * - * Note that based on the aspect mode, and if this Size component has a parent set or not, the minimums set here - * _can_ be exceed in some situations. - * - * @method Phaser.Structs.Size#setMin - * @since 3.16.0 - * - * @param {number} [width=0] - The minimum allowed width of the Size component. - * @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setMin: function (width, height) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - - this.minWidth = Clamp(width, 0, this.maxWidth); - this.minHeight = Clamp(height, 0, this.maxHeight); - - return this.setSize(this._width, this._height); - }, - - /** - * Set the maximum width and height values this Size component will allow. - * - * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. - * - * Note that based on the aspect mode, and if this Size component has a parent set or not, the maximums set here - * _can_ be exceed in some situations. - * - * @method Phaser.Structs.Size#setMax - * @since 3.16.0 - * - * @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component. - * @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setMax: function (width, height) - { - if (width === undefined) { width = Number.MAX_VALUE; } - if (height === undefined) { height = width; } - - this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); - this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); - - return this.setSize(this._width, this._height); - }, - - /** - * Sets the width and height of this Size component based on the aspect mode. - * - * If the aspect mode is 'none' then calling this method will change the aspect ratio, otherwise the current - * aspect ratio is honored across all other modes. - * - * If snapTo values have been set then the given width and height are snapped first, prior to any further - * adjustment via min/max values, or a parent. - * - * If minimum and/or maximum dimensions have been specified, the values given to this method will be clamped into - * that range prior to adjustment, but may still exceed them depending on the aspect mode. - * - * If this Size component has a parent set, and the aspect mode is `fit` or `envelop`, then the given sizes will - * be clamped to the range specified by the parent. - * - * @method Phaser.Structs.Size#setSize - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - setSize: function (width, height) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - - switch (this.aspectMode) - { - case Size.NONE: - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; - break; - - case Size.WIDTH_CONTROLS_HEIGHT: - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(this._width * (1 / this.aspectRatio), false); - break; - - case Size.HEIGHT_CONTROLS_WIDTH: - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this._width = this.getNewWidth(this._height * this.aspectRatio, false); - break; - - case Size.FIT: - this.constrain(width, height, true); - break; - - case Size.ENVELOP: - this.constrain(width, height, false); - break; - } - - return this; - }, - - /** - * Sets a new aspect ratio, overriding what was there previously. - * - * It then calls `setSize` immediately using the current dimensions. - * - * @method Phaser.Structs.Size#setAspectRatio - * @since 3.16.0 - * - * @param {number} ratio - The new aspect ratio. - * - * @return {this} This Size component instance. - */ - setAspectRatio: function (ratio) - { - this.aspectRatio = ratio; - - return this.setSize(this._width, this._height); - }, - - /** - * Sets a new width and height for this Size component and updates the aspect ratio based on them. - * - * It _doesn't_ change the `aspectMode` and still factors in size limits such as the min max and parent bounds. - * - * @method Phaser.Structs.Size#resize - * @since 3.16.0 - * - * @param {number} width - The new width of the Size component. - * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. - * - * @return {this} This Size component instance. - */ - resize: function (width, height) - { - this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); - this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); - this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; - - return this; - }, - - /** - * Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width. - * - * @method Phaser.Structs.Size#getNewWidth - * @since 3.16.0 - * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. - * - * @return {number} The modified width value. - */ - getNewWidth: function (value, checkParent) - { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minWidth, this.maxWidth); - - if (checkParent && this._parent && value > this._parent.width) - { - value = Math.max(this.minWidth, this._parent.width); - } - - return value; - }, - - /** - * Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height. - * - * @method Phaser.Structs.Size#getNewHeight - * @since 3.16.0 - * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. - * - * @return {number} The modified height value. - */ - getNewHeight: function (value, checkParent) - { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minHeight, this.maxHeight); - - if (checkParent && this._parent && value > this._parent.height) - { - value = Math.max(this.minHeight, this._parent.height); - } - - return value; - }, - - /** - * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. - * - * If `fit` is true there may be some space inside the target area which is not covered if its aspect ratio differs. - * If `fit` is false the size may extend further out than the target area if the aspect ratios differ. - * - * If this Size component has a parent set, then the width and height passed to this method will be clamped so - * it cannot exceed that of the parent. - * - * @method Phaser.Structs.Size#constrain - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * @param {boolean} [fit=true] - Perform a `fit` (true) constraint, or an `envelop` (false) constraint. - * - * @return {this} This Size component instance. - */ - constrain: function (width, height, fit) - { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - if (fit === undefined) { fit = true; } - - width = this.getNewWidth(width); - height = this.getNewHeight(height); - - var snap = this.snapTo; - var newRatio = (height === 0) ? 1 : width / height; - - if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) - { - // We need to change the height to fit the width - - width = SnapFloor(width, snap.x); - - height = width / this.aspectRatio; - - if (snap.y > 0) - { - height = SnapFloor(height, snap.y); - - // Reduce the width accordingly - width = height * this.aspectRatio; - } - } - else if ((fit && this.aspectRatio < newRatio) || (!fit && this.aspectRatio > newRatio)) - { - // We need to change the width to fit the height - - height = SnapFloor(height, snap.y); - - width = height * this.aspectRatio; - - if (snap.x > 0) - { - width = SnapFloor(width, snap.x); - - // Reduce the height accordingly - height = width * (1 / this.aspectRatio); - } - } - - this._width = width; - this._height = height; - - return this; - }, - - /** - * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. - * - * There may be some space inside the target area which is not covered if its aspect ratio differs. - * - * If this Size component has a parent set, then the width and height passed to this method will be clamped so - * it cannot exceed that of the parent. - * - * @method Phaser.Structs.Size#fitTo - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * - * @return {this} This Size component instance. - */ - fitTo: function (width, height) - { - return this.constrain(width, height, true); - }, - - /** - * The current `width` and `height` are adjusted so that they fully envelope the given dimensions, while keeping the aspect ratio. - * - * The size may extend further out than the target area if the aspect ratios differ. - * - * If this Size component has a parent set, then the values are clamped so that it never exceeds the parent - * on the longest axis. - * - * @method Phaser.Structs.Size#envelop - * @since 3.16.0 - * - * @param {number} [width=0] - The new width of the Size component. - * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. - * - * @return {this} This Size component instance. - */ - envelop: function (width, height) - { - return this.constrain(width, height, false); - }, - - /** - * Sets the width of this Size component. - * - * Depending on the aspect mode, changing the width may also update the height and aspect ratio. - * - * @method Phaser.Structs.Size#setWidth - * @since 3.16.0 - * - * @param {number} width - The new width of the Size component. - * - * @return {this} This Size component instance. - */ - setWidth: function (value) - { - return this.setSize(value, this._height); - }, - - /** - * Sets the height of this Size component. - * - * Depending on the aspect mode, changing the height may also update the width and aspect ratio. - * - * @method Phaser.Structs.Size#setHeight - * @since 3.16.0 - * - * @param {number} height - The new height of the Size component. - * - * @return {this} This Size component instance. - */ - setHeight: function (value) - { - return this.setSize(this._width, value); - }, - - /** - * Returns a string representation of this Size component. - * - * @method Phaser.Structs.Size#toString - * @since 3.16.0 - * - * @return {string} A string representation of this Size component. - */ - toString: function () - { - return '[{ Size (width=' + this._width + ' height=' + this._height + ' aspectRatio=' + this.aspectRatio + ' aspectMode=' + this.aspectMode + ') }]'; - }, - - /** - * Sets the values of this Size component to the `element.style.width` and `height` - * properties of the given DOM Element. The properties are set as `px` values. - * - * @method Phaser.Structs.Size#setCSS - * @since 3.17.0 - * - * @param {HTMLElement} element - The DOM Element to set the CSS style on. - */ - setCSS: function (element) - { - if (element && element.style) - { - element.style.width = this._width + 'px'; - element.style.height = this._height + 'px'; - } - }, - - /** - * Copies the aspect mode, aspect ratio, width and height from this Size component - * to the given Size component. Note that the parent, if set, is not copied across. - * - * @method Phaser.Structs.Size#copy - * @since 3.16.0 - * - * @param {Phaser.Structs.Size} destination - The Size component to copy the values to. - * - * @return {Phaser.Structs.Size} The updated destination Size component. - */ - copy: function (destination) - { - destination.setAspectMode(this.aspectMode); - - destination.aspectRatio = this.aspectRatio; - - return destination.setSize(this.width, this.height); - }, - - /** - * Destroys this Size component. - * - * This clears the local properties and any parent object, if set. - * - * A destroyed Size component cannot be re-used. - * - * @method Phaser.Structs.Size#destroy - * @since 3.16.0 - */ - destroy: function () - { - this._parent = null; - this.snapTo = null; - }, - - /** - * The width of this Size component. - * - * This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled. - * - * A width can never be less than zero. - * - * Changing this value will automatically update the `height` if the aspect ratio lock is enabled. - * You can also use the `setWidth` and `getWidth` methods. - * - * @name Phaser.Structs.Size#width - * @type {number} - * @since 3.16.0 - */ - width: { - - get: function () - { - return this._width; - }, - - set: function (value) - { - this.setSize(value, this._height); - } - - }, - - /** - * The height of this Size component. - * - * This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled. - * - * A height can never be less than zero. - * - * Changing this value will automatically update the `width` if the aspect ratio lock is enabled. - * You can also use the `setHeight` and `getHeight` methods. - * - * @name Phaser.Structs.Size#height - * @type {number} - * @since 3.16.0 - */ - height: { - - get: function () - { - return this._height; - }, - - set: function (value) - { - this.setSize(this._width, value); - } - - } - -}); - -/** - * Do not make the size fit the aspect ratio. Change the ratio when the size changes. - * - * @name Phaser.Structs.Size.NONE - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.NONE = 0; - -/** - * The height is automatically adjusted based on the width. - * - * @name Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.WIDTH_CONTROLS_HEIGHT = 1; - -/** - * The width is automatically adjusted based on the height. - * - * @name Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.HEIGHT_CONTROLS_WIDTH = 2; - -/** - * The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. - * - * @name Phaser.Structs.Size.FIT - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.FIT = 3; - -/** - * The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. - * - * @name Phaser.Structs.Size.ENVELOP - * @constant - * @type {number} - * @since 3.16.0 - */ -Size.ENVELOP = 4; - -module.exports = Size; - - -/***/ }), -/* 395 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(141); -var Events = __webpack_require__(21); -var GameEvents = __webpack_require__(22); -var GetValue = __webpack_require__(6); -var LoaderEvents = __webpack_require__(90); -var NOOP = __webpack_require__(1); -var Scene = __webpack_require__(396); -var Systems = __webpack_require__(199); - -/** - * @classdesc - * The Scene Manager. - * - * The Scene Manager is a Game level system, responsible for creating, processing and updating all of the - * Scenes in a Game instance. -ó * - * - * @class SceneManager - * @memberof Phaser.Scenes - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance this Scene Manager belongs to. - * @param {object} sceneConfig - Scene specific configuration settings. - */ -var SceneManager = new Class({ - - initialize: - - function SceneManager (game, sceneConfig) - { - /** - * The Game that this SceneManager belongs to. - * - * @name Phaser.Scenes.SceneManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * An object that maps the keys to the scene so we can quickly get a scene from a key without iteration. - * - * @name Phaser.Scenes.SceneManager#keys - * @type {object} - * @since 3.0.0 - */ - this.keys = {}; - - /** - * The array in which all of the scenes are kept. - * - * @name Phaser.Scenes.SceneManager#scenes - * @type {array} - * @since 3.0.0 - */ - this.scenes = []; - - /** - * Scenes pending to be added are stored in here until the manager has time to add it. - * - * @name Phaser.Scenes.SceneManager#_pending - * @type {array} - * @private - * @since 3.0.0 - */ - this._pending = []; - - /** - * An array of scenes waiting to be started once the game has booted. - * - * @name Phaser.Scenes.SceneManager#_start - * @type {array} - * @private - * @since 3.0.0 - */ - this._start = []; - - /** - * An operations queue, because we don't manipulate the scenes array during processing. - * - * @name Phaser.Scenes.SceneManager#_queue - * @type {array} - * @private - * @since 3.0.0 - */ - this._queue = []; - - /** - * Boot time data to merge. - * - * @name Phaser.Scenes.SceneManager#_data - * @type {object} - * @private - * @since 3.4.0 - */ - this._data = {}; - - /** - * Is the Scene Manager actively processing the Scenes list? - * - * @name Phaser.Scenes.SceneManager#isProcessing - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.isProcessing = false; - - /** - * Has the Scene Manager properly started? - * - * @name Phaser.Scenes.SceneManager#isBooted - * @type {boolean} - * @default false - * @readonly - * @since 3.4.0 - */ - this.isBooted = false; - - /** - * Do any of the Cameras in any of the Scenes require a custom viewport? - * If not we can skip scissor tests. - * - * @name Phaser.Scenes.SceneManager#customViewports - * @type {number} - * @default 0 - * @since 3.12.0 - */ - this.customViewports = 0; - - if (sceneConfig) - { - if (!Array.isArray(sceneConfig)) - { - sceneConfig = [ sceneConfig ]; - } - - for (var i = 0; i < sceneConfig.length; i++) - { - // The i === 0 part just autostarts the first Scene given (unless it says otherwise in its config) - this._pending.push({ - key: 'default', - scene: sceneConfig[i], - autoStart: (i === 0), - data: {} - }); - } - } - - game.events.once(GameEvents.READY, this.bootQueue, this); - }, - - /** - * Internal first-time Scene boot handler. - * - * @method Phaser.Scenes.SceneManager#bootQueue - * @private - * @since 3.2.0 - */ - bootQueue: function () - { - if (this.isBooted) - { - return; - } - - var i; - var entry; - var key; - var sceneConfig; - - for (i = 0; i < this._pending.length; i++) - { - entry = this._pending[i]; - - key = entry.key; - sceneConfig = entry.scene; - - var newScene; - - if (sceneConfig instanceof Scene) - { - newScene = this.createSceneFromInstance(key, sceneConfig); - } - else if (typeof sceneConfig === 'object') - { - newScene = this.createSceneFromObject(key, sceneConfig); - } - else if (typeof sceneConfig === 'function') - { - newScene = this.createSceneFromFunction(key, sceneConfig); - } - - // Replace key in case the scene changed it - key = newScene.sys.settings.key; - - this.keys[key] = newScene; - - this.scenes.push(newScene); - - // Any data to inject? - if (this._data[key]) - { - newScene.sys.settings.data = this._data[key].data; - - if (this._data[key].autoStart) - { - entry.autoStart = true; - } - } - - if (entry.autoStart || newScene.sys.settings.active) - { - this._start.push(key); - } - } - - // Clear the pending lists - this._pending.length = 0; - - this._data = {}; - - this.isBooted = true; - - // _start might have been populated by the above - for (i = 0; i < this._start.length; i++) - { - entry = this._start[i]; - - this.start(entry); - } - - this._start.length = 0; - }, - - /** - * Process the Scene operations queue. - * - * @method Phaser.Scenes.SceneManager#processQueue - * @since 3.0.0 - */ - processQueue: function () - { - var pendingLength = this._pending.length; - var queueLength = this._queue.length; - - if (pendingLength === 0 && queueLength === 0) - { - return; - } - - var i; - var entry; - - if (pendingLength) - { - for (i = 0; i < pendingLength; i++) - { - entry = this._pending[i]; - - this.add(entry.key, entry.scene, entry.autoStart, entry.data); - } - - // _start might have been populated by this.add - for (i = 0; i < this._start.length; i++) - { - entry = this._start[i]; - - this.start(entry); - } - - // Clear the pending lists - this._start.length = 0; - this._pending.length = 0; - - return; - } - - for (i = 0; i < this._queue.length; i++) - { - entry = this._queue[i]; - - this[entry.op](entry.keyA, entry.keyB); - } - - this._queue.length = 0; - }, - - /** - * Adds a new Scene into the SceneManager. - * You must give each Scene a unique key by which you'll identify it. - * - * The `sceneConfig` can be: - * - * * A `Phaser.Scene` object, or an object that extends it. - * * A plain JavaScript object - * * A JavaScript ES6 Class that extends `Phaser.Scene` - * * A JavaScript ES5 prototype based Class - * * A JavaScript function - * - * If a function is given then a new Scene will be created by calling it. - * - * @method Phaser.Scenes.SceneManager#add - * @since 3.0.0 - * - * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. - * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig|function)} sceneConfig - The config for the Scene - * @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added. - * @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. - * - * @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`. - */ - add: function (key, sceneConfig, autoStart, data) - { - if (autoStart === undefined) { autoStart = false; } - if (data === undefined) { data = {}; } - - // If processing or not booted then put scene into a holding pattern - if (this.isProcessing || !this.isBooted) - { - this._pending.push({ - key: key, - scene: sceneConfig, - autoStart: autoStart, - data: data - }); - - if (!this.isBooted) - { - this._data[key] = { data: data }; - } - - return null; - } - - key = this.getKey(key, sceneConfig); - - var newScene; - - if (sceneConfig instanceof Scene) - { - newScene = this.createSceneFromInstance(key, sceneConfig); - } - else if (typeof sceneConfig === 'object') - { - sceneConfig.key = key; - - newScene = this.createSceneFromObject(key, sceneConfig); - } - else if (typeof sceneConfig === 'function') - { - newScene = this.createSceneFromFunction(key, sceneConfig); - } - - // Any data to inject? - newScene.sys.settings.data = data; - - // Replace key in case the scene changed it - key = newScene.sys.settings.key; - - this.keys[key] = newScene; - - this.scenes.push(newScene); - - if (autoStart || newScene.sys.settings.active) - { - if (this._pending.length) - { - this._start.push(key); - } - else - { - this.start(key); - } - } - - return newScene; - }, - - /** - * Removes a Scene from the SceneManager. - * - * The Scene is removed from the local scenes array, it's key is cleared from the keys - * cache and Scene.Systems.destroy is then called on it. - * - * If the SceneManager is processing the Scenes when this method is called it will - * queue the operation for the next update sequence. - * - * @method Phaser.Scenes.SceneManager#remove - * @since 3.2.0 - * - * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - remove: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'remove', keyA: key, keyB: null }); - } - else - { - var sceneToRemove = this.getScene(key); - - if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) - { - return this; - } - - var index = this.scenes.indexOf(sceneToRemove); - var sceneKey = sceneToRemove.sys.settings.key; - - if (index > -1) - { - delete this.keys[sceneKey]; - this.scenes.splice(index, 1); - - if (this._start.indexOf(sceneKey) > -1) - { - index = this._start.indexOf(sceneKey); - this._start.splice(index, 1); - } - - sceneToRemove.sys.destroy(); - } - } - - return this; - }, - - /** - * Boot the given Scene. - * - * @method Phaser.Scenes.SceneManager#bootScene - * @private - * @fires Phaser.Scenes.Events#TRANSITION_INIT - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to boot. - */ - bootScene: function (scene) - { - var sys = scene.sys; - var settings = sys.settings; - - sys.sceneUpdate = NOOP; - - if (scene.init) - { - scene.init.call(scene, settings.data); - - settings.status = CONST.INIT; - - if (settings.isTransition) - { - sys.events.emit(Events.TRANSITION_INIT, settings.transitionFrom, settings.transitionDuration); - } - } - - var loader; - - if (sys.load) - { - loader = sys.load; - - loader.reset(); - } - - if (loader && scene.preload) - { - scene.preload.call(scene); - - // Is the loader empty? - if (loader.list.size === 0) - { - this.create(scene); - } - else - { - settings.status = CONST.LOADING; - - // Start the loader going as we have something in the queue - loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); - - loader.start(); - } - } - else - { - // No preload? Then there was nothing to load either - this.create(scene); - } - }, - - /** - * Handles load completion for a Scene's Loader. - * - * Starts the Scene that the Loader belongs to. - * - * @method Phaser.Scenes.SceneManager#loadComplete - * @private - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading. - */ - loadComplete: function (loader) - { - var scene = loader.scene; - - // TODO - Remove. This should *not* be handled here - // Try to unlock HTML5 sounds every time any loader completes - if (this.game.sound && this.game.sound.onBlurPausedSounds) - { - this.game.sound.unlock(); - } - - this.create(scene); - }, - - /** - * Handle payload completion for a Scene. - * - * @method Phaser.Scenes.SceneManager#payloadComplete - * @private - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading its Scene's payload. - */ - payloadComplete: function (loader) - { - this.bootScene(loader.scene); - }, - - /** - * Updates the Scenes. - * - * @method Phaser.Scenes.SceneManager#update - * @since 3.0.0 - * - * @param {number} time - Time elapsed. - * @param {number} delta - Delta time from the last update. - */ - update: function (time, delta) - { - this.processQueue(); - - this.isProcessing = true; - - // Loop through the active scenes in reverse order - for (var i = this.scenes.length - 1; i >= 0; i--) - { - var sys = this.scenes[i].sys; - - if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) - { - sys.step(time, delta); - } - } - }, - - /** - * Renders the Scenes. - * - * @method Phaser.Scenes.SceneManager#render - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer to use. - */ - render: function (renderer) - { - // Loop through the scenes in forward order - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) - { - sys.render(renderer); - } - } - - this.isProcessing = false; - }, - - /** - * Calls the given Scene's {@link Phaser.Scene#create} method and updates its status. - * - * @method Phaser.Scenes.SceneManager#create - * @private - * @fires Phaser.Scenes.Events#CREATE - * @fires Phaser.Scenes.Events#TRANSITION_INIT - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to create. - */ - create: function (scene) - { - var sys = scene.sys; - var settings = sys.settings; - - if (scene.create) - { - settings.status = CONST.CREATING; - - scene.create.call(scene, settings.data); - - if (settings.status === CONST.DESTROYED) - { - return; - } - } - - if (settings.isTransition) - { - sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration); - } - - // If the Scene has an update function we'll set it now, otherwise it'll remain as NOOP - if (scene.update) - { - sys.sceneUpdate = scene.update; - } - - settings.status = CONST.RUNNING; - - sys.events.emit(Events.CREATE, scene); - }, - - /** - * Creates and initializes a Scene from a function. - * - * @method Phaser.Scenes.SceneManager#createSceneFromFunction - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {function} scene - The function to create the Scene from. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromFunction: function (key, scene) - { - var newScene = new scene(); - - if (newScene instanceof Scene) - { - var configKey = newScene.sys.settings.key; - - if (configKey !== '') - { - key = configKey; - } - - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } - - return this.createSceneFromInstance(key, newScene); - } - else - { - newScene.sys = new Systems(newScene); - - newScene.sys.settings.key = key; - - newScene.sys.init(this.game); - - return newScene; - } - }, - - /** - * Creates and initializes a Scene instance. - * - * @method Phaser.Scenes.SceneManager#createSceneFromInstance - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {Phaser.Scene} newScene - The Scene instance. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromInstance: function (key, newScene) - { - var configKey = newScene.sys.settings.key; - - if (configKey === '') - { - newScene.sys.settings.key = key; - } - - newScene.sys.init(this.game); - - return newScene; - }, - - /** - * Creates and initializes a Scene from an Object definition. - * - * @method Phaser.Scenes.SceneManager#createSceneFromObject - * @private - * @since 3.0.0 - * - * @param {string} key - The key of the Scene. - * @param {(string|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig)} sceneConfig - The Scene config. - * - * @return {Phaser.Scene} The created Scene. - */ - createSceneFromObject: function (key, sceneConfig) - { - var newScene = new Scene(sceneConfig); - - var configKey = newScene.sys.settings.key; - - if (configKey !== '') - { - key = configKey; - } - else - { - newScene.sys.settings.key = key; - } - - newScene.sys.init(this.game); - - // Extract callbacks - - var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; - - for (var i = 0; i < defaults.length; i++) - { - var sceneCallback = GetValue(sceneConfig, defaults[i], null); - - if (sceneCallback) - { - newScene[defaults[i]] = sceneCallback; - } - } - - // Now let's move across any other functions or properties that may exist in the extend object: - - /* - scene: { - preload: preload, - create: create, - extend: { - hello: 1, - test: 'atari', - addImage: addImage - } - } - */ - - if (sceneConfig.hasOwnProperty('extend')) - { - for (var propertyKey in sceneConfig.extend) - { - if (!sceneConfig.extend.hasOwnProperty(propertyKey)) - { - continue; - } - - var value = sceneConfig.extend[propertyKey]; - - if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') - { - // Populate the DataManager - newScene.data.merge(value); - } - else if (propertyKey !== 'sys') - { - newScene[propertyKey] = value; - } - } - } - - return newScene; - }, - - /** - * Retrieves the key of a Scene from a Scene config. - * - * @method Phaser.Scenes.SceneManager#getKey - * @private - * @since 3.0.0 - * - * @param {string} key - The key to check in the Scene config. - * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|function)} sceneConfig - The Scene config. - * - * @return {string} The Scene key. - */ - getKey: function (key, sceneConfig) - { - if (!key) { key = 'default'; } - - if (typeof sceneConfig === 'function') - { - return key; - } - else if (sceneConfig instanceof Scene) - { - key = sceneConfig.sys.settings.key; - } - else if (typeof sceneConfig === 'object' && sceneConfig.hasOwnProperty('key')) - { - key = sceneConfig.key; - } - - // By this point it's either 'default' or extracted from the Scene - - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } - else - { - return key; - } - }, - - /** - * Returns an array of all the current Scenes being managed by this Scene Manager. - * - * You can filter the output by the active state of the Scene and choose to have - * the array returned in normal or reversed order. - * - * @method Phaser.Scenes.SceneManager#getScenes - * @since 3.16.0 - * - * @param {boolean} [isActive=true] - Only include Scene's that are currently active? - * @param {boolean} [inReverse=false] - Return the array of Scenes in reverse? - * - * @return {Phaser.Scene[]} An array containing all of the Scenes in the Scene Manager. - */ - getScenes: function (isActive, inReverse) - { - if (isActive === undefined) { isActive = true; } - if (inReverse === undefined) { inReverse = false; } - - var out = []; - var scenes = this.scenes; - - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; - - if (scene && (!isActive || (isActive && scene.sys.isActive()))) - { - out.push(scene); - } - } - - return (inReverse) ? out.reverse() : out; - }, - - /** - * Retrieves a Scene. - * - * @method Phaser.Scenes.SceneManager#getScene - * @since 3.0.0 - * - * @param {string|Phaser.Scene} key - The Scene to retrieve. - * - * @return {?Phaser.Scene} The Scene. - */ - getScene: function (key) - { - if (typeof key === 'string') - { - if (this.keys[key]) - { - return this.keys[key]; - } - } - else - { - for (var i = 0; i < this.scenes.length; i++) - { - if (key === this.scenes[i]) - { - return key; - } - } - } - - return null; - }, - - /** - * Determines whether a Scene is running. - * - * @method Phaser.Scenes.SceneManager#isActive - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is running. - */ - isActive: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isActive(); - } - - return null; - }, - - /** - * Determines whether a Scene is paused. - * - * @method Phaser.Scenes.SceneManager#isPaused - * @since 3.17.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is paused. - */ - isPaused: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isPaused(); - } - - return null; - }, - - /** - * Determines whether a Scene is visible. - * - * @method Phaser.Scenes.SceneManager#isVisible - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is visible. - */ - isVisible: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isVisible(); - } - - return null; - }, - - /** - * Determines whether a Scene is sleeping. - * - * @method Phaser.Scenes.SceneManager#isSleeping - * @since 3.0.0 - * - * @param {string} key - The Scene to check. - * - * @return {boolean} Whether the Scene is sleeping. - */ - isSleeping: function (key) - { - var scene = this.getScene(key); - - if (scene) - { - return scene.sys.isSleeping(); - } - - return null; - }, - - /** - * Pauses the given Scene. - * - * @method Phaser.Scenes.SceneManager#pause - * @since 3.0.0 - * - * @param {string} key - The Scene to pause. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its pause event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - pause: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.pause(data); - } - - return this; - }, - - /** - * Resumes the given Scene. - * - * @method Phaser.Scenes.SceneManager#resume - * @since 3.0.0 - * - * @param {string} key - The Scene to resume. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its resume event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - resume: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.resume(data); - } - - return this; - }, - - /** - * Puts the given Scene to sleep. - * - * @method Phaser.Scenes.SceneManager#sleep - * @since 3.0.0 - * - * @param {string} key - The Scene to put to sleep. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its sleep event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - sleep: function (key, data) - { - var scene = this.getScene(key); - - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.sleep(data); - } - - return this; - }, - - /** - * Awakens the given Scene. - * - * @method Phaser.Scenes.SceneManager#wake - * @since 3.0.0 - * - * @param {string} key - The Scene to wake up. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its wake event. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - wake: function (key, data) - { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.wake(data); - } - - return this; - }, - - /** - * Runs the given Scene. - * - * If the given Scene is paused, it will resume it. If sleeping, it will wake it. - * If not running at all, it will be started. - * - * Use this if you wish to open a modal Scene by calling `pause` on the current - * Scene, then `run` on the modal Scene. - * - * @method Phaser.Scenes.SceneManager#run - * @since 3.10.0 - * - * @param {string} key - The Scene to run. - * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. - * - * @return {Phaser.Scenes.SceneManager} This Scene Manager. - */ - run: function (key, data) - { - var scene = this.getScene(key); - - if (!scene) - { - for (var i = 0; i < this._pending.length; i++) - { - if (this._pending[i].key === key) - { - this.queueOp('start', key, data); - break; - } - } - return this; - } - - if (scene.sys.isSleeping()) - { - // Sleeping? - scene.sys.wake(data); - } - else if (scene.sys.isPaused()) - { - // Paused? - scene.sys.resume(data); - } - else - { - // Not actually running? - this.start(key, data); - } - }, - - /** - * Starts the given Scene. - * - * @method Phaser.Scenes.SceneManager#start - * @since 3.0.0 - * - * @param {string} key - The Scene to start. - * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - start: function (key, data) - { - // If the Scene Manager is not running, then put the Scene into a holding pattern - if (!this.isBooted) - { - this._data[key] = { - autoStart: true, - data: data - }; - - return this; - } - - var scene = this.getScene(key); - - if (scene) - { - var sys = scene.sys; - - // If the Scene is already running (perhaps they called start from a launched sub-Scene?) - // then we close it down before starting it again. - if (sys.isActive() || sys.isPaused()) - { - sys.shutdown(); - - sys.sceneUpdate = NOOP; - - sys.start(data); - } - else - { - sys.sceneUpdate = NOOP; - - sys.start(data); - - var loader; - - if (sys.load) - { - loader = sys.load; - } - - // Files payload? - if (loader && sys.settings.hasOwnProperty('pack')) - { - loader.reset(); - - if (loader.addPack({ payload: sys.settings.pack })) - { - sys.settings.status = CONST.LOADING; - - loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); - - loader.start(); - - return this; - } - } - } - - this.bootScene(scene); - } - - return this; - }, - - /** - * Stops the given Scene. - * - * @method Phaser.Scenes.SceneManager#stop - * @since 3.0.0 - * - * @param {string} key - The Scene to stop. - * @param {object} [data] - Optional data object to pass to Scene.shutdown. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - stop: function (key, data) - { - var scene = this.getScene(key); - - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.shutdown(data); - } - - return this; - }, - - /** - * Sleeps one one Scene and starts the other. - * - * @method Phaser.Scenes.SceneManager#switch - * @since 3.0.0 - * - * @param {string} from - The Scene to sleep. - * @param {string} to - The Scene to start. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - switch: function (from, to) - { - var sceneA = this.getScene(from); - var sceneB = this.getScene(to); - - if (sceneA && sceneB && sceneA !== sceneB) - { - this.sleep(from); - - if (this.isSleeping(to)) - { - this.wake(to); - } - else - { - this.start(to); - } - } - - return this; - }, - - /** - * Retrieves a Scene by numeric index. - * - * @method Phaser.Scenes.SceneManager#getAt - * @since 3.0.0 - * - * @param {number} index - The index of the Scene to retrieve. - * - * @return {(Phaser.Scene|undefined)} The Scene. - */ - getAt: function (index) - { - return this.scenes[index]; - }, - - /** - * Retrieves the numeric index of a Scene. - * - * @method Phaser.Scenes.SceneManager#getIndex - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The key of the Scene. - * - * @return {number} The index of the Scene. - */ - getIndex: function (key) - { - var scene = this.getScene(key); - - return this.scenes.indexOf(scene); - }, - - /** - * Brings a Scene to the top of the Scenes list. - * - * This means it will render above all other Scenes. - * - * @method Phaser.Scenes.SceneManager#bringToTop - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - bringToTop: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'bringToTop', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); - - if (index !== -1 && index < this.scenes.length) - { - var scene = this.getScene(key); - - this.scenes.splice(index, 1); - this.scenes.push(scene); - } - } - - return this; - }, - - /** - * Sends a Scene to the back of the Scenes list. - * - * This means it will render below all other Scenes. - * - * @method Phaser.Scenes.SceneManager#sendToBack - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - sendToBack: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); - - if (index !== -1 && index > 0) - { - var scene = this.getScene(key); - - this.scenes.splice(index, 1); - this.scenes.unshift(scene); - } - } - - return this; - }, - - /** - * Moves a Scene down one position in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#moveDown - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveDown: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'moveDown', keyA: key, keyB: null }); - } - else - { - var indexA = this.getIndex(key); - - if (indexA > 0) - { - var indexB = indexA - 1; - var sceneA = this.getScene(key); - var sceneB = this.getAt(indexB); - - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } - - return this; - }, - - /** - * Moves a Scene up one position in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#moveUp - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to move. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveUp: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); - } - else - { - var indexA = this.getIndex(key); - - if (indexA < this.scenes.length - 1) - { - var indexB = indexA + 1; - var sceneA = this.getScene(key); - var sceneB = this.getAt(indexB); - - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } - - return this; - }, - - /** - * Moves a Scene so it is immediately above another Scene in the Scenes list. - * - * This means it will render over the top of the other Scene. - * - * @method Phaser.Scenes.SceneManager#moveAbove - * @since 3.2.0 - * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. - * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveAbove: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); - - // Remove - this.scenes.splice(indexB, 1); - - // Add in new location - this.scenes.splice(indexA + 1, 0, tempScene); - } - } - - return this; - }, - - /** - * Moves a Scene so it is immediately below another Scene in the Scenes list. - * - * This means it will render behind the other Scene. - * - * @method Phaser.Scenes.SceneManager#moveBelow - * @since 3.2.0 - * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. - * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - moveBelow: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'moveBelow', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); - - // Remove - this.scenes.splice(indexB, 1); - - if (indexA === 0) - { - this.scenes.unshift(tempScene); - } - else - { - // Add in new location - this.scenes.splice(indexA, 0, tempScene); - } - } - } - - return this; - }, - - /** - * Queue a Scene operation for the next update. - * - * @method Phaser.Scenes.SceneManager#queueOp - * @private - * @since 3.0.0 - * - * @param {string} op - The operation to perform. - * @param {(string|Phaser.Scene)} keyA - Scene A. - * @param {(any|string|Phaser.Scene)} [keyB] - Scene B, or a data object. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - queueOp: function (op, keyA, keyB) - { - this._queue.push({ op: op, keyA: keyA, keyB: keyB }); - - return this; - }, - - /** - * Swaps the positions of two Scenes in the Scenes list. - * - * @method Phaser.Scenes.SceneManager#swapPosition - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. - * @param {(string|Phaser.Scene)} keyB - The second Scene to swap. - * - * @return {Phaser.Scenes.SceneManager} This SceneManager. - */ - swapPosition: function (keyA, keyB) - { - if (keyA === keyB) - { - return this; - } - - if (this.isProcessing) - { - this._queue.push({ op: 'swapPosition', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); - - if (indexA !== indexB && indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexA); - - this.scenes[indexA] = this.scenes[indexB]; - this.scenes[indexB] = tempScene; - } - } - - return this; - }, - - /** - * Dumps debug information about each Scene to the developer console. - * - * @method Phaser.Scenes.SceneManager#dump - * @since 3.2.0 - */ - dump: function () - { - var out = []; - var map = [ 'pending', 'init', 'start', 'loading', 'creating', 'running', 'paused', 'sleeping', 'shutdown', 'destroyed' ]; - - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - var key = (sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED)) ? '[*] ' : '[-] '; - key += sys.settings.key + ' (' + map[sys.settings.status] + ')'; - - out.push(key); - } - - console.log(out.join('\n')); - }, - - /** - * Destroy the SceneManager and all of its Scene's systems. - * - * @method Phaser.Scenes.SceneManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var i = 0; i < this.scenes.length; i++) - { - var sys = this.scenes[i].sys; - - sys.destroy(); - } - - this.update = NOOP; - - this.scenes = []; - - this._pending = []; - this._start = []; - this._queue = []; - - this.game = null; - } - -}); - -module.exports = SceneManager; - - -/***/ }), -/* 396 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Systems = __webpack_require__(199); - -/** - * @classdesc - * A base Phaser.Scene class which can be extended for your own use. - * - * You can also define the optional methods {@link Phaser.Types.Scenes.SceneInitCallback init()}, {@link Phaser.Types.Scenes.ScenePreloadCallback preload()}, and {@link Phaser.Types.Scenes.SceneCreateCallback create()}. - * - * @class Scene - * @memberof Phaser - * @constructor - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. - */ -var Scene = new Class({ - - initialize: - - function Scene (config) - { - /** - * The Scene Systems. You must never overwrite this property, or all hell will break lose. - * - * @name Phaser.Scene#sys - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.sys = new Systems(this, config); - - /** - * A reference to the Phaser.Game instance. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game; - - /** - * A reference to the global Animation Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#anims - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 - */ - this.anims; - - /** - * A reference to the global Cache. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#cache - * @type {Phaser.Cache.CacheManager} - * @since 3.0.0 - */ - this.cache; - - /** - * A reference to the game level Data Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#registry - * @type {Phaser.Data.DataManager} - * @since 3.0.0 - */ - this.registry; - - /** - * A reference to the Sound Manager. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#sound - * @type {Phaser.Sound.BaseSoundManager} - * @since 3.0.0 - */ - this.sound; - - /** - * A reference to the Texture Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#textures - * @type {Phaser.Textures.TextureManager} - * @since 3.0.0 - */ - this.textures; - - /** - * A scene level Event Emitter. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events; - - /** - * A scene level Camera System. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#cameras - * @type {Phaser.Cameras.Scene2D.CameraManager} - * @since 3.0.0 - */ - this.cameras; - - /** - * A scene level Game Object Factory. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#add - * @type {Phaser.GameObjects.GameObjectFactory} - * @since 3.0.0 - */ - this.add; - - /** - * A scene level Game Object Creator. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#make - * @type {Phaser.GameObjects.GameObjectCreator} - * @since 3.0.0 - */ - this.make; - - /** - * A reference to the Scene Manager Plugin. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#scene - * @type {Phaser.Scenes.ScenePlugin} - * @since 3.0.0 - */ - this.scene; - - /** - * A scene level Game Object Display List. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#children - * @type {Phaser.GameObjects.DisplayList} - * @since 3.0.0 - */ - this.children; - - /** - * A scene level Lights Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#lights - * @type {Phaser.GameObjects.LightsManager} - * @since 3.0.0 - */ - this.lights; - - /** - * A scene level Data Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#data - * @type {Phaser.Data.DataManager} - * @since 3.0.0 - */ - this.data; - - /** - * A scene level Input Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#input - * @type {Phaser.Input.InputPlugin} - * @since 3.0.0 - */ - this.input; - - /** - * A scene level Loader Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#load - * @type {Phaser.Loader.LoaderPlugin} - * @since 3.0.0 - */ - this.load; - - /** - * A scene level Time and Clock Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#time - * @type {Phaser.Time.Clock} - * @since 3.0.0 - */ - this.time; - - /** - * A scene level Tween Manager Plugin. - * This property will only be available if defined in the Scene Injection Map and the plugin is installed. - * - * @name Phaser.Scene#tweens - * @type {Phaser.Tweens.TweenManager} - * @since 3.0.0 - */ - this.tweens; - - /** - * A scene level Arcade Physics Plugin. - * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. - * - * @name Phaser.Scene#physics - * @type {Phaser.Physics.Arcade.ArcadePhysics} - * @since 3.0.0 - */ - this.physics; - - /** - * A scene level Matter Physics Plugin. - * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. - * - * @name Phaser.Scene#matter - * @type {Phaser.Physics.Matter.MatterPhysics} - * @since 3.0.0 - */ - this.matter; - - if (false) - {} - - /** - * A reference to the global Scale Manager. - * This property will only be available if defined in the Scene Injection Map. - * - * @name Phaser.Scene#scale - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.2 - */ - this.scale; - - /** - * A reference to the Plugin Manager. - * - * The Plugin Manager is a global system that allows plugins to register themselves with it, and can then install - * those plugins into Scenes as required. - * - * @name Phaser.Scene#plugins - * @type {Phaser.Plugins.PluginManager} - * @since 3.0.0 - */ - this.plugins; - - /** - * A reference to the renderer instance Phaser is using, either Canvas or WebGL. - * - * @name Phaser.Scene#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.50.0 - */ - this.renderer; - }, - - /** - * Should be overridden by your own Scenes. - * This method is called once per game step while the scene is running. - * - * @method Phaser.Scene#update - * @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. - */ - update: function () - { - } - -}); - -module.exports = Scene; - - -/***/ }), -/* 397 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var UppercaseFirst = __webpack_require__(200); - -/** - * Builds an array of which physics plugins should be activated for the given Scene. - * - * @function Phaser.Scenes.GetPhysicsPlugins - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - The scene system to get the physics systems of. - * - * @return {array} An array of Physics systems to start for this Scene. - */ -var GetPhysicsPlugins = function (sys) -{ - var defaultSystem = sys.game.config.defaultPhysicsSystem; - var sceneSystems = GetFastValue(sys.settings, 'physics', false); - - if (!defaultSystem && !sceneSystems) - { - // No default physics system or systems in this scene - return; - } - - // Let's build the systems array - var output = []; - - if (defaultSystem) - { - output.push(UppercaseFirst(defaultSystem + 'Physics')); - } - - if (sceneSystems) - { - for (var key in sceneSystems) - { - key = UppercaseFirst(key.concat('Physics')); - - if (output.indexOf(key) === -1) - { - output.push(key); - } - } - } - - // An array of Physics systems to start for this Scene - return output; -}; - -module.exports = GetPhysicsPlugins; - - -/***/ }), -/* 398 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); - -/** - * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. - * - * @function Phaser.Scenes.GetScenePlugins - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems object to check for plugins. - * - * @return {array} An array of all plugins which should be activated, either the default ones or the ones configured in the Scene Systems object. - */ -var GetScenePlugins = function (sys) -{ - var defaultPlugins = sys.plugins.getDefaultScenePlugins(); - - var scenePlugins = GetFastValue(sys.settings, 'plugins', false); - - // Scene Plugins always override Default Plugins - if (Array.isArray(scenePlugins)) - { - return scenePlugins; - } - else if (defaultPlugins) - { - return defaultPlugins; - } - else - { - // No default plugins or plugins in this scene - return []; - } -}; - -module.exports = GetScenePlugins; - - -/***/ }), -/* 399 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(141); -var GetValue = __webpack_require__(6); -var Merge = __webpack_require__(142); -var InjectionMap = __webpack_require__(974); - -/** - * @namespace Phaser.Scenes.Settings - */ - -var Settings = { - - /** - * Takes a Scene configuration object and returns a fully formed System Settings object. - * - * @function Phaser.Scenes.Settings.create - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - The Scene configuration object used to create this Scene Settings. - * - * @return {Phaser.Types.Scenes.SettingsObject} The Scene Settings object created as a result of the config and default settings. - */ - create: function (config) - { - if (typeof config === 'string') - { - config = { key: config }; - } - else if (config === undefined) - { - // Pass the 'hasOwnProperty' checks - config = {}; - } - - return { - - status: CONST.PENDING, - - key: GetValue(config, 'key', ''), - active: GetValue(config, 'active', false), - visible: GetValue(config, 'visible', true), - - isBooted: false, - - isTransition: false, - transitionFrom: null, - transitionDuration: 0, - transitionAllowInput: true, - - // Loader payload array - - data: {}, - - pack: GetValue(config, 'pack', false), - - // Cameras - - cameras: GetValue(config, 'cameras', null), - - // Scene Property Injection Map - - map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), - - // Physics - - physics: GetValue(config, 'physics', {}), - - // Loader - - loader: GetValue(config, 'loader', {}), - - // Plugins - - plugins: GetValue(config, 'plugins', false), - - // Input - - input: GetValue(config, 'input', {}) - - }; - } - -}; - -module.exports = Settings; - - -/***/ }), -/* 400 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); -var CanvasTexture = __webpack_require__(401); -var Class = __webpack_require__(0); -var Color = __webpack_require__(35); -var CONST = __webpack_require__(39); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(103); -var GameEvents = __webpack_require__(22); -var GenerateTexture = __webpack_require__(366); -var GetValue = __webpack_require__(6); -var Parser = __webpack_require__(403); -var Texture = __webpack_require__(201); - -/** - * @callback EachTextureCallback - * - * @param {Phaser.Textures.Texture} texture - Each texture in Texture Manager. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. - */ - -/** - * @classdesc - * Textures are managed by the global TextureManager. This is a singleton class that is - * responsible for creating and delivering Textures and their corresponding Frames to Game Objects. - * - * Sprites and other Game Objects get the texture data they need from the TextureManager. - * - * Access it via `scene.textures`. - * - * @class TextureManager - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Textures - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. - */ -var TextureManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function TextureManager (game) - { - EventEmitter.call(this); - - /** - * The Game that this TextureManager belongs to. - * - * @name Phaser.Textures.TextureManager#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * The name of this manager. - * - * @name Phaser.Textures.TextureManager#name - * @type {string} - * @since 3.0.0 - */ - this.name = 'TextureManager'; - - /** - * An object that has all of textures that Texture Manager creates. - * Textures are assigned to keys so we can access to any texture that this object has directly by key value without iteration. - * - * @name Phaser.Textures.TextureManager#list - * @type {object} - * @default {} - * @since 3.0.0 - */ - this.list = {}; - - /** - * The temporary canvas element to save an pixel data of an arbitrary texture in getPixel() and getPixelAlpha() method. - * - * @name Phaser.Textures.TextureManager#_tempCanvas - * @type {HTMLCanvasElement} - * @private - * @since 3.0.0 - */ - this._tempCanvas = CanvasPool.create2D(this, 1, 1); - - /** - * The context of the temporary canvas element made to save an pixel data in getPixel() and getPixelAlpha() method. - * - * @name Phaser.Textures.TextureManager#_tempContext - * @type {CanvasRenderingContext2D} - * @private - * @since 3.0.0 - */ - this._tempContext = this._tempCanvas.getContext('2d'); - - /** - * An counting value used for emitting 'ready' event after all of managers in game is loaded. - * - * @name Phaser.Textures.TextureManager#_pending - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._pending = 0; - - game.events.once(GameEvents.BOOT, this.boot, this); - }, - - /** - * The Boot Handler called by Phaser.Game when it first starts up. - * - * @method Phaser.Textures.TextureManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - this.on(Events.LOAD, this.updatePending, this); - this.on(Events.ERROR, this.updatePending, this); - - var config = this.game.config; - - this.addBase64('__DEFAULT', config.defaultImage); - this.addBase64('__MISSING', config.missingImage); - this.addBase64('__WHITE', config.whiteImage); - - this._pending = 3; - - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, - - /** - * After 'onload' or 'onerror' invoked twice, emit 'ready' event. - * - * @method Phaser.Textures.TextureManager#updatePending - * @private - * @since 3.0.0 - */ - updatePending: function () - { - this._pending--; - - if (this._pending === 0) - { - this.off(Events.LOAD); - this.off(Events.ERROR); - - this.emit(Events.READY); - } - }, - - /** - * Checks the given texture key and throws a console.warn if the key is already in use, then returns false. - * If you wish to avoid the console.warn then use `TextureManager.exists` instead. - * - * @method Phaser.Textures.TextureManager#checkKey - * @since 3.7.0 - * - * @param {string} key - The texture key to check. - * - * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. - */ - checkKey: function (key) - { - if (this.exists(key)) - { - // eslint-disable-next-line no-console - console.error('Texture key already in use: ' + key); - - return false; - } - - return true; - }, - - /** - * Removes a Texture from the Texture Manager and destroys it. This will immediately - * clear all references to it from the Texture Manager, and if it has one, destroy its - * WebGLTexture. This will emit a `removetexture` event. - * - * Note: If you have any Game Objects still using this texture they will start throwing - * errors the next time they try to render. Make sure that removing the texture is the final - * step when clearing down to avoid this. - * - * @method Phaser.Textures.TextureManager#remove - * @fires Phaser.Textures.Events#REMOVE - * @since 3.7.0 - * - * @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it. - * - * @return {Phaser.Textures.TextureManager} The Texture Manager. - */ - remove: function (key) - { - if (typeof key === 'string') - { - if (this.exists(key)) - { - key = this.get(key); - } - else - { - console.warn('No texture found matching key: ' + key); - return this; - } - } - - // By this point key should be a Texture, if not, the following fails anyway - if (this.list.hasOwnProperty(key.key)) - { - key.destroy(); - - this.emit(Events.REMOVE, key.key); - } - - return this; - }, - - /** - * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. - * - * @method Phaser.Textures.TextureManager#removeKey - * @since 3.17.0 - * - * @param {string} key - The key to remove from the texture list. - * - * @return {Phaser.Textures.TextureManager} The Texture Manager. - */ - removeKey: function (key) - { - if (this.list.hasOwnProperty(key)) - { - delete this.list[key]; - } - - return this; - }, - - /** - * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. - * - * It works by creating an `Image` DOM object, then setting the `src` attribute to - * the given base64 encoded data. As a result, the process is asynchronous by its nature, - * so be sure to listen for the events this method dispatches before using the texture. - * - * @method Phaser.Textures.TextureManager#addBase64 - * @fires Phaser.Textures.Events#ADD - * @fires Phaser.Textures.Events#ERROR - * @fires Phaser.Textures.Events#LOAD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {*} data - The Base64 encoded data. - * - * @return {this} This Texture Manager instance. - */ - addBase64: function (key, data) - { - if (this.checkKey(key)) - { - var _this = this; - - var image = new Image(); - - image.onerror = function () - { - _this.emit(Events.ERROR, key); - }; - - image.onload = function () - { - var texture = _this.create(key, image); - - Parser.Image(texture, 0); - - _this.emit(Events.ADD, key, texture); - - _this.emit(Events.LOAD, key, texture); - }; - - image.src = data; - } - - return this; - }, - - /** - * Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data. - * - * You can also provide the image type and encoder options. - * - * This will only work with bitmap based texture frames, such as those created from Texture Atlases. - * It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please - * see the WebGL Snapshot function instead. - * - * @method Phaser.Textures.TextureManager#getBase64 - * @since 3.12.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png. - * @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored. - * - * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. - */ - getBase64: function (key, frame, type, encoderOptions) - { - if (type === undefined) { type = 'image/png'; } - if (encoderOptions === undefined) { encoderOptions = 0.92; } - - var data = ''; - - var textureFrame = this.getFrame(key, frame); - - if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) - { - console.warn('Cannot getBase64 from WebGL Texture'); - } - else if (textureFrame) - { - var cd = textureFrame.canvasData; - - var canvas = CanvasPool.create2D(this, cd.width, cd.height); - var ctx = canvas.getContext('2d'); - - ctx.drawImage( - textureFrame.source.image, - cd.x, - cd.y, - cd.width, - cd.height, - 0, - 0, - cd.width, - cd.height - ); - - data = canvas.toDataURL(type, encoderOptions); - - CanvasPool.remove(canvas); - } - - return data; - }, - - /** - * Adds a new Texture to the Texture Manager created from the given Image element. - * - * @method Phaser.Textures.TextureManager#addImage - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addImage: function (key, source, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.Image(texture, 0); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Takes a WebGL Texture and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. - * - * This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites. - * - * If the `width` and `height` arguments are omitted, but the WebGL Texture was created by Phaser's WebGL Renderer - * and has `glTexture.width` and `glTexture.height` properties, these values will be used instead. - * - * This is a WebGL only feature. - * - * @method Phaser.Textures.TextureManager#addGLTexture - * @fires Phaser.Textures.Events#ADD - * @since 3.19.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {WebGLTexture} glTexture - The source Render Texture. - * @param {number} [width] - The new width of the Texture. Read from `glTexture.width` if omitted. - * @param {number} [height] - The new height of the Texture. Read from `glTexture.height` if omitted. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addGLTexture: function (key, glTexture, width, height) - { - var texture = null; - - if (this.checkKey(key)) - { - if (width === undefined) { width = glTexture.width; } - if (height === undefined) { height = glTexture.height; } - - texture = this.create(key, glTexture, width, height); - - texture.add('__BASE', 0, 0, 0, width, height); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Render Texture to the Texture Manager using the given key. - * This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites. - * - * @method Phaser.Textures.TextureManager#addRenderTexture - * @fires Phaser.Textures.Events#ADD - * @since 3.12.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addRenderTexture: function (key, renderTexture) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, renderTexture); - - texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Creates a new Texture using the given config values. - * - * Generated textures consist of a Canvas element to which the texture data is drawn. - * - * Generates a texture based on the given Create configuration object. - * - * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the - * data cells map to a single color. For example, if the texture config looked like this: - * - * ```javascript - * var star = [ - * '.....828.....', - * '....72227....', - * '....82228....', - * '...7222227...', - * '2222222222222', - * '8222222222228', - * '.72222222227.', - * '..787777787..', - * '..877777778..', - * '.78778887787.', - * '.27887.78872.', - * '.787.....787.' - * ]; - * - * this.textures.generate('star', { data: star, pixelWidth: 4 }); - * ``` - * - * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array - * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color - * number 8 in the palette. If a cell contains a period character `.` then it is transparent. - * - * The default palette is Arne16, but you can specify your own using the `palette` property. - * - * @method Phaser.Textures.TextureManager#generate - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.Types.Create.GenerateTextureConfig} config - The configuration object needed to generate the texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - generate: function (key, config) - { - if (this.checkKey(key)) - { - var canvas = CanvasPool.create(this, 1, 1); - - config.canvas = canvas; - - GenerateTexture(config); - - return this.addCanvas(key, canvas); - } - else - { - return null; - } - }, - - /** - * Creates a new Texture using a blank Canvas element of the size given. - * - * Canvas elements are automatically pooled and calling this method will - * extract a free canvas from the CanvasPool, or create one if none are available. - * - * @method Phaser.Textures.TextureManager#createCanvas - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {number} [width=256] - The width of the Canvas element. - * @param {number} [height=256] - The height of the Canvas element. - * - * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. - */ - createCanvas: function (key, width, height) - { - if (width === undefined) { width = 256; } - if (height === undefined) { height = 256; } - - if (this.checkKey(key)) - { - var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); - - return this.addCanvas(key, canvas); - } - - return null; - }, - - /** - * Creates a new Canvas Texture object from an existing Canvas element - * and adds it to this Texture Manager, unless `skipCache` is true. - * - * @method Phaser.Textures.TextureManager#addCanvas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture. - * @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache? - * - * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. - */ - addCanvas: function (key, source, skipCache) - { - if (skipCache === undefined) { skipCache = false; } - - var texture = null; - - if (skipCache) - { - texture = new CanvasTexture(this, key, source, source.width, source.height); - } - else if (this.checkKey(key)) - { - texture = new CanvasTexture(this, key, source, source.width, source.height); - - this.list[key] = texture; - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a new Texture Atlas to this Texture Manager. - * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. - * - * @method Phaser.Textures.TextureManager#addAtlas - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlas: function (key, source, data, dataSource) - { - // New Texture Packer format? - if (Array.isArray(data.textures) || Array.isArray(data.frames)) - { - return this.addAtlasJSONArray(key, source, data, dataSource); - } - else - { - return this.addAtlasJSONHash(key, source, data, dataSource); - } - }, - - /** - * Adds a Texture Atlas to this Texture Manager. - * The frame data of the atlas must be stored in an Array within the JSON. - * This is known as a JSON Array in software such as Texture Packer. - * - * @method Phaser.Textures.TextureManager#addAtlasJSONArray - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(HTMLImageElement|HTMLImageElement[])} source - The source Image element/s. - * @param {(object|object[])} data - The Texture Atlas data/s. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasJSONArray: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - // Multi-Atlas? - if (Array.isArray(data)) - { - var singleAtlasFile = (data.length === 1); // multi-pack with one atlas file for all images - - // !! Assumes the textures are in the same order in the source array as in the json data !! - for (var i = 0; i < texture.source.length; i++) - { - var atlasData = singleAtlasFile ? data[0] : data[i]; - - Parser.JSONArray(texture, i, atlasData); - } - } - else - { - Parser.JSONArray(texture, 0, data); - } - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Texture Atlas to this Texture Manager. - * The frame data of the atlas must be stored in an Object within the JSON. - * This is known as a JSON Hash in software such as Texture Packer. - * - * @method Phaser.Textures.TextureManager#addAtlasJSONHash - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasJSONHash: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - if (Array.isArray(data)) - { - for (var i = 0; i < data.length; i++) - { - Parser.JSONHash(texture, i, data[i]); - } - } - else - { - Parser.JSONHash(texture, 0, data); - } - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Texture Atlas to this Texture Manager, where the atlas data is given - * in the XML format. - * - * @method Phaser.Textures.TextureManager#addAtlasXML - * @fires Phaser.Textures.Events#ADD - * @since 3.7.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas XML data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addAtlasXML: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.AtlasXML(texture, 0, data); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Unity Texture Atlas to this Texture Manager. - * The data must be in the form of a Unity YAML file. - * - * @method Phaser.Textures.TextureManager#addUnityAtlas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {object} data - The Texture Atlas data. - * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addUnityAtlas: function (key, source, data, dataSource) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - Parser.UnityYAML(texture, 0, data); - - if (dataSource) - { - texture.setDataSource(dataSource); - } - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Sprite Sheet to this Texture Manager. - * - * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact - * same size and cannot be trimmed or rotated. - * - * @method Phaser.Textures.TextureManager#addSpriteSheet - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addSpriteSheet: function (key, source, config) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, source); - - var width = texture.source[0].width; - var height = texture.source[0].height; - - Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); - - this.emit(Events.ADD, key, texture); - } - - return texture; - }, - - /** - * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. - * - * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact - * same size and cannot be trimmed or rotated. - * - * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas - * @fires Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - addSpriteSheetFromAtlas: function (key, config) - { - if (!this.checkKey(key)) - { - return null; - } - - var atlasKey = GetValue(config, 'atlas', null); - var atlasFrame = GetValue(config, 'frame', null); - - if (!atlasKey || !atlasFrame) - { - return; - } - - var atlas = this.get(atlasKey); - var sheet = atlas.get(atlasFrame); - - if (sheet) - { - var texture = this.create(key, sheet.source.image); - - if (sheet.trimmed) - { - // If trimmed we need to help the parser adjust - Parser.SpriteSheetFromAtlas(texture, sheet, config); - } - else - { - Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); - } - - this.emit(Events.ADD, key, texture); - - return texture; - } - }, - - /** - * Creates a new Texture using the given source and dimensions. - * - * @method Phaser.Textures.TextureManager#create - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {HTMLImageElement} source - The source Image element. - * @param {number} width - The width of the Texture. - * @param {number} height - The height of the Texture. - * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. - */ - create: function (key, source, width, height) - { - var texture = null; - - if (this.checkKey(key)) - { - texture = new Texture(this, key, source, width, height); - - this.list[key] = texture; - } - - return texture; - }, - - /** - * Checks the given key to see if a Texture using it exists within this Texture Manager. - * - * @method Phaser.Textures.TextureManager#exists - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * - * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. - */ - exists: function (key) - { - return (this.list.hasOwnProperty(key)); - }, - - /** - * Returns a Texture from the Texture Manager that matches the given key. - * - * If the key is `undefined` it will return the `__DEFAULT` Texture. - * - * If the key is an instance of a Texture, it will return the key directly. - * - * Finally. if the key is given, but not found and not a Texture instance, it will return the `__MISSING` Texture. - * - * @method Phaser.Textures.TextureManager#get - * @since 3.0.0 - * - * @param {(string|Phaser.Textures.Texture)} key - The unique string-based key of the Texture, or a Texture instance. - * - * @return {Phaser.Textures.Texture} The Texture that was created. - */ - get: function (key) - { - if (key === undefined) { key = '__DEFAULT'; } - - if (this.list[key]) - { - return this.list[key]; - } - else if (key instanceof Texture) - { - return key; - } - else - { - return this.list['__MISSING']; - } - }, - - /** - * Takes a Texture key and Frame name and returns a clone of that Frame if found. - * - * @method Phaser.Textures.TextureManager#cloneFrame - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} frame - The string or index of the Frame to be cloned. - * - * @return {Phaser.Textures.Frame} A Clone of the given Frame. - */ - cloneFrame: function (key, frame) - { - if (this.list[key]) - { - return this.list[key].get(frame).clone(); - } - }, - - /** - * Takes a Texture key and Frame name and returns a reference to that Frame, if found. - * - * @method Phaser.Textures.TextureManager#getFrame - * @since 3.0.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * - * @return {Phaser.Textures.Frame} A Texture Frame object. - */ - getFrame: function (key, frame) - { - if (this.list[key]) - { - return this.list[key].get(frame); - } - }, - - /** - * Returns an array with all of the keys of all Textures in this Texture Manager. - * The output array will exclude the `__DEFAULT` and `__MISSING` keys. - * - * @method Phaser.Textures.TextureManager#getTextureKeys - * @since 3.0.0 - * - * @return {string[]} An array containing all of the Texture keys stored in this Texture Manager. - */ - getTextureKeys: function () - { - var output = []; - - for (var key in this.list) - { - if (key !== '__DEFAULT' && key !== '__MISSING') - { - output.push(key); - } - } - - return output; - }, - - /** - * Given a Texture and an `x` and `y` coordinate this method will return a new - * Color object that has been populated with the color and alpha values of the pixel - * at that location in the Texture. - * - * @method Phaser.Textures.TextureManager#getPixel - * @since 3.0.0 - * - * @param {number} x - The x coordinate of the pixel within the Texture. - * @param {number} y - The y coordinate of the pixel within the Texture. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {?Phaser.Display.Color} A Color object populated with the color values of the requested pixel, - * or `null` if the coordinates were out of bounds. - */ - getPixel: function (x, y, key, frame) - { - var textureFrame = this.getFrame(key, frame); - - if (textureFrame) - { - // Adjust for trim (if not trimmed x and y are just zero) - x -= textureFrame.x; - y -= textureFrame.y; - - var data = textureFrame.data.cut; - - x += data.x; - y += data.y; - - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; - - ctx.clearRect(0, 0, 1, 1); - ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - - var rgb = ctx.getImageData(0, 0, 1, 1); - - return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); - } - } - - return null; - }, - - /** - * Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255 - * corresponding to the alpha value of the pixel at that location in the Texture. If the coordinate - * is out of bounds it will return null. - * - * @method Phaser.Textures.TextureManager#getPixelAlpha - * @since 3.10.0 - * - * @param {number} x - The x coordinate of the pixel within the Texture. - * @param {number} y - The y coordinate of the pixel within the Texture. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds. - */ - getPixelAlpha: function (x, y, key, frame) - { - var textureFrame = this.getFrame(key, frame); - - if (textureFrame) - { - // Adjust for trim (if not trimmed x and y are just zero) - x -= textureFrame.x; - y -= textureFrame.y; - - var data = textureFrame.data.cut; - - x += data.x; - y += data.y; - - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; - - ctx.clearRect(0, 0, 1, 1); - ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - - var rgb = ctx.getImageData(0, 0, 1, 1); - - return rgb.data[3]; - } - } - - return null; - }, - - /** - * Sets the given Game Objects `texture` and `frame` properties so that it uses - * the Texture and Frame specified in the `key` and `frame` arguments to this method. - * - * @method Phaser.Textures.TextureManager#setTexture - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the texture would be set on. - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string or index of the Frame. - * - * @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on. - */ - setTexture: function (gameObject, key, frame) - { - if (this.list[key]) - { - gameObject.texture = this.list[key]; - gameObject.frame = gameObject.texture.get(frame); - } - - return gameObject; - }, - - /** - * Changes the key being used by a Texture to the new key provided. - * - * The old key is removed, allowing it to be re-used. - * - * Game Objects are linked to Textures by a reference to the Texture object, so - * all existing references will be retained. - * - * @method Phaser.Textures.TextureManager#renameTexture - * @since 3.12.0 - * - * @param {string} currentKey - The current string-based key of the Texture you wish to rename. - * @param {string} newKey - The new unique string-based key to use for the Texture. - * - * @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`. - */ - renameTexture: function (currentKey, newKey) - { - var texture = this.get(currentKey); - - if (texture && currentKey !== newKey) - { - texture.key = newKey; - - this.list[newKey] = texture; - - delete this.list[currentKey]; - - return true; - } - - return false; - }, - - /** - * Passes all Textures to the given callback. - * - * @method Phaser.Textures.TextureManager#each - * @since 3.0.0 - * - * @param {EachTextureCallback} callback - The callback function to be sent the Textures. - * @param {object} scope - The value to use as `this` when executing the callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. - */ - each: function (callback, scope) - { - var args = [ null ]; - - for (var i = 1; i < arguments.length; i++) - { - args.push(arguments[i]); - } - - for (var texture in this.list) - { - args[0] = this.list[texture]; - - callback.apply(scope, args); - } - }, - - /** - * Destroys the Texture Manager and all Textures stored within it. - * - * @method Phaser.Textures.TextureManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var texture in this.list) - { - this.list[texture].destroy(); - } - - this.list = {}; - - this.game = null; - - CanvasPool.remove(this._tempCanvas); - } - -}); - -module.exports = TextureManager; - - -/***/ }), -/* 401 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Clamp = __webpack_require__(17); -var Color = __webpack_require__(35); -var CONST = __webpack_require__(39); -var IsSizePowerOfTwo = __webpack_require__(136); -var Texture = __webpack_require__(201); - -/** - * @classdesc - * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. - * - * You can use the properties of this texture to draw to the canvas element directly, using all of the standard - * canvas operations available in the browser. Any Game Object can be given this texture and will render with it. - * - * Note: When running under WebGL the Canvas Texture needs to re-generate its base WebGLTexture and reupload it to - * the GPU every time you modify it, otherwise the changes you make to this texture will not be visible. To do this - * you should call `CanvasTexture.refresh()` once you are finished with your changes to the canvas. Try and keep - * this to a minimum, especially on large canvas sizes, or you may inadvertently thrash the GPU by constantly uploading - * texture data to it. This restriction does not apply if using the Canvas Renderer. - * - * It starts with only one frame that covers the whole of the canvas. You can add further frames, that specify - * sections of the canvas using the `add` method. - * - * Should you need to resize the canvas use the `setSize` method so that it accurately updates all of the underlying - * texture data as well. Forgetting to do this (i.e. by changing the canvas size directly from your code) could cause - * graphical errors. - * - * @class CanvasTexture - * @extends Phaser.Textures.Texture - * @memberof Phaser.Textures - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Textures.TextureManager} manager - A reference to the Texture Manager this Texture belongs to. - * @param {string} key - The unique string-based key of this Texture. - * @param {HTMLCanvasElement} source - The canvas element that is used as the base of this texture. - * @param {number} width - The width of the canvas. - * @param {number} height - The height of the canvas. - */ -var CanvasTexture = new Class({ - - Extends: Texture, - - initialize: - - function CanvasTexture (manager, key, source, width, height) - { - Texture.call(this, manager, key, source, width, height); - - this.add('__BASE', 0, 0, 0, width, height); - - /** - * A reference to the Texture Source of this Canvas. - * - * @name Phaser.Textures.CanvasTexture#_source - * @type {Phaser.Textures.TextureSource} - * @private - * @since 3.7.0 - */ - this._source = this.frames['__BASE'].source; - - /** - * The source Canvas Element. - * - * @name Phaser.Textures.CanvasTexture#canvas - * @readonly - * @type {HTMLCanvasElement} - * @since 3.7.0 - */ - this.canvas = this._source.image; - - /** - * The 2D Canvas Rendering Context. - * - * @name Phaser.Textures.CanvasTexture#context - * @readonly - * @type {CanvasRenderingContext2D} - * @since 3.7.0 - */ - this.context = this.canvas.getContext('2d'); - - /** - * The width of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. - * - * @name Phaser.Textures.CanvasTexture#width - * @readonly - * @type {number} - * @since 3.7.0 - */ - this.width = width; - - /** - * The height of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. - * - * @name Phaser.Textures.CanvasTexture#height - * @readonly - * @type {number} - * @since 3.7.0 - */ - this.height = height; - - /** - * The context image data. - * Use the `update` method to populate this when the canvas changes. - * - * @name Phaser.Textures.CanvasTexture#imageData - * @type {ImageData} - * @since 3.13.0 - */ - this.imageData = this.context.getImageData(0, 0, width, height); - - /** - * A Uint8ClampedArray view into the `buffer`. - * Use the `update` method to populate this when the canvas changes. - * Note that this is unavailable in some browsers, such as Epic Browser, due to their security restrictions. - * - * @name Phaser.Textures.CanvasTexture#data - * @type {Uint8ClampedArray} - * @since 3.13.0 - */ - this.data = null; - - if (this.imageData) - { - this.data = this.imageData.data; - } - - /** - * An Uint32Array view into the `buffer`. - * - * @name Phaser.Textures.CanvasTexture#pixels - * @type {Uint32Array} - * @since 3.13.0 - */ - this.pixels = null; - - /** - * An ArrayBuffer the same size as the context ImageData. - * - * @name Phaser.Textures.CanvasTexture#buffer - * @type {ArrayBuffer} - * @since 3.13.0 - */ - this.buffer; - - if (this.data) - { - if (this.imageData.data.buffer) - { - this.buffer = this.imageData.data.buffer; - this.pixels = new Uint32Array(this.buffer); - } - else if (window.ArrayBuffer) - { - this.buffer = new ArrayBuffer(this.imageData.data.length); - this.pixels = new Uint32Array(this.buffer); - } - else - { - this.pixels = this.imageData.data; - } - } - }, - - /** - * This re-creates the `imageData` from the current context. - * It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array. - * - * Warning: This is a very expensive operation, so use it sparingly. - * - * @method Phaser.Textures.CanvasTexture#update - * @since 3.13.0 - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - update: function () - { - this.imageData = this.context.getImageData(0, 0, this.width, this.height); - - this.data = this.imageData.data; - - if (this.imageData.data.buffer) - { - this.buffer = this.imageData.data.buffer; - this.pixels = new Uint32Array(this.buffer); - } - else if (window.ArrayBuffer) - { - this.buffer = new ArrayBuffer(this.imageData.data.length); - this.pixels = new Uint32Array(this.buffer); - } - else - { - this.pixels = this.imageData.data; - } - - if (this.manager.game.config.renderType === CONST.WEBGL) - { - this.refresh(); - } - - return this; - }, - - /** - * Draws the given Image or Canvas element to this CanvasTexture, then updates the internal - * ImageData buffer and arrays. - * - * @method Phaser.Textures.CanvasTexture#draw - * @since 3.13.0 - * - * @param {number} x - The x coordinate to draw the source at. - * @param {number} y - The y coordinate to draw the source at. - * @param {(HTMLImageElement|HTMLCanvasElement)} source - The element to draw to this canvas. - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - draw: function (x, y, source) - { - this.context.drawImage(source, x, y); - - return this.update(); - }, - - /** - * Draws the given texture frame to this CanvasTexture, then updates the internal - * ImageData buffer and arrays. - * - * @method Phaser.Textures.CanvasTexture#drawFrame - * @since 3.16.0 - * - * @param {string} key - The unique string-based key of the Texture. - * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. - * @param {number} [x=0] - The x coordinate to draw the source at. - * @param {number} [y=0] - The y coordinate to draw the source at. - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - drawFrame: function (key, frame, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - var textureFrame = this.manager.getFrame(key, frame); - - if (textureFrame) - { - var cd = textureFrame.canvasData; - - var width = textureFrame.cutWidth; - var height = textureFrame.cutHeight; - var res = textureFrame.source.resolution; - - this.context.drawImage( - textureFrame.source.image, - cd.x, cd.y, - width, - height, - x, y, - width / res, - height / res - ); - - return this.update(); - } - else - { - return this; - } - }, - - /** - * Sets a pixel in the CanvasTexture to the given color and alpha values. - * - * This is an expensive operation to run in large quantities, so use sparingly. - * - * @method Phaser.Textures.CanvasTexture#setPixel - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} red - The red color value. A number between 0 and 255. - * @param {number} green - The green color value. A number between 0 and 255. - * @param {number} blue - The blue color value. A number between 0 and 255. - * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. - * - * @return {this} This CanvasTexture. - */ - setPixel: function (x, y, red, green, blue, alpha) - { - if (alpha === undefined) { alpha = 255; } - - x = Math.abs(Math.floor(x)); - y = Math.abs(Math.floor(y)); - - var index = this.getIndex(x, y); - - if (index > -1) - { - var imageData = this.context.getImageData(x, y, 1, 1); - - imageData.data[0] = red; - imageData.data[1] = green; - imageData.data[2] = blue; - imageData.data[3] = alpha; - - this.context.putImageData(imageData, x, y); - } - - return this; - }, - - /** - * Puts the ImageData into the context of this CanvasTexture at the given coordinates. - * - * @method Phaser.Textures.CanvasTexture#putData - * @since 3.16.0 - * - * @param {ImageData} imageData - The ImageData to put at the given location. - * @param {number} x - The x coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [dirtyX=0] - Horizontal position (x coordinate) of the top-left corner from which the image data will be extracted. - * @param {number} [dirtyY=0] - Vertical position (x coordinate) of the top-left corner from which the image data will be extracted. - * @param {number} [dirtyWidth] - Width of the rectangle to be painted. Defaults to the width of the image data. - * @param {number} [dirtyHeight] - Height of the rectangle to be painted. Defaults to the height of the image data. - * - * @return {this} This CanvasTexture. - */ - putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) - { - if (dirtyX === undefined) { dirtyX = 0; } - if (dirtyY === undefined) { dirtyY = 0; } - if (dirtyWidth === undefined) { dirtyWidth = imageData.width; } - if (dirtyHeight === undefined) { dirtyHeight = imageData.height; } - - this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight); - - return this; - }, - - /** - * Gets an ImageData region from this CanvasTexture from the position and size specified. - * You can write this back using `CanvasTexture.putData`, or manipulate it. - * - * @method Phaser.Textures.CanvasTexture#getData - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} width - The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left. - * @param {number} height - The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up. - * - * @return {ImageData} The ImageData extracted from this CanvasTexture. - */ - getData: function (x, y, width, height) - { - x = Clamp(Math.floor(x), 0, this.width - 1); - y = Clamp(Math.floor(y), 0, this.height - 1); - width = Clamp(width, 1, this.width - x); - height = Clamp(height, 1, this.height - y); - - var imageData = this.context.getImageData(x, y, width, height); - - return imageData; - }, - - /** - * Get the color of a specific pixel from this texture and store it in a Color object. - * - * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, - * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. - * - * @method Phaser.Textures.CanvasTexture#getPixel - * @since 3.13.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {Phaser.Display.Color} [out] - A Color object to store the pixel values in. If not provided a new Color object will be created. - * - * @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties. - */ - getPixel: function (x, y, out) - { - if (!out) - { - out = new Color(); - } - - var index = this.getIndex(x, y); - - if (index > -1) - { - var data = this.data; - - var r = data[index + 0]; - var g = data[index + 1]; - var b = data[index + 2]; - var a = data[index + 3]; - - out.setTo(r, g, b, a); - } - - return out; - }, - - /** - * Returns an array containing all of the pixels in the given region. - * - * If the requested region extends outside the bounds of this CanvasTexture, - * the region is truncated to fit. - * - * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, - * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. - * - * @method Phaser.Textures.CanvasTexture#getPixels - * @since 3.16.0 - * - * @param {number} [x=0] - The x coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [y=0] - The y coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} [width] - The width of the region to get. Must be an integer. Defaults to the canvas width if not given. - * @param {number} [height] - The height of the region to get. Must be an integer. If not given will be set to the `width`. - * - * @return {Phaser.Types.Textures.PixelConfig[][]} A 2d array of Pixel objects. - */ - getPixels: function (x, y, width, height) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = width; } - - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); - - var left = Clamp(x, 0, this.width); - var right = Clamp(x + width, 0, this.width); - var top = Clamp(y, 0, this.height); - var bottom = Clamp(y + height, 0, this.height); - - var pixel = new Color(); - - var out = []; - - for (var py = top; py < bottom; py++) - { - var row = []; - - for (var px = left; px < right; px++) - { - pixel = this.getPixel(px, py, pixel); - - row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); - } - - out.push(row); - } - - return out; - }, - - /** - * Returns the Image Data index for the given pixel in this CanvasTexture. - * - * The index can be used to read directly from the `this.data` array. - * - * The index points to the red value in the array. The subsequent 3 indexes - * point to green, blue and alpha respectively. - * - * @method Phaser.Textures.CanvasTexture#getIndex - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. - * - * @return {number} - */ - getIndex: function (x, y) - { - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); - - if (x < this.width && y < this.height) - { - return (x + y * this.width) * 4; - } - else - { - return -1; - } - }, - - /** - * This should be called manually if you are running under WebGL. - * It will refresh the WebGLTexture from the Canvas source. Only call this if you know that the - * canvas has changed, as there is a significant GPU texture allocation cost involved in doing so. - * - * @method Phaser.Textures.CanvasTexture#refresh - * @since 3.7.0 - * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. - */ - refresh: function () - { - this._source.update(); - - return this; - }, - - /** - * Gets the Canvas Element. - * - * @method Phaser.Textures.CanvasTexture#getCanvas - * @since 3.7.0 - * - * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. - */ - getCanvas: function () - { - return this.canvas; - }, - - /** - * Gets the 2D Canvas Rendering Context. - * - * @method Phaser.Textures.CanvasTexture#getContext - * @since 3.7.0 - * - * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. - */ - getContext: function () - { - return this.context; - }, - - /** - * Clears the given region of this Canvas Texture, resetting it back to transparent. - * If no region is given, the whole Canvas Texture is cleared. - * - * @method Phaser.Textures.CanvasTexture#clear - * @since 3.7.0 - * - * @param {number} [x=0] - The x coordinate of the top-left of the region to clear. - * @param {number} [y=0] - The y coordinate of the top-left of the region to clear. - * @param {number} [width] - The width of the region. - * @param {number} [height] - The height of the region. - * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. - */ - clear: function (x, y, width, height) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } - - this.context.clearRect(x, y, width, height); - - return this.update(); - }, - - /** - * Changes the size of this Canvas Texture. - * - * @method Phaser.Textures.CanvasTexture#setSize - * @since 3.7.0 - * - * @param {number} width - The new width of the Canvas. - * @param {number} [height] - The new height of the Canvas. If not given it will use the width as the height. - * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. - */ - setSize: function (width, height) - { - if (height === undefined) { height = width; } - - if (width !== this.width || height !== this.height) - { - // Update the Canvas - this.canvas.width = width; - this.canvas.height = height; - - // Update the Texture Source - this._source.width = width; - this._source.height = height; - this._source.isPowerOf2 = IsSizePowerOfTwo(width, height); - - // Update the Frame - this.frames['__BASE'].setSize(width, height, 0, 0); - - // Update this - this.width = width; - this.height = height; - - this.refresh(); - } - - return this; - }, - - /** - * Destroys this Texture and releases references to its sources and frames. - * - * @method Phaser.Textures.CanvasTexture#destroy - * @since 3.16.0 - */ - destroy: function () - { - Texture.prototype.destroy.call(this); - - this._source = null; - this.canvas = null; - this.context = null; - this.imageData = null; - this.data = null; - this.pixels = null; - this.buffer = null; - } - -}); - -module.exports = CanvasTexture; - - -/***/ }), -/* 402 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); -var Class = __webpack_require__(0); -var IsSizePowerOfTwo = __webpack_require__(136); -var ScaleModes = __webpack_require__(263); - -/** - * @classdesc - * A Texture Source is the encapsulation of the actual source data for a Texture. - * - * This is typically an Image Element, loaded from the file system or network, a Canvas Element or a Video Element. - * - * A Texture can contain multiple Texture Sources, which only happens when a multi-atlas is loaded. - * - * @class TextureSource - * @memberof Phaser.Textures - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture this TextureSource belongs to. - * @param {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} source - The source image data. - * @param {number} [width] - Optional width of the source image. If not given it's derived from the source itself. - * @param {number} [height] - Optional height of the source image. If not given it's derived from the source itself. - * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. - */ -var TextureSource = new Class({ - - initialize: - - function TextureSource (texture, source, width, height, flipY) - { - if (flipY === undefined) { flipY = false; } - - var game = texture.manager.game; - - /** - * The Texture this TextureSource belongs to. - * - * @name Phaser.Textures.TextureSource#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.7.0 - */ - this.renderer = game.renderer; - - /** - * The Texture this TextureSource belongs to. - * - * @name Phaser.Textures.TextureSource#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 - */ - this.texture = texture; - - /** - * The source of the image data. - * - * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. - * - * @name Phaser.Textures.TextureSource#source - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} - * @since 3.12.0 - */ - this.source = source; - - /** - * The image data. - * - * This is either an Image element, Canvas element or a Video Element. - * - * @name Phaser.Textures.TextureSource#image - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} - * @since 3.0.0 - */ - this.image = source; - - /** - * Currently un-used. - * - * @name Phaser.Textures.TextureSource#compressionAlgorithm - * @type {number} - * @default null - * @since 3.0.0 - */ - this.compressionAlgorithm = null; - - /** - * The resolution of the source image. - * - * @name Phaser.Textures.TextureSource#resolution - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.resolution = 1; - - /** - * The width of the source image. If not specified in the constructor it will check - * the `naturalWidth` and then `width` properties of the source image. - * - * @name Phaser.Textures.TextureSource#width - * @type {number} - * @since 3.0.0 - */ - this.width = width || source.naturalWidth || source.videoWidth || source.width || 0; - - /** - * The height of the source image. If not specified in the constructor it will check - * the `naturalHeight` and then `height` properties of the source image. - * - * @name Phaser.Textures.TextureSource#height - * @type {number} - * @since 3.0.0 - */ - this.height = height || source.naturalHeight || source.videoHeight || source.height || 0; - - /** - * The Scale Mode the image will use when rendering. - * Either Linear or Nearest. - * - * @name Phaser.Textures.TextureSource#scaleMode - * @type {number} - * @since 3.0.0 - */ - this.scaleMode = ScaleModes.DEFAULT; - - /** - * Is the source image a Canvas Element? - * - * @name Phaser.Textures.TextureSource#isCanvas - * @type {boolean} - * @since 3.0.0 - */ - this.isCanvas = (source instanceof HTMLCanvasElement); - - /** - * Is the source image a Video Element? - * - * @name Phaser.Textures.TextureSource#isVideo - * @type {boolean} - * @since 3.20.0 - */ - this.isVideo = (window.hasOwnProperty('HTMLVideoElement') && source instanceof HTMLVideoElement); - - /** - * Is the source image a Render Texture? - * - * @name Phaser.Textures.TextureSource#isRenderTexture - * @type {boolean} - * @since 3.12.0 - */ - this.isRenderTexture = (source.type === 'RenderTexture'); - - /** - * Is the source image a WebGLTexture? - * - * @name Phaser.Textures.TextureSource#isGLTexture - * @type {boolean} - * @since 3.19.0 - */ - this.isGLTexture = (window.hasOwnProperty('WebGLTexture') && source instanceof WebGLTexture); - - /** - * Are the source image dimensions a power of two? - * - * @name Phaser.Textures.TextureSource#isPowerOf2 - * @type {boolean} - * @since 3.0.0 - */ - this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height); - - /** - * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture - * already, then this is a reference to that WebGLTexture. - * - * @name Phaser.Textures.TextureSource#glTexture - * @type {?WebGLTexture} - * @default null - * @since 3.0.0 - */ - this.glTexture = null; - - /** - * The current texture unit index as assigned by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. - * - * @name Phaser.Textures.TextureSource#glIndex - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.glIndex = 0; - - /** - * The counter value when this texture was last assigned an index by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. - * - * @name Phaser.Textures.TextureSource#glIndexCounter - * @type {number} - * @default -1 - * @since 3.50.0 - */ - this.glIndexCounter = -1; - - /** - * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. - * - * @name Phaser.Textures.TextureSource#flipY - * @type {boolean} - * @since 3.20.0 - */ - this.flipY = flipY; - - this.init(game); - }, - - /** - * Creates a WebGL Texture, if required, and sets the Texture filter mode. - * - * @method Phaser.Textures.TextureSource#init - * @since 3.0.0 - * - * @param {Phaser.Game} game - A reference to the Phaser Game instance. - */ - init: function (game) - { - var renderer = this.renderer; - - if (renderer) - { - if (renderer.gl) - { - if (this.isCanvas) - { - this.glTexture = renderer.createCanvasTexture(this.image, false, this.flipY); - } - else if (this.isVideo) - { - this.glTexture = renderer.createVideoTexture(this.image, false, this.flipY); - } - else if (this.isRenderTexture) - { - this.image = this.source.canvas; - - this.glTexture = renderer.createTextureFromSource(null, this.width, this.height, this.scaleMode); - } - else if (this.isGLTexture) - { - this.glTexture = this.source; - } - else - { - this.glTexture = renderer.createTextureFromSource(this.image, this.width, this.height, this.scaleMode); - } - } - else if (this.isRenderTexture) - { - this.image = this.source.canvas; - } - } - - if (!game.config.antialias) - { - this.setFilter(1); - } - }, - - /** - * Sets the Filter Mode for this Texture. - * - * The mode can be either Linear, the default, or Nearest. - * - * For pixel-art you should use Nearest. - * - * @method Phaser.Textures.TextureSource#setFilter - * @since 3.0.0 - * - * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. - */ - setFilter: function (filterMode) - { - if (this.renderer.gl) - { - this.renderer.setTextureFilter(this.glTexture, filterMode); - } - - this.scaleMode = filterMode; - }, - - /** - * Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload. - * - * @method Phaser.Textures.TextureSource#setFlipY - * @since 3.20.0 - * - * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? - */ - setFlipY: function (value) - { - if (value === undefined) { value = true; } - - this.flipY = value; - - return this; - }, - - /** - * If this TextureSource is backed by a Canvas and is running under WebGL, - * it updates the WebGLTexture using the canvas data. - * - * @method Phaser.Textures.TextureSource#update - * @since 3.7.0 - */ - update: function () - { - var gl = this.renderer.gl; - - if (gl && this.isCanvas) - { - this.glTexture = this.renderer.updateCanvasTexture(this.image, this.glTexture, this.flipY); - } - else if (gl && this.isVideo) - { - this.glTexture = this.renderer.updateVideoTexture(this.image, this.glTexture, this.flipY); - } - }, - - /** - * Destroys this Texture Source and nulls the references. - * - * @method Phaser.Textures.TextureSource#destroy - * @since 3.0.0 - */ - destroy: function () - { - if (this.glTexture) - { - this.renderer.deleteTexture(this.glTexture, false); - } - - if (this.isCanvas) - { - CanvasPool.remove(this.image); - } - - this.renderer = null; - this.texture = null; - this.source = null; - this.image = null; - this.glTexture = null; - } - -}); - -module.exports = TextureSource; - - -/***/ }), -/* 403 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Textures.Parsers - */ - -module.exports = { - - AtlasXML: __webpack_require__(975), - Canvas: __webpack_require__(976), - Image: __webpack_require__(977), - JSONArray: __webpack_require__(978), - JSONHash: __webpack_require__(979), - SpriteSheet: __webpack_require__(980), - SpriteSheetFromAtlas: __webpack_require__(981), - UnityYAML: __webpack_require__(982) - -}; - - -/***/ }), -/* 404 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var HTML5AudioSoundManager = __webpack_require__(405); -var NoAudioSoundManager = __webpack_require__(408); -var WebAudioSoundManager = __webpack_require__(410); - -/** - * Creates a Web Audio, HTML5 Audio or No Audio Sound Manager based on config and device settings. - * - * Be aware of https://developers.google.com/web/updates/2017/09/autoplay-policy-changes - * - * @function Phaser.Sound.SoundManagerCreator - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - * - * @return {(Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager|Phaser.Sound.NoAudioSoundManager)} The Sound Manager instance that was created. - */ -var SoundManagerCreator = { - - create: function (game) - { - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - return new NoAudioSoundManager(game); - } - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - return new WebAudioSoundManager(game); - } - - return new HTML5AudioSoundManager(game); - } - -}; - -module.exports = SoundManagerCreator; - - -/***/ }), -/* 405 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var HTML5AudioSound = __webpack_require__(407); - -/** - * HTML5 Audio implementation of the Sound Manager. - * - * To play multiple instances of the same HTML5 Audio sound, you need to provide an `instances` value when - * loading the sound with the Loader: - * - * ```javascript - * this.load.audio('explosion', 'explosion.mp3', { - * instances: 2 - * }); - * ``` - * - * Not all browsers can play all audio formats. - * - * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). - * - * @class HTML5AudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var HTML5AudioSoundManager = new Class({ - - Extends: BaseSoundManager, - - initialize: - - function HTML5AudioSoundManager (game) - { - /** - * Flag indicating whether if there are no idle instances of HTML5 Audio tag, - * for any particular sound, if one of the used tags should be hijacked and used - * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play - * call should be ignored. - * - * @name Phaser.Sound.HTML5AudioSoundManager#override - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.override = true; - - /** - * Value representing time difference, in seconds, between calling - * play method on an audio tag and when it actually starts playing. - * It is used to achieve more accurate delayed sound playback. - * - * You might need to tweak this value to get the desired results - * since audio play delay varies depending on the browser/platform. - * - * @name Phaser.Sound.HTML5AudioSoundManager#audioPlayDelay - * @type {number} - * @default 0.1 - * @since 3.0.0 - */ - this.audioPlayDelay = 0.1; - - /** - * A value by which we should offset the loop end marker of the - * looping sound to compensate for lag, caused by changing audio - * tag playback position, in order to achieve gapless looping. - * - * You might need to tweak this value to get the desired results - * since loop lag varies depending on the browser/platform. - * - * @name Phaser.Sound.HTML5AudioSoundManager#loopEndOffset - * @type {number} - * @default 0.05 - * @since 3.0.0 - */ - this.loopEndOffset = 0.05; - - /** - * An array for keeping track of all the sounds - * that were paused when game lost focus. - * - * @name Phaser.Sound.HTML5AudioSoundManager#onBlurPausedSounds - * @type {Phaser.Sound.HTML5AudioSound[]} - * @private - * @default [] - * @since 3.0.0 - */ - this.onBlurPausedSounds = []; - - this.locked = 'ontouchstart' in window; - - /** - * A queue of all actions performed on sound objects while audio was locked. - * Once the audio gets unlocked, after an explicit user interaction, - * all actions will be performed in chronological order. - * Array of object types: { sound: Phaser.Sound.HTML5AudioSound, name: string, value?: * } - * - * @name Phaser.Sound.HTML5AudioSoundManager#lockedActionsQueue - * @type {array} - * @private - * @since 3.0.0 - */ - this.lockedActionsQueue = this.locked ? [] : null; - - /** - * Property that actually holds the value of global mute - * for HTML5 Audio sound manager implementation. - * - * @name Phaser.Sound.HTML5AudioSoundManager#_mute - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._mute = false; - - /** - * Property that actually holds the value of global volume - * for HTML5 Audio sound manager implementation. - * - * @name Phaser.Sound.HTML5AudioSoundManager#_volume - * @type {boolean} - * @private - * @default 1 - * @since 3.0.0 - */ - this._volume = 1; - - BaseSoundManager.call(this, game); - }, - - /** - * Adds a new sound into the sound manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#add - * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. - * - * @return {Phaser.Sound.HTML5AudioSound} The new sound instance. - */ - add: function (key, config) - { - var sound = new HTML5AudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - /** - * Unlocks HTML5 Audio loading and playback on mobile - * devices on the initial explicit user interaction. - * - * @method Phaser.Sound.HTML5AudioSoundManager#unlock - * @since 3.0.0 - */ - unlock: function () - { - this.locked = false; - - var _this = this; - - this.game.cache.audio.entries.each(function (key, tags) - { - for (var i = 0; i < tags.length; i++) - { - if (tags[i].dataset.locked === 'true') - { - _this.locked = true; - - return false; - } - } - - return true; - }); - - if (!this.locked) - { - return; - } - - var moved = false; - - var detectMove = function () - { - moved = true; - }; - - var unlock = function () - { - if (moved) - { - moved = false; - return; - } - - document.body.removeEventListener('touchmove', detectMove); - document.body.removeEventListener('touchend', unlock); - - var lockedTags = []; - - _this.game.cache.audio.entries.each(function (key, tags) - { - for (var i = 0; i < tags.length; i++) - { - var tag = tags[i]; - - if (tag.dataset.locked === 'true') - { - lockedTags.push(tag); - } - } - - return true; - }); - - if (lockedTags.length === 0) - { - return; - } - - var lastTag = lockedTags[lockedTags.length - 1]; - - lastTag.oncanplaythrough = function () - { - lastTag.oncanplaythrough = null; - - lockedTags.forEach(function (tag) - { - tag.dataset.locked = 'false'; - }); - - _this.unlocked = true; - }; - - lockedTags.forEach(function (tag) - { - tag.load(); - }); - }; - - this.once(Events.UNLOCKED, function () - { - this.forEachActiveSound(function (sound) - { - if (sound.currentMarker === null && sound.duration === 0) - { - sound.duration = sound.tags[0].duration; - } - - sound.totalDuration = sound.tags[0].duration; - }); - - while (this.lockedActionsQueue.length) - { - var lockedAction = this.lockedActionsQueue.shift(); - - if (lockedAction.sound[lockedAction.prop].apply) - { - lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); - } - else - { - lockedAction.sound[lockedAction.prop] = lockedAction.value; - } - } - - }, this); - - document.body.addEventListener('touchmove', detectMove, false); - document.body.addEventListener('touchend', unlock, false); - }, - - /** - * Method used internally for pausing sound manager if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onBlur - * @protected - * @since 3.0.0 - */ - onBlur: function () - { - this.forEachActiveSound(function (sound) - { - if (sound.isPlaying) - { - this.onBlurPausedSounds.push(sound); - sound.onBlur(); - } - }); - }, - - /** - * Method used internally for resuming sound manager if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onFocus - * @protected - * @since 3.0.0 - */ - onFocus: function () - { - this.onBlurPausedSounds.forEach(function (sound) - { - sound.onFocus(); - }); - - this.onBlurPausedSounds.length = 0; - }, - - /** - * Calls Phaser.Sound.BaseSoundManager#destroy method - * and cleans up all HTML5 Audio related stuff. - * - * @method Phaser.Sound.HTML5AudioSoundManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSoundManager.prototype.destroy.call(this); - - this.onBlurPausedSounds.length = 0; - this.onBlurPausedSounds = null; - }, - - /** - * Method used internally by Phaser.Sound.HTML5AudioSound class methods and property setters - * to check if sound manager is locked and then either perform action immediately or queue it - * to be performed once the sound manager gets unlocked. - * - * @method Phaser.Sound.HTML5AudioSoundManager#isLocked - * @protected - * @since 3.0.0 - * - * @param {Phaser.Sound.HTML5AudioSound} sound - Sound object on which to perform queued action. - * @param {string} prop - Name of the method to be called or property to be assigned a value to. - * @param {*} [value] - An optional parameter that either holds an array of arguments to be passed to the method call or value to be set to the property. - * - * @return {boolean} Whether the sound manager is locked. - */ - isLocked: function (sound, prop, value) - { - if (sound.tags[0].dataset.locked === 'true') - { - this.lockedActionsQueue.push({ - sound: sound, - prop: prop, - value: value - }); - - return true; - } - - return false; - }, - - /** - * Sets the muted state of all this Sound Manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 - * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. - * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * @name Phaser.Sound.HTML5AudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return this._mute; - }, - - set: function (value) - { - this._mute = value; - - this.forEachActiveSound(function (sound) - { - sound.updateMute(); - }); - - this.emit(Events.GLOBAL_MUTE, this, value); - } - - }, - - /** - * Sets the volume of this Sound Manager. - * - * @method Phaser.Sound.HTML5AudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 - * - * @param {number} value - The global volume of this Sound Manager. - * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * @name Phaser.Sound.HTML5AudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this._volume; - }, - - set: function (value) - { - this._volume = value; - - this.forEachActiveSound(function (sound) - { - sound.updateVolume(); - }); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = HTML5AudioSoundManager; - - -/***/ }), -/* 406 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SafeRange = __webpack_require__(78); - -/** - * 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 {number} [startIndex=0] - An optional start index to search from. - * @param {number} [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; - - -/***/ }), -/* 407 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var Clamp = __webpack_require__(17); - -/** - * @classdesc - * HTML5 Audio implementation of the sound. - * - * @class HTML5AudioSound - * @extends Phaser.Sound.BaseSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.HTML5AudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var HTML5AudioSound = new Class({ - - Extends: BaseSound, - - initialize: - - function HTML5AudioSound (manager, key, config) - { - if (config === undefined) { config = {}; } - - /** - * An array containing all HTML5 Audio tags that could be used for individual - * sound's playback. Number of instances depends on the config value passed - * to the Loader#audio method call, default is 1. - * - * @name Phaser.Sound.HTML5AudioSound#tags - * @type {HTMLAudioElement[]} - * @private - * @since 3.0.0 - */ - this.tags = manager.game.cache.audio.get(key); - - if (!this.tags) - { - throw new Error('There is no audio asset with key "' + key + '" in the audio cache'); - } - - /** - * Reference to an HTML5 Audio tag used for playing sound. - * - * @name Phaser.Sound.HTML5AudioSound#audio - * @type {HTMLAudioElement} - * @private - * @default null - * @since 3.0.0 - */ - this.audio = null; - - /** - * Timestamp as generated by the Request Animation Frame or SetTimeout - * representing the time at which the delayed sound playback should start. - * Set to 0 if sound playback is not delayed. - * - * @name Phaser.Sound.HTML5AudioSound#startTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * Audio tag's playback position recorded on previous - * update method call. Set to 0 if sound is not playing. - * - * @name Phaser.Sound.HTML5AudioSound#previousTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.previousTime = 0; - - this.duration = this.tags[0].duration; - - this.totalDuration = this.tags[0].duration; - - BaseSound.call(this, manager, key, config); - }, - - /** - * Play this sound, or a marked section of it. - * It always plays the sound from the start. If you want to start playback from a specific time - * you can set 'seek' setting of the config object, provided to this call, to that value. - * - * @method Phaser.Sound.HTML5AudioSound#play - * @fires Phaser.Sound.Events#PLAY - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} Whether the sound started playing successfully. - */ - play: function (markerName, config) - { - if (this.manager.isLocked(this, 'play', [ markerName, config ])) - { - return false; - } - - if (!BaseSound.prototype.play.call(this, markerName, config)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - if (!this.pickAndPlayAudioTag()) - { - return false; - } - - this.emit(Events.PLAY, this); - - return true; - }, - - /** - * Pauses the sound. - * - * @method Phaser.Sound.HTML5AudioSound#pause - * @fires Phaser.Sound.Events#PAUSE - * @since 3.0.0 - * - * @return {boolean} Whether the sound was paused successfully. - */ - pause: function () - { - if (this.manager.isLocked(this, 'pause')) - { - return false; - } - - if (this.startTime > 0) - { - return false; - } - - if (!BaseSound.prototype.pause.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = true \/\/\/ - this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - - this.stopAndReleaseAudioTag(); - - this.emit(Events.PAUSE, this); - - return true; - }, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.HTML5AudioSound#resume - * @fires Phaser.Sound.Events#RESUME - * @since 3.0.0 - * - * @return {boolean} Whether the sound was resumed successfully. - */ - resume: function () - { - if (this.manager.isLocked(this, 'resume')) - { - return false; - } - - if (this.startTime > 0) - { - return false; - } - - if (!BaseSound.prototype.resume.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - if (!this.pickAndPlayAudioTag()) - { - return false; - } - - this.emit(Events.RESUME, this); - - return true; - }, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.HTML5AudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 - * - * @return {boolean} Whether the sound was stopped successfully. - */ - stop: function () - { - if (this.manager.isLocked(this, 'stop')) - { - return false; - } - - if (!BaseSound.prototype.stop.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndReleaseAudioTag(); - - this.emit(Events.STOP, this); - - return true; - }, - - /** - * Used internally to do what the name says. - * - * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag - * @private - * @since 3.0.0 - * - * @return {boolean} Whether the sound was assigned an audio tag successfully. - */ - pickAndPlayAudioTag: function () - { - if (!this.pickAudioTag()) - { - this.reset(); - return false; - } - - var seek = this.currentConfig.seek; - var delay = this.currentConfig.delay; - var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; - - this.previousTime = offset; - this.audio.currentTime = offset; - this.applyConfig(); - - if (delay === 0) - { - this.startTime = 0; - - if (this.audio.paused) - { - this.playCatchPromise(); - } - } - else - { - this.startTime = window.performance.now() + delay * 1000; - - if (!this.audio.paused) - { - this.audio.pause(); - } - } - - this.resetConfig(); - - return true; - }, - - /** - * This method performs the audio tag pooling logic. It first looks for - * unused audio tag to assign to this sound object. If there are no unused - * audio tags, based on HTML5AudioSoundManager#override property value, it - * looks for sound with most advanced playback and hijacks its audio tag or - * does nothing. - * - * @method Phaser.Sound.HTML5AudioSound#pickAudioTag - * @private - * @since 3.0.0 - * - * @return {boolean} Whether the sound was assigned an audio tag successfully. - */ - pickAudioTag: function () - { - if (this.audio) - { - return true; - } - - for (var i = 0; i < this.tags.length; i++) - { - var audio = this.tags[i]; - - if (audio.dataset.used === 'false') - { - audio.dataset.used = 'true'; - this.audio = audio; - return true; - } - } - - if (!this.manager.override) - { - return false; - } - - var otherSounds = []; - - this.manager.forEachActiveSound(function (sound) - { - if (sound.key === this.key && sound.audio) - { - otherSounds.push(sound); - } - }, this); - - otherSounds.sort(function (a1, a2) - { - if (a1.loop === a2.loop) - { - // sort by progress - return (a2.seek / a2.duration) - (a1.seek / a1.duration); - } - return a1.loop ? 1 : -1; - }); - - var selectedSound = otherSounds[0]; - - this.audio = selectedSound.audio; - - selectedSound.reset(); - selectedSound.audio = null; - selectedSound.startTime = 0; - selectedSound.previousTime = 0; - - return true; - }, - - /** - * Method used for playing audio tag and catching possible exceptions - * thrown from rejected Promise returned from play method call. - * - * @method Phaser.Sound.HTML5AudioSound#playCatchPromise - * @private - * @since 3.0.0 - */ - playCatchPromise: function () - { - var playPromise = this.audio.play(); - - if (playPromise) - { - // eslint-disable-next-line no-unused-vars - playPromise.catch(function (reason) - { - console.warn(reason); - }); - } - }, - - /** - * Used internally to do what the name says. - * - * @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag - * @private - * @since 3.0.0 - */ - stopAndReleaseAudioTag: function () - { - this.startTime = 0; - this.previousTime = 0; - - if (this.audio) - { - this.audio.pause(); - this.audio.dataset.used = 'false'; - this.audio = null; - } - }, - - /** - * Method used internally to reset sound state, usually when stopping sound - * or when hijacking audio tag from another sound. - * - * @method Phaser.Sound.HTML5AudioSound#reset - * @private - * @since 3.0.0 - */ - reset: function () - { - BaseSound.prototype.stop.call(this); - }, - - /** - * Method used internally by sound manager for pausing sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSoundManager#onBlur - * @private - * @since 3.0.0 - */ - onBlur: function () - { - this.isPlaying = false; - this.isPaused = true; - - this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - - this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); - - this.stopAndReleaseAudioTag(); - }, - - /** - * Method used internally by sound manager for resuming sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.HTML5AudioSound#onFocus - * @private - * @since 3.0.0 - */ - onFocus: function () - { - this.isPlaying = true; - this.isPaused = false; - this.pickAndPlayAudioTag(); - }, - - /** - * Update method called automatically by sound manager on every game step. - * - * @method Phaser.Sound.HTML5AudioSound#update - * @fires Phaser.Sound.Events#COMPLETE - * @fires Phaser.Sound.Events#LOOPED - * @protected - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - */ - update: function (time) - { - if (!this.isPlaying) - { - return; - } - - // handling delayed playback - if (this.startTime > 0) - { - if (this.startTime < time - this.manager.audioPlayDelay) - { - this.audio.currentTime += Math.max(0, time - this.startTime) / 1000; - this.startTime = 0; - this.previousTime = this.audio.currentTime; - this.playCatchPromise(); - } - - return; - } - - // handle looping and ending - var startTime = this.currentMarker ? this.currentMarker.start : 0; - var endTime = startTime + this.duration; - var currentTime = this.audio.currentTime; - - if (this.currentConfig.loop) - { - if (currentTime >= endTime - this.manager.loopEndOffset) - { - this.audio.currentTime = startTime + Math.max(0, currentTime - endTime); - currentTime = this.audio.currentTime; - } - else if (currentTime < startTime) - { - this.audio.currentTime += startTime; - currentTime = this.audio.currentTime; - } - - if (currentTime < this.previousTime) - { - this.emit(Events.LOOPED, this); - } - } - else if (currentTime >= endTime) - { - this.reset(); - - this.stopAndReleaseAudioTag(); - - this.emit(Events.COMPLETE, this); - - return; - } - - this.previousTime = currentTime; - }, - - /** - * Calls Phaser.Sound.BaseSound#destroy method - * and cleans up all HTML5 Audio related stuff. - * - * @method Phaser.Sound.HTML5AudioSound#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - - this.tags = null; - - if (this.audio) - { - this.stopAndReleaseAudioTag(); - } - }, - - /** - * Method used internally to determine mute setting of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#updateMute - * @private - * @since 3.0.0 - */ - updateMute: function () - { - if (this.audio) - { - this.audio.muted = this.currentConfig.mute || this.manager.mute; - } - }, - - /** - * Method used internally to calculate total volume of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#updateVolume - * @private - * @since 3.0.0 - */ - updateVolume: function () - { - if (this.audio) - { - this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1); - } - }, - - /** - * Method used internally to calculate total playback rate of the sound. - * - * @method Phaser.Sound.HTML5AudioSound#calculateRate - * @protected - * @since 3.0.0 - */ - calculateRate: function () - { - BaseSound.prototype.calculateRate.call(this); - - if (this.audio) - { - this.audio.playbackRate = this.totalRate; - } - }, - - /** - * Boolean indicating whether the sound is muted or not. - * Gets or sets the muted state of this sound. - * - * @name Phaser.Sound.HTML5AudioSound#mute - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return this.currentConfig.mute; - }, - - set: function (value) - { - this.currentConfig.mute = value; - - if (this.manager.isLocked(this, 'mute', value)) - { - return; - } - - this.updateMute(); - - this.emit(Events.MUTE, this, value); - } - }, - - /** - * Sets the muted state of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setMute - * @fires Phaser.Sound.Events#MUTE - * @since 3.4.0 - * - * @param {boolean} value - `true` to mute this sound, `false` to unmute it. - * - * @return {this} This Sound instance. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). - * - * @name Phaser.Sound.HTML5AudioSound#volume - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.currentConfig.volume; - }, - - set: function (value) - { - this.currentConfig.volume = value; - - if (this.manager.isLocked(this, 'volume', value)) - { - return; - } - - this.updateVolume(); - - this.emit(Events.VOLUME, this, value); - } - }, - - /** - * Sets the volume of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setVolume - * @fires Phaser.Sound.Events#VOLUME - * @since 3.4.0 - * - * @param {number} value - The volume of the sound. - * - * @return {this} This Sound instance. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * Rate at which this Sound will be played. - * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @name Phaser.Sound.HTML5AudioSound#rate - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#RATE - * @since 3.0.0 - */ - rate: { - - get: function () - { - return this.currentConfig.rate; - }, - - set: function (value) - { - this.currentConfig.rate = value; - - if (this.manager.isLocked(this, Events.RATE, value)) - { - return; - } - else - { - this.calculateRate(); - - this.emit(Events.RATE, this, value); - } - } - - }, - - /** - * Sets the playback rate of this Sound. - * - * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @method Phaser.Sound.HTML5AudioSound#setRate - * @fires Phaser.Sound.Events#RATE - * @since 3.3.0 - * - * @param {number} value - The playback rate at of this Sound. - * - * @return {this} This Sound instance. - */ - setRate: function (value) - { - this.rate = value; - - return this; - }, - - /** - * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @name Phaser.Sound.HTML5AudioSound#detune - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#DETUNE - * @since 3.0.0 - */ - detune: { - - get: function () - { - return this.currentConfig.detune; - }, - - set: function (value) - { - this.currentConfig.detune = value; - - if (this.manager.isLocked(this, Events.DETUNE, value)) - { - return; - } - else - { - this.calculateRate(); - - this.emit(Events.DETUNE, this, value); - } - } - - }, - - /** - * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @method Phaser.Sound.HTML5AudioSound#setDetune - * @fires Phaser.Sound.Events#DETUNE - * @since 3.3.0 - * - * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @return {this} This Sound instance. - */ - setDetune: function (value) - { - this.detune = value; - - return this; - }, - - /** - * Property representing the position of playback for this sound, in seconds. - * Setting it to a specific value moves current playback to that position. - * The value given is clamped to the range 0 to current marker duration. - * Setting seek of a stopped sound has no effect. - * - * @name Phaser.Sound.HTML5AudioSound#seek - * @type {number} - * @fires Phaser.Sound.Events#SEEK - * @since 3.0.0 - */ - seek: { - - get: function () - { - if (this.isPlaying) - { - return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); - } - else if (this.isPaused) - { - return this.currentConfig.seek; - } - else - { - return 0; - } - }, - - set: function (value) - { - if (this.manager.isLocked(this, 'seek', value)) - { - return; - } - - if (this.startTime > 0) - { - return; - } - - if (this.isPlaying || this.isPaused) - { - value = Math.min(Math.max(0, value), this.duration); - - if (this.isPlaying) - { - this.previousTime = value; - this.audio.currentTime = value; - } - else if (this.isPaused) - { - this.currentConfig.seek = value; - } - - this.emit(Events.SEEK, this, value); - } - } - }, - - /** - * Seeks to a specific point in this sound. - * - * @method Phaser.Sound.HTML5AudioSound#setSeek - * @fires Phaser.Sound.Events#SEEK - * @since 3.4.0 - * - * @param {number} value - The point in the sound to seek to. - * - * @return {this} This Sound instance. - */ - setSeek: function (value) - { - this.seek = value; - - return this; - }, - - /** - * Flag indicating whether or not the sound or current sound marker will loop. - * - * @name Phaser.Sound.HTML5AudioSound#loop - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#LOOP - * @since 3.0.0 - */ - loop: { - - get: function () - { - return this.currentConfig.loop; - }, - - set: function (value) - { - this.currentConfig.loop = value; - - if (this.manager.isLocked(this, 'loop', value)) - { - return; - } - - if (this.audio) - { - this.audio.loop = value; - } - - this.emit(Events.LOOP, this, value); - } - - }, - - /** - * Sets the loop state of this Sound. - * - * @method Phaser.Sound.HTML5AudioSound#setLoop - * @fires Phaser.Sound.Events#LOOP - * @since 3.4.0 - * - * @param {boolean} value - `true` to loop this sound, `false` to not loop it. - * - * @return {Phaser.Sound.HTML5AudioSound} This Sound instance. - */ - setLoop: function (value) - { - this.loop = value; - - return this; - }, - - /** - * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. - * - * @name Phaser.Sound.HTML5AudioSound#pan - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - */ - pan: { - - get: function () - { - return this.currentConfig.pan; - }, - - set: function (value) - { - this.currentConfig.pan = value; - - this.emit(Events.PAN, this, value); - } - }, - - /** - * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. - * - * @method Phaser.Sound.HTML5AudioSound#setPan - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - * - * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). - * - * @return {this} This Sound instance. - */ - setPan: function (value) - { - this.pan = value; - - return this; - } - -}); - -module.exports = HTML5AudioSound; - - -/***/ }), -/* 408 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var NoAudioSound = __webpack_require__(409); -var NOOP = __webpack_require__(1); - -/** - * @classdesc - * No-audio implementation of the Sound Manager. It is used if audio has been - * disabled in the game config or the device doesn't support any audio. - * - * It represents a graceful degradation of Sound Manager logic that provides - * minimal functionality and prevents Phaser projects that use audio from - * breaking on devices that don't support any audio playback technologies. - * - * @class NoAudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var NoAudioSoundManager = new Class({ - - Extends: EventEmitter, - - initialize: - - function NoAudioSoundManager (game) - { - EventEmitter.call(this); - - this.game = game; - this.sounds = []; - this.mute = false; - this.volume = 1; - this.rate = 1; - this.detune = 0; - this.pauseOnBlur = true; - this.locked = false; - }, - - add: function (key, config) - { - var sound = new NoAudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - addAudioSprite: function (key, config) - { - var sound = this.add(key, config); - - sound.spritemap = {}; - - return sound; - }, - - // eslint-disable-next-line no-unused-vars - play: function (key, extra) - { - return false; - }, - - // eslint-disable-next-line no-unused-vars - playAudioSprite: function (key, spriteName, config) - { - return false; - }, - - remove: function (sound) - { - return BaseSoundManager.prototype.remove.call(this, sound); - }, - - removeByKey: function (key) - { - return BaseSoundManager.prototype.removeByKey.call(this, key); - }, - - pauseAll: NOOP, - resumeAll: NOOP, - stopAll: NOOP, - update: NOOP, - setRate: NOOP, - setDetune: NOOP, - setMute: NOOP, - setVolume: NOOP, - - forEachActiveSound: function (callbackfn, scope) - { - BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); - }, - - destroy: function () - { - BaseSoundManager.prototype.destroy.call(this); - } - -}); - -module.exports = NoAudioSoundManager; - - -/***/ }), -/* 409 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Extend = __webpack_require__(19); - -var returnFalse = function () -{ - return false; -}; - -var returnNull = function () -{ - return null; -}; - -var returnThis = function () -{ - return this; -}; - -/** - * @classdesc - * No audio implementation of the sound. It is used if audio has been - * disabled in the game config or the device doesn't support any audio. - * - * It represents a graceful degradation of sound logic that provides - * minimal functionality and prevents Phaser projects that use audio from - * breaking on devices that don't support any audio playback technologies. - * - * @class NoAudioSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.NoAudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var NoAudioSound = new Class({ - - Extends: EventEmitter, - - initialize: - - function NoAudioSound (manager, key, config) - { - if (config === void 0) { config = {}; } - - EventEmitter.call(this); - - this.manager = manager; - this.key = key; - this.isPlaying = false; - this.isPaused = false; - this.totalRate = 1; - this.duration = 0; - this.totalDuration = 0; - - this.config = Extend({ - mute: false, - volume: 1, - rate: 1, - detune: 0, - seek: 0, - loop: false, - delay: 0, - pan: 0 - }, config); - - this.currentConfig = this.config; - this.mute = false; - this.volume = 1; - this.rate = 1; - this.detune = 0; - this.seek = 0; - this.loop = false; - this.pan = 0; - this.markers = {}; - this.currentMarker = null; - this.pendingRemove = false; - }, - - /** - * @method Phaser.Sound.NoAudioSound#addMarker - * @since 3.0.0 - * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. - * - * @return {boolean} false - */ - addMarker: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#updateMarker - * @since 3.0.0 - * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. - * - * @return {boolean} false - */ - updateMarker: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#removeMarker - * @since 3.0.0 - * - * @param {string} markerName - The name of the marker to remove. - * - * @return {null} null - */ - removeMarker: returnNull, - - /** - * @method Phaser.Sound.NoAudioSound#play - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} false - */ - play: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#pause - * @since 3.0.0 - * - * @return {boolean} false - */ - pause: returnFalse, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.NoAudioSound#resume - * @since 3.0.0 - * - * @return {boolean} false - */ - resume: returnFalse, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.NoAudioSound#stop - * @since 3.0.0 - * - * @return {boolean} false - */ - stop: returnFalse, - - /** - * Destroys this sound and all associated events and marks it for removal from the sound manager. - * - * @method Phaser.Sound.NoAudioSound#destroy - * @fires Phaser.Sound.Events#DESTROY - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - }, - - setMute: returnThis, - - setVolume: returnThis, - - setRate: returnThis, - - setDetune: returnThis, - - setSeek: returnThis, - - setLoop: returnThis, - - setPan: returnThis - -}); - -module.exports = NoAudioSound; - - -/***/ }), -/* 410 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Base64ToArrayBuffer = __webpack_require__(411); -var BaseSoundManager = __webpack_require__(143); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); -var GameEvents = __webpack_require__(22); -var WebAudioSound = __webpack_require__(412); - -/** - * @classdesc - * Web Audio API implementation of the Sound Manager. - * - * Not all browsers can play all audio formats. - * - * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). - * - * @class WebAudioSoundManager - * @extends Phaser.Sound.BaseSoundManager - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - */ -var WebAudioSoundManager = new Class({ - - Extends: BaseSoundManager, - - initialize: - - function WebAudioSoundManager (game) - { - /** - * The AudioContext being used for playback. - * - * @name Phaser.Sound.WebAudioSoundManager#context - * @type {AudioContext} - * @private - * @since 3.0.0 - */ - this.context = this.createAudioContext(game); - - /** - * Gain node responsible for controlling global muting. - * - * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.masterMuteNode = this.context.createGain(); - - /** - * Gain node responsible for controlling global volume. - * - * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.masterVolumeNode = this.context.createGain(); - - this.masterMuteNode.connect(this.masterVolumeNode); - - this.masterVolumeNode.connect(this.context.destination); - - /** - * Destination node for connecting individual sounds to. - * - * @name Phaser.Sound.WebAudioSoundManager#destination - * @type {AudioNode} - * @private - * @since 3.0.0 - */ - this.destination = this.masterMuteNode; - - this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); - - BaseSoundManager.call(this, game); - - if (this.locked && game.isBooted) - { - this.unlock(); - } - else - { - game.events.once(GameEvents.BOOT, this.unlock, this); - } - }, - - /** - * Method responsible for instantiating and returning AudioContext instance. - * If an instance of an AudioContext class was provided through the game config, - * that instance will be returned instead. This can come in handy if you are reloading - * a Phaser game on a page that never properly refreshes (such as in an SPA project) - * and you want to reuse already instantiated AudioContext. - * - * @method Phaser.Sound.WebAudioSoundManager#createAudioContext - * @private - * @since 3.0.0 - * - * @param {Phaser.Game} game - Reference to the current game instance. - * - * @return {AudioContext} The AudioContext instance to be used for playback. - */ - createAudioContext: function (game) - { - var audioConfig = game.config.audio; - - if (audioConfig.context) - { - audioConfig.context.resume(); - - return audioConfig.context; - } - - return new AudioContext(); - }, - - /** - * This method takes a new AudioContext reference and then sets - * this Sound Manager to use that context for all playback. - * - * As part of this call it also disconnects the master mute and volume - * nodes and then re-creates them on the new given context. - * - * @method Phaser.Sound.WebAudioSoundManager#setAudioContext - * @since 3.21.0 - * - * @param {AudioContext} context - Reference to an already created AudioContext instance. - * - * @return {this} The WebAudioSoundManager instance. - */ - setAudioContext: function (context) - { - if (this.context) - { - this.context.close(); - } - - if (this.masterMuteNode) - { - this.masterMuteNode.disconnect(); - } - - if (this.masterVolumeNode) - { - this.masterVolumeNode.disconnect(); - } - - this.context = context; - - this.masterMuteNode = context.createGain(); - this.masterVolumeNode = context.createGain(); - - this.masterMuteNode.connect(this.masterVolumeNode); - this.masterVolumeNode.connect(context.destination); - - this.destination = this.masterMuteNode; - - return this; - }, - - /** - * Adds a new sound into the sound manager. - * - * @method Phaser.Sound.WebAudioSoundManager#add - * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. - * - * @return {Phaser.Sound.WebAudioSound} The new sound instance. - */ - add: function (key, config) - { - var sound = new WebAudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, - - /** - * Decode audio data into a format ready for playback via Web Audio. - * - * The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. - * - * The `audioKey` is the key that will be used to save the decoded audio to the audio cache. - * - * Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig` - * objects as the first and only argument. - * - * Decoding is an async process, so be sure to listen for the events to know when decoding has completed. - * - * Once the audio has decoded it can be added to the Sound Manager or played via its key. - * - * @method Phaser.Sound.WebAudioSoundManager#decodeAudio - * @fires Phaser.Sound.Events#DECODED - * @fires Phaser.Sound.Events#DECODED_ALL - * @since 3.18.0 - * - * @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects. - * @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. - */ - decodeAudio: function (audioKey, audioData) - { - var audioFiles; - - if (!Array.isArray(audioKey)) - { - audioFiles = [ { key: audioKey, data: audioData } ]; - } - else - { - audioFiles = audioKey; - } - - var cache = this.game.cache.audio; - var remaining = audioFiles.length; - - for (var i = 0; i < audioFiles.length; i++) - { - var entry = audioFiles[i]; - - var key = entry.key; - var data = entry.data; - - if (typeof data === 'string') - { - data = Base64ToArrayBuffer(data); - } - - var success = function (key, audioBuffer) - { - cache.add(key, audioBuffer); - - this.emit(Events.DECODED, key); - - remaining--; - - if (remaining === 0) - { - this.emit(Events.DECODED_ALL); - } - }.bind(this, key); - - var failure = function (key, error) - { - // eslint-disable-next-line no-console - console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); - - remaining--; - - if (remaining === 0) - { - this.emit(Events.DECODED_ALL); - } - }.bind(this, key); - - this.context.decodeAudioData(data, success, failure); - } - }, - - /** - * Unlocks Web Audio API on the initial input event. - * - * Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09). - * - * @method Phaser.Sound.WebAudioSoundManager#unlock - * @since 3.0.0 - */ - unlock: function () - { - var _this = this; - - var body = document.body; - - var unlockHandler = function unlockHandler () - { - if (_this.context) - { - _this.context.resume().then(function () - { - body.removeEventListener('touchstart', unlockHandler); - body.removeEventListener('touchend', unlockHandler); - body.removeEventListener('click', unlockHandler); - body.removeEventListener('keydown', unlockHandler); - - _this.unlocked = true; - }, function () - { - body.removeEventListener('touchstart', unlockHandler); - body.removeEventListener('touchend', unlockHandler); - body.removeEventListener('click', unlockHandler); - body.removeEventListener('keydown', unlockHandler); - }); - } - }; - - if (body) - { - body.addEventListener('touchstart', unlockHandler, false); - body.addEventListener('touchend', unlockHandler, false); - body.addEventListener('click', unlockHandler, false); - body.addEventListener('keydown', unlockHandler, false); - } - }, - - /** - * Method used internally for pausing sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.WebAudioSoundManager#onBlur - * @protected - * @since 3.0.0 - */ - onBlur: function () - { - if (!this.locked) - { - this.context.suspend(); - } - }, - - /** - * Method used internally for resuming sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.WebAudioSoundManager#onFocus - * @protected - * @since 3.0.0 - */ - onFocus: function () - { - if (!this.locked) - { - this.context.resume(); - } - }, - - /** - * Calls Phaser.Sound.BaseSoundManager#destroy method - * and cleans up all Web Audio API related stuff. - * - * @method Phaser.Sound.WebAudioSoundManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.destination = null; - this.masterVolumeNode.disconnect(); - this.masterVolumeNode = null; - this.masterMuteNode.disconnect(); - this.masterMuteNode = null; - - if (this.game.config.audio.context) - { - this.context.suspend(); - } - else - { - var _this = this; - - this.context.close().then(function () - { - _this.context = null; - }); - } - - BaseSoundManager.prototype.destroy.call(this); - }, - - /** - * Sets the muted state of all this Sound Manager. - * - * @method Phaser.Sound.WebAudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 - * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. - * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * @name Phaser.Sound.WebAudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return (this.masterMuteNode.gain.value === 0); - }, - - set: function (value) - { - this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0); - - this.emit(Events.GLOBAL_MUTE, this, value); - } - - }, - - /** - * Sets the volume of this Sound Manager. - * - * @method Phaser.Sound.WebAudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 - * - * @param {number} value - The global volume of this Sound Manager. - * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * @name Phaser.Sound.WebAudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.masterVolumeNode.gain.value; - }, - - set: function (value) - { - this.masterVolumeNode.gain.setValueAtTime(value, 0); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = WebAudioSoundManager; - - -/***/ }), -/* 411 */ -/***/ (function(module, exports) { - -/** - * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -// Use a lookup table to find the index. -var lookup = new Uint8Array(256); - -for (var i = 0; i < chars.length; i++) -{ - lookup[chars.charCodeAt(i)] = i; -} - -/** - * Converts a base64 string, either with or without a data uri, into an Array Buffer. - * - * @function Phaser.Utils.Base64.Base64ToArrayBuffer - * @since 3.18.0 - * - * @param {string} base64 - The base64 string to be decoded. Can optionally contain a data URI header, which will be stripped out prior to decoding. - * - * @return {ArrayBuffer} An ArrayBuffer decoded from the base64 data. - */ -var Base64ToArrayBuffer = function (base64) -{ - // Is it a data uri? if so, strip the header away - base64 = base64.substr(base64.indexOf(',') + 1); - - var len = base64.length; - var bufferLength = len * 0.75; - var p = 0; - var encoded1; - var encoded2; - var encoded3; - var encoded4; - - if (base64[len - 1] === '=') - { - bufferLength--; - - if (base64[len - 2] === '=') - { - bufferLength--; - } - } - - var arrayBuffer = new ArrayBuffer(bufferLength); - var bytes = new Uint8Array(arrayBuffer); - - for (var i = 0; i < len; i += 4) - { - encoded1 = lookup[base64.charCodeAt(i)]; - encoded2 = lookup[base64.charCodeAt(i + 1)]; - encoded3 = lookup[base64.charCodeAt(i + 2)]; - encoded4 = lookup[base64.charCodeAt(i + 3)]; - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } - - return arrayBuffer; -}; - -module.exports = Base64ToArrayBuffer; - - -/***/ }), -/* 412 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseSound = __webpack_require__(144); -var Class = __webpack_require__(0); -var Events = __webpack_require__(68); - -/** - * @classdesc - * Web Audio API implementation of the sound. - * - * @class WebAudioSound - * @extends Phaser.Sound.BaseSound - * @memberof Phaser.Sound - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Sound.WebAudioSoundManager} manager - Reference to the current sound manager instance. - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. - */ -var WebAudioSound = new Class({ - - Extends: BaseSound, - - initialize: - - function WebAudioSound (manager, key, config) - { - if (config === undefined) { config = {}; } - - /** - * Audio buffer containing decoded data of the audio asset to be played. - * - * @name Phaser.Sound.WebAudioSound#audioBuffer - * @type {AudioBuffer} - * @private - * @since 3.0.0 - */ - this.audioBuffer = manager.game.cache.audio.get(key); - - if (!this.audioBuffer) - { - throw new Error('Audio key "' + key + '" missing from cache'); - } - - /** - * A reference to an audio source node used for playing back audio from - * audio data stored in Phaser.Sound.WebAudioSound#audioBuffer. - * - * @name Phaser.Sound.WebAudioSound#source - * @type {AudioBufferSourceNode} - * @private - * @default null - * @since 3.0.0 - */ - this.source = null; - - /** - * A reference to a second audio source used for gapless looped playback. - * - * @name Phaser.Sound.WebAudioSound#loopSource - * @type {AudioBufferSourceNode} - * @private - * @default null - * @since 3.0.0 - */ - this.loopSource = null; - - /** - * Gain node responsible for controlling this sound's muting. - * - * @name Phaser.Sound.WebAudioSound#muteNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.muteNode = manager.context.createGain(); - - /** - * Gain node responsible for controlling this sound's volume. - * - * @name Phaser.Sound.WebAudioSound#volumeNode - * @type {GainNode} - * @private - * @since 3.0.0 - */ - this.volumeNode = manager.context.createGain(); - - /** - * Panner node responsible for controlling this sound's pan. - * - * @name Phaser.Sound.WebAudioSound#pannerNode - * @type {StereoPannerNode} - * @private - * @since 3.50.0 - */ - this.pannerNode = manager.context.createStereoPanner(); - - /** - * The time at which the sound should have started playback from the beginning. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#playTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.playTime = 0; - - /** - * The time at which the sound source should have actually started playback. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#startTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.startTime = 0; - - /** - * The time at which the sound loop source should actually start playback. - * Based on BaseAudioContext.currentTime value. - * - * @name Phaser.Sound.WebAudioSound#loopTime - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.loopTime = 0; - - /** - * An array where we keep track of all rate updates during playback. - * Array of object types: { time: number, rate: number } - * - * @name Phaser.Sound.WebAudioSound#rateUpdates - * @type {array} - * @private - * @default [] - * @since 3.0.0 - */ - this.rateUpdates = []; - - /** - * Used for keeping track when sound source playback has ended - * so its state can be updated accordingly. - * - * @name Phaser.Sound.WebAudioSound#hasEnded - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this.hasEnded = false; - - /** - * Used for keeping track when sound source has looped - * so its state can be updated accordingly. - * - * @name Phaser.Sound.WebAudioSound#hasLooped - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this.hasLooped = false; - - this.muteNode.connect(this.volumeNode); - - this.volumeNode.connect(this.pannerNode); - - this.pannerNode.connect(manager.destination); - - this.duration = this.audioBuffer.duration; - - this.totalDuration = this.audioBuffer.duration; - - BaseSound.call(this, manager, key, config); - }, - - /** - * Play this sound, or a marked section of it. - * - * It always plays the sound from the start. If you want to start playback from a specific time - * you can set 'seek' setting of the config object, provided to this call, to that value. - * - * @method Phaser.Sound.WebAudioSound#play - * @fires Phaser.Sound.Events#PLAY - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. - * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. - * - * @return {boolean} Whether the sound started playing successfully. - */ - play: function (markerName, config) - { - if (!BaseSound.prototype.play.call(this, markerName, config)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - this.stopAndRemoveBufferSource(); - this.createAndStartBufferSource(); - - this.emit(Events.PLAY, this); - - return true; - }, - - /** - * Pauses the sound. - * - * @method Phaser.Sound.WebAudioSound#pause - * @fires Phaser.Sound.Events#PAUSE - * @since 3.0.0 - * - * @return {boolean} Whether the sound was paused successfully. - */ - pause: function () - { - if (this.manager.context.currentTime < this.startTime) - { - return false; - } - - if (!BaseSound.prototype.pause.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = true \/\/\/ - this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time - this.stopAndRemoveBufferSource(); - - this.emit(Events.PAUSE, this); - - return true; - }, - - /** - * Resumes the sound. - * - * @method Phaser.Sound.WebAudioSound#resume - * @fires Phaser.Sound.Events#RESUME - * @since 3.0.0 - * - * @return {boolean} Whether the sound was resumed successfully. - */ - resume: function () - { - if (this.manager.context.currentTime < this.startTime) - { - return false; - } - - if (!BaseSound.prototype.resume.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - this.createAndStartBufferSource(); - - this.emit(Events.RESUME, this); - - return true; - }, - - /** - * Stop playing this sound. - * - * @method Phaser.Sound.WebAudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 - * - * @return {boolean} Whether the sound was stopped successfully. - */ - stop: function () - { - if (!BaseSound.prototype.stop.call(this)) - { - return false; - } - - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndRemoveBufferSource(); - - this.emit(Events.STOP, this); - - return true; - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createAndStartBufferSource - * @private - * @since 3.0.0 - */ - createAndStartBufferSource: function () - { - var seek = this.currentConfig.seek; - var delay = this.currentConfig.delay; - var when = this.manager.context.currentTime + delay; - var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; - var duration = this.duration - seek; - - this.playTime = when - seek; - this.startTime = when; - this.source = this.createBufferSource(); - - this.applyConfig(); - - this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); - - this.resetConfig(); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource - * @private - * @since 3.0.0 - */ - createAndStartLoopBufferSource: function () - { - var when = this.getLoopTime(); - var offset = this.currentMarker ? this.currentMarker.start : 0; - var duration = this.duration; - - this.loopTime = when; - this.loopSource = this.createBufferSource(); - this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0); - this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#createBufferSource - * @private - * @since 3.0.0 - * - * @return {AudioBufferSourceNode} - */ - createBufferSource: function () - { - var _this = this; - var source = this.manager.context.createBufferSource(); - - source.buffer = this.audioBuffer; - - source.connect(this.muteNode); - - source.onended = function (ev) - { - if (ev.target === _this.source) - { - // sound ended - if (_this.currentConfig.loop) - { - _this.hasLooped = true; - } - else - { - _this.hasEnded = true; - } - } - - // else was stopped - }; - - return source; - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource - * @private - * @since 3.0.0 - */ - stopAndRemoveBufferSource: function () - { - if (this.source) - { - this.source.stop(); - this.source.disconnect(); - this.source = null; - } - - this.playTime = 0; - this.startTime = 0; - - this.stopAndRemoveLoopBufferSource(); - }, - - /** - * Used internally. - * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource - * @private - * @since 3.0.0 - */ - stopAndRemoveLoopBufferSource: function () - { - if (this.loopSource) - { - this.loopSource.stop(); - this.loopSource.disconnect(); - this.loopSource = null; - } - - this.loopTime = 0; - }, - - /** - * Method used internally for applying config values to some of the sound properties. - * - * @method Phaser.Sound.WebAudioSound#applyConfig - * @protected - * @since 3.0.0 - */ - applyConfig: function () - { - this.rateUpdates.length = 0; - - this.rateUpdates.push({ - time: 0, - rate: 1 - }); - - BaseSound.prototype.applyConfig.call(this); - }, - - /** - * Update method called automatically by sound manager on every game step. - * - * @method Phaser.Sound.WebAudioSound#update - * @fires Phaser.Sound.Events#COMPLETE - * @fires Phaser.Sound.Events#LOOPED - * @protected - * @since 3.0.0 - */ - update: function () - { - if (this.hasEnded) - { - this.hasEnded = false; - - BaseSound.prototype.stop.call(this); - - this.stopAndRemoveBufferSource(); - - this.emit(Events.COMPLETE, this); - } - else if (this.hasLooped) - { - this.hasLooped = false; - this.source = this.loopSource; - this.loopSource = null; - this.playTime = this.startTime = this.loopTime; - this.rateUpdates.length = 0; - - this.rateUpdates.push({ - time: 0, - rate: this.totalRate - }); - - this.createAndStartLoopBufferSource(); - - this.emit(Events.LOOPED, this); - } - }, - - /** - * Calls Phaser.Sound.BaseSound#destroy method - * and cleans up all Web Audio API related stuff. - * - * @method Phaser.Sound.WebAudioSound#destroy - * @since 3.0.0 - */ - destroy: function () - { - BaseSound.prototype.destroy.call(this); - - this.audioBuffer = null; - this.stopAndRemoveBufferSource(); - this.muteNode.disconnect(); - this.muteNode = null; - this.volumeNode.disconnect(); - this.volumeNode = null; - this.pannerNode.disconnect(); - this.pannerNode = null; - this.rateUpdates.length = 0; - this.rateUpdates = null; - }, - - /** - * Method used internally to calculate total playback rate of the sound. - * - * @method Phaser.Sound.WebAudioSound#calculateRate - * @protected - * @since 3.0.0 - */ - calculateRate: function () - { - BaseSound.prototype.calculateRate.call(this); - - var now = this.manager.context.currentTime; - - if (this.source && typeof this.totalRate === 'number') - { - this.source.playbackRate.setValueAtTime(this.totalRate, now); - } - - if (this.isPlaying) - { - this.rateUpdates.push({ - time: Math.max(this.startTime, now) - this.playTime, - rate: this.totalRate - }); - - if (this.loopSource) - { - this.stopAndRemoveLoopBufferSource(); - this.createAndStartLoopBufferSource(); - } - } - }, - - /** - * Method used internally for calculating current playback time of a playing sound. - * - * @method Phaser.Sound.WebAudioSound#getCurrentTime - * @private - * @since 3.0.0 - */ - getCurrentTime: function () - { - var currentTime = 0; - - for (var i = 0; i < this.rateUpdates.length; i++) - { - var nextTime = 0; - - if (i < this.rateUpdates.length - 1) - { - nextTime = this.rateUpdates[i + 1].time; - } - else - { - nextTime = this.manager.context.currentTime - this.playTime; - } - - currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate; - } - - return currentTime; - }, - - /** - * Method used internally for calculating the time - * at witch the loop source should start playing. - * - * @method Phaser.Sound.WebAudioSound#getLoopTime - * @private - * @since 3.0.0 - */ - getLoopTime: function () - { - var lastRateUpdateCurrentTime = 0; - - for (var i = 0; i < this.rateUpdates.length - 1; i++) - { - lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; - } - - var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1]; - - return this.playTime + lastRateUpdate.time + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate; - }, - - /** - * Rate at which this Sound will be played. - * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @name Phaser.Sound.WebAudioSound#rate - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#RATE - * @since 3.0.0 - */ - rate: { - - get: function () - { - return this.currentConfig.rate; - }, - - set: function (value) - { - this.currentConfig.rate = value; - - this.calculateRate(); - - this.emit(Events.RATE, this, value); - } - - }, - - /** - * Sets the playback rate of this Sound. - * - * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed - * and 2.0 doubles the audios playback speed. - * - * @method Phaser.Sound.WebAudioSound#setRate - * @fires Phaser.Sound.Events#RATE - * @since 3.3.0 - * - * @param {number} value - The playback rate at of this Sound. - * - * @return {this} This Sound instance. - */ - setRate: function (value) - { - this.rate = value; - - return this; - }, - - /** - * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @name Phaser.Sound.WebAudioSound#detune - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#DETUNE - * @since 3.0.0 - */ - detune: { - - get: function () - { - return this.currentConfig.detune; - }, - - set: function (value) - { - this.currentConfig.detune = value; - - this.calculateRate(); - - this.emit(Events.DETUNE, this, value); - } - - }, - - /** - * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). - * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @method Phaser.Sound.WebAudioSound#setDetune - * @fires Phaser.Sound.Events#DETUNE - * @since 3.3.0 - * - * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). - * - * @return {this} This Sound instance. - */ - setDetune: function (value) - { - this.detune = value; - - return this; - }, - - /** - * Boolean indicating whether the sound is muted or not. - * Gets or sets the muted state of this sound. - * - * @name Phaser.Sound.WebAudioSound#mute - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#MUTE - * @since 3.0.0 - */ - mute: { - - get: function () - { - return (this.muteNode.gain.value === 0); - }, - - set: function (value) - { - this.currentConfig.mute = value; - this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0); - - this.emit(Events.MUTE, this, value); - } - - }, - - /** - * Sets the muted state of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setMute - * @fires Phaser.Sound.Events#MUTE - * @since 3.4.0 - * - * @param {boolean} value - `true` to mute this sound, `false` to unmute it. - * - * @return {this} This Sound instance. - */ - setMute: function (value) - { - this.mute = value; - - return this; - }, - - /** - * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). - * - * @name Phaser.Sound.WebAudioSound#volume - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#VOLUME - * @since 3.0.0 - */ - volume: { - - get: function () - { - return this.volumeNode.gain.value; - }, - - set: function (value) - { - this.currentConfig.volume = value; - this.volumeNode.gain.setValueAtTime(value, 0); - - this.emit(Events.VOLUME, this, value); - } - }, - - /** - * Sets the volume of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setVolume - * @fires Phaser.Sound.Events#VOLUME - * @since 3.4.0 - * - * @param {number} value - The volume of the sound. - * - * @return {this} This Sound instance. - */ - setVolume: function (value) - { - this.volume = value; - - return this; - }, - - /** - * Property representing the position of playback for this sound, in seconds. - * Setting it to a specific value moves current playback to that position. - * The value given is clamped to the range 0 to current marker duration. - * Setting seek of a stopped sound has no effect. - * - * @name Phaser.Sound.WebAudioSound#seek - * @type {number} - * @fires Phaser.Sound.Events#SEEK - * @since 3.0.0 - */ - seek: { - - get: function () - { - if (this.isPlaying) - { - if (this.manager.context.currentTime < this.startTime) - { - return this.startTime - this.playTime; - } - - return this.getCurrentTime(); - } - else if (this.isPaused) - { - return this.currentConfig.seek; - } - else - { - return 0; - } - }, - - set: function (value) - { - if (this.manager.context.currentTime < this.startTime) - { - return; - } - - if (this.isPlaying || this.isPaused) - { - value = Math.min(Math.max(0, value), this.duration); - - this.currentConfig.seek = value; - - if (this.isPlaying) - { - this.stopAndRemoveBufferSource(); - this.createAndStartBufferSource(); - } - - this.emit(Events.SEEK, this, value); - } - } - }, - - /** - * Seeks to a specific point in this sound. - * - * @method Phaser.Sound.WebAudioSound#setSeek - * @fires Phaser.Sound.Events#SEEK - * @since 3.4.0 - * - * @param {number} value - The point in the sound to seek to. - * - * @return {this} This Sound instance. - */ - setSeek: function (value) - { - this.seek = value; - - return this; - }, - - /** - * Flag indicating whether or not the sound or current sound marker will loop. - * - * @name Phaser.Sound.WebAudioSound#loop - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#LOOP - * @since 3.0.0 - */ - loop: { - - get: function () - { - return this.currentConfig.loop; - }, - - set: function (value) - { - this.currentConfig.loop = value; - - if (this.isPlaying) - { - this.stopAndRemoveLoopBufferSource(); - - if (value) - { - this.createAndStartLoopBufferSource(); - } - } - - this.emit(Events.LOOP, this, value); - } - }, - - /** - * Sets the loop state of this Sound. - * - * @method Phaser.Sound.WebAudioSound#setLoop - * @fires Phaser.Sound.Events#LOOP - * @since 3.4.0 - * - * @param {boolean} value - `true` to loop this sound, `false` to not loop it. - * - * @return {this} This Sound instance. - */ - setLoop: function (value) - { - this.loop = value; - - return this; - }, - - /** - * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * @name Phaser.Sound.WebAudioSound#pan - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - */ - pan: { - - get: function () - { - return this.pannerNode.pan.value; - }, - - set: function (value) - { - this.currentConfig.pan = value; - this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime); - - this.emit(Events.PAN, this, value); - } - }, - - /** - * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). - * - * @method Phaser.Sound.WebAudioSound#setPan - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 - * - * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). - * - * @return {this} This Sound instance. - */ - setPan: function (value) - { - this.pan = value; - - return this; - } - -}); - -module.exports = WebAudioSound; - - -/***/ }), -/* 413 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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; - - -/***/ }), -/* 414 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @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 {number} k - The k-th element index. - * @param {number} [left=0] - The index of the left part of the range. - * @param {number} [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; - - -/***/ }), -/* 415 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetValue = __webpack_require__(6); -var Shuffle = __webpack_require__(129); - -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; - - -/***/ }), -/* 416 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Structs.Events - */ - -module.exports = { - - PROCESS_QUEUE_ADD: __webpack_require__(1035), - PROCESS_QUEUE_REMOVE: __webpack_require__(1036) - -}; - - -/***/ }), -/* 417 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetAdvancedValue = __webpack_require__(13); - -/** - * Adds an Animation component to a Sprite and populates it based on the given config. - * - * @function Phaser.GameObjects.BuildGameObjectAnimation - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. - * @param {object} config - The animation config. - * - * @return {Phaser.GameObjects.Sprite} The updated Sprite. - */ -var BuildGameObjectAnimation = function (sprite, config) -{ - var animConfig = GetAdvancedValue(config, 'anims', null); - - if (animConfig === null) - { - return sprite; - } - - if (typeof animConfig === 'string') - { - // { anims: 'key' } - sprite.anims.play(animConfig); - } - else if (typeof animConfig === 'object') - { - // { anims: { - // key: string - // startFrame: [string|number] - // delay: [float] - // repeat: [integer] - // repeatDelay: [float] - // yoyo: [boolean] - // play: [boolean] - // delayedPlay: [boolean] - // } - // } - - var anims = sprite.anims; - - var key = GetAdvancedValue(animConfig, 'key', undefined); - - if (key) - { - var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); - - var delay = GetAdvancedValue(animConfig, 'delay', 0); - var repeat = GetAdvancedValue(animConfig, 'repeat', 0); - var repeatDelay = GetAdvancedValue(animConfig, 'repeatDelay', 0); - var yoyo = GetAdvancedValue(animConfig, 'yoyo', false); - - var play = GetAdvancedValue(animConfig, 'play', false); - var delayedPlay = GetAdvancedValue(animConfig, 'delayedPlay', 0); - - var playConfig = { - key: key, - delay: delay, - repeat: repeat, - repeatDelay: repeatDelay, - yoyo: yoyo, - startFrame: startFrame - }; - - if (play) - { - anims.play(playConfig); - } - else if (delayedPlay > 0) - { - anims.playAfterDelay(playConfig, delayedPlay); - } - else - { - anims.load(playConfig); - } - } - } - - return sprite; -}; - -module.exports = BuildGameObjectAnimation; - - -/***/ }), -/* 418 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Frame = __webpack_require__(104); - -/** - * @classdesc - * A Bob Game Object. - * - * A Bob belongs to a Blitter Game Object. The Blitter is responsible for managing and rendering this object. - * - * A Bob has a position, alpha value and a frame from a texture that it uses to render with. You can also toggle - * the flipped and visible state of the Bob. The Frame the Bob uses to render can be changed dynamically, but it - * must be a Frame within the Texture used by the parent Blitter. - * - * Bob positions are relative to the Blitter parent. So if you move the Blitter parent, all Bob children will - * have their positions impacted by this change as well. - * - * You can manipulate Bob objects directly from your game code, but the creation and destruction of them should be - * handled via the Blitter parent. - * - * @class Bob - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Blitter} blitter - The parent Blitter object is responsible for updating this Bob. - * @param {number} x - The horizontal position of this Game Object in the world, relative to the parent Blitter position. - * @param {number} y - The vertical position of this Game Object in the world, relative to the parent Blitter position. - * @param {(string|number)} frame - The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. - * @param {boolean} visible - Should the Bob render visible or not to start with? - */ -var Bob = new Class({ - - initialize: - - function Bob (blitter, x, y, frame, visible) - { - /** - * The Blitter object that this Bob belongs to. - * - * @name Phaser.GameObjects.Bob#parent - * @type {Phaser.GameObjects.Blitter} - * @since 3.0.0 - */ - this.parent = blitter; - - /** - * The x position of this Bob, relative to the x position of the Blitter. - * - * @name Phaser.GameObjects.Bob#x - * @type {number} - * @since 3.0.0 - */ - this.x = x; - - /** - * The y position of this Bob, relative to the y position of the Blitter. - * - * @name Phaser.GameObjects.Bob#y - * @type {number} - * @since 3.0.0 - */ - this.y = y; - - /** - * The frame that the Bob uses to render with. - * To change the frame use the `Bob.setFrame` method. - * - * @name Phaser.GameObjects.Bob#frame - * @type {Phaser.Textures.Frame} - * @protected - * @since 3.0.0 - */ - this.frame = frame; - - /** - * A blank object which can be used to store data related to this Bob in. - * - * @name Phaser.GameObjects.Bob#data - * @type {object} - * @default {} - * @since 3.0.0 - */ - this.data = {}; - - /** - * The tint value of this Bob. - * - * @name Phaser.GameObjects.Bob#tint - * @type {number} - * @default 0xffffff - * @since 3.20.0 - */ - this.tint = 0xffffff; - - /** - * The visible state of this Bob. - * - * @name Phaser.GameObjects.Bob#_visible - * @type {boolean} - * @private - * @since 3.0.0 - */ - this._visible = visible; - - /** - * The alpha value of this Bob. - * - * @name Phaser.GameObjects.Bob#_alpha - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - this._alpha = 1; - - /** - * The horizontally flipped state of the Bob. - * A Bob that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture. - * - * @name Phaser.GameObjects.Bob#flipX - * @type {boolean} - * @since 3.0.0 - */ - this.flipX = false; - - /** - * The vertically flipped state of the Bob. - * A Bob 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. - * - * @name Phaser.GameObjects.Bob#flipY - * @type {boolean} - * @since 3.0.0 - */ - this.flipY = false; - }, - - /** - * Changes the Texture Frame being used by this Bob. - * The frame must be part of the Texture the parent Blitter is using. - * If no value is given it will use the default frame of the Blitter parent. - * - * @method Phaser.GameObjects.Bob#setFrame - * @since 3.0.0 - * - * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. - * - * @return {this} This Bob Game Object. - */ - setFrame: function (frame) - { - if (frame === undefined) - { - this.frame = this.parent.frame; - } - else if (frame instanceof Frame && frame.texture === this.parent.texture) - { - this.frame = frame; - } - else - { - this.frame = this.parent.texture.get(frame); - } - - return this; - }, - - /** - * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. - * - * @method Phaser.GameObjects.Bob#resetFlip - * @since 3.0.0 - * - * @return {this} This Bob Game Object. - */ - resetFlip: function () - { - this.flipX = false; - this.flipY = false; - - return this; - }, - - /** - * Resets this Bob. - * - * Changes the position to the values given, and optionally changes the frame. - * - * Also resets the flipX and flipY values, sets alpha back to 1 and visible to true. - * - * @method Phaser.GameObjects.Bob#reset - * @since 3.0.0 - * - * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. - * - * @return {this} This Bob Game Object. - */ - reset: function (x, y, frame) - { - this.x = x; - this.y = y; - - this.flipX = false; - this.flipY = false; - - this._alpha = 1; - this._visible = true; - - this.parent.dirty = true; - - if (frame) - { - this.setFrame(frame); - } - - return this; - }, - - /** - * Changes the position of this Bob to the values given. - * - * @method Phaser.GameObjects.Bob#setPosition - * @since 3.20.0 - * - * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * - * @return {this} This Bob Game Object. - */ - setPosition: function (x, y) - { - this.x = x; - this.y = y; - - return this; - }, - - /** - * Sets the horizontal flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#setFlipX - * @since 3.0.0 - * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Bob Game Object. - */ - setFlipX: function (value) - { - this.flipX = value; - - return this; - }, - - /** - * Sets the vertical flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#setFlipY - * @since 3.0.0 - * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Bob Game Object. - */ - setFlipY: function (value) - { - this.flipY = value; - - return this; - }, - - /** - * Sets the horizontal and vertical flipped state of this Bob. - * - * @method Phaser.GameObjects.Bob#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 Bob Game Object. - */ - setFlip: function (x, y) - { - this.flipX = x; - this.flipY = y; - - return this; - }, - - /** - * Sets the visibility of this Bob. - * - * An invisible Bob will skip rendering. - * - * @method Phaser.GameObjects.Bob#setVisible - * @since 3.0.0 - * - * @param {boolean} value - The visible state of the Game Object. - * - * @return {this} This Bob Game Object. - */ - setVisible: function (value) - { - this.visible = value; - - return this; - }, - - /** - * Set the Alpha level of this Bob. 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. - * - * A Bob with alpha 0 will skip rendering. - * - * @method Phaser.GameObjects.Bob#setAlpha - * @since 3.0.0 - * - * @param {number} value - The alpha value used for this Bob. Between 0 and 1. - * - * @return {this} This Bob Game Object. - */ - setAlpha: function (value) - { - this.alpha = value; - - return this; - }, - - /** - * Sets the tint of this Bob. - * - * @method Phaser.GameObjects.Bob#setTint - * @since 3.20.0 - * - * @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff. - * - * @return {this} This Bob Game Object. - */ - setTint: function (value) - { - this.tint = value; - - return this; - }, - - /** - * Destroys this Bob instance. - * Removes itself from the Blitter and clears the parent, frame and data properties. - * - * @method Phaser.GameObjects.Bob#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.parent.dirty = true; - - this.parent.children.remove(this); - - this.parent = undefined; - this.frame = undefined; - this.data = undefined; - }, - - /** - * The visible state of the Bob. - * - * An invisible Bob will skip rendering. - * - * @name Phaser.GameObjects.Bob#visible - * @type {boolean} - * @since 3.0.0 - */ - visible: { - - get: function () - { - return this._visible; - }, - - set: function (value) - { - this.parent.dirty |= (this._visible !== value); - this._visible = value; - } - - }, - - /** - * The alpha value of the Bob, between 0 and 1. - * - * A Bob with alpha 0 will skip rendering. - * - * @name Phaser.GameObjects.Bob#alpha - * @type {number} - * @since 3.0.0 - */ - alpha: { - - get: function () - { - return this._alpha; - }, - - set: function (value) - { - this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); - this._alpha = value; - } - - } - -}); - -module.exports = Bob; - - -/***/ }), -/* 419 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -/** - * 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; - - -/***/ }), -/* 420 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DOMElementRender = __webpack_require__(1049); -var GameObject = __webpack_require__(15); -var IsPlainObject = __webpack_require__(7); -var RemoveFromDOM = __webpack_require__(197); -var SCENE_EVENTS = __webpack_require__(21); -var Vector4 = __webpack_require__(138); - -/** - * @classdesc - * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. - * - * In order for DOM Elements to display you have to enable them by adding the following to your game - * configuration object: - * - * ```javascript - * dom { - * createContainer: true - * } - * ``` - * - * When this is added, Phaser will automatically create a DOM Container div that is positioned over the top - * of the game canvas. This div is sized to match the canvas, and if the canvas size changes, as a result of - * settings within the Scale Manager, the dom container is resized accordingly. - * - * If you have not already done so, you have to provide a `parent` in the Game Configuration, or the DOM - * Container will fail to be created. - * - * You can create a DOM Element by either passing in DOMStrings, or by passing in a reference to an existing - * Element that you wish to be placed under the control of Phaser. For example: - * - * ```javascript - * this.add.dom(x, y, 'div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * The above code will insert a div element into the DOM Container at the given x/y coordinate. The DOMString in - * the 4th argument sets the initial CSS style of the div and the final argument is the inner text. In this case, - * it will create a lime colored div that is 220px by 100px in size with the text Phaser in it, in an Arial font. - * - * You should nearly always, without exception, use explicitly sized HTML Elements, in order to fully control - * alignment and positioning of the elements next to regular game content. - * - * Rather than specify the CSS and HTML directly you can use the `load.html` File Loader to load it into the - * cache and then use the `createFromCache` method instead. You can also use `createFromHTML` and various other - * methods available in this class to help construct your elements. - * - * Once the element has been created you can then control it like you would any other Game Object. You can set its - * position, scale, rotation, alpha and other properties. It will move as the main Scene Camera moves and be clipped - * at the edge of the canvas. It's important to remember some limitations of DOM Elements: The obvious one is that - * they appear above or below your game canvas. You cannot blend them into the display list, meaning you cannot have - * a DOM Element, then a Sprite, then another DOM Element behind it. - * - * They also cannot be enabled for input. To do that, you have to use the `addListener` method to add native event - * listeners directly. The final limitation is to do with cameras. The DOM Container is sized to match the game canvas - * entirely and clipped accordingly. DOM Elements respect camera scrolling and scrollFactor settings, but if you - * change the size of the camera so it no longer matches the size of the canvas, they won't be clipped accordingly. - * - * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. - * - * Note that you should only have DOM Elements in a Scene with a _single_ Camera. If you require multiple cameras, - * use parallel scenes to achieve this. - * - * DOM Elements are a powerful way to align native HTML with your Phaser Game Objects. For example, you can insert - * a login form for a multiplayer game directly into your title screen. Or a text input box for a highscore table. - * Or a banner ad from a 3rd party service. Or perhaps you'd like to use them for high resolution text display and - * UI. The choice is up to you, just remember that you're dealing with standard HTML and CSS floating over the top - * of your game, and should treat it accordingly. - * - * @class DOMElement - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.17.0 - * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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 DOM Element in the world. - * @param {number} [y=0] - The vertical position of this DOM Element in the world. - * @param {(Element|string)} [element] - An existing DOM element, or a string. If a string starting with a # it will do a `getElementById` look-up on the string (minus the hash). Without a hash, it represents the type of element to create, i.e. 'div'. - * @param {(string|any)} [style] - If a string, will be set directly as the elements `style` property value. If a plain object, will be iterated and the values transferred. In both cases the values replacing whatever CSS styles may have been previously set. - * @param {string} [innerText] - If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. - */ -var DOMElement = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Origin, - Components.ScrollFactor, - Components.Transform, - Components.Visible, - DOMElementRender - ], - - initialize: - - function DOMElement (scene, x, y, element, style, innerText) - { - GameObject.call(this, scene, 'DOMElement'); - - /** - * A reference to the parent DOM Container that the Game instance created when it started. - * - * @name Phaser.GameObjects.DOMElement#parent - * @type {Element} - * @since 3.17.0 - */ - this.parent = scene.sys.game.domContainer; - - /** - * A reference to the HTML Cache. - * - * @name Phaser.GameObjects.DOMElement#cache - * @type {Phaser.Cache.BaseCache} - * @since 3.17.0 - */ - this.cache = scene.sys.cache.html; - - /** - * The actual DOM Element that this Game Object is bound to. For example, if you've created a `
` - * then this property is a direct reference to that element within the dom. - * - * @name Phaser.GameObjects.DOMElement#node - * @type {Element} - * @since 3.17.0 - */ - this.node; - - /** - * By default a DOM Element will have its transform, display, opacity, zIndex and blend mode properties - * updated when its rendered. If, for some reason, you don't want any of these changed other than the - * CSS transform, then set this flag to `true`. When `true` only the CSS Transform is applied and it's - * up to you to keep track of and set the other properties as required. - * - * This can be handy if, for example, you've a nested DOM Element and you don't want the opacity to be - * picked-up by any of its children. - * - * @name Phaser.GameObjects.DOMElement#transformOnly - * @type {boolean} - * @since 3.17.0 - */ - this.transformOnly = false; - - /** - * The angle, in radians, by which to skew the DOM Element on the horizontal axis. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @name Phaser.GameObjects.DOMElement#skewX - * @type {number} - * @since 3.17.0 - */ - this.skewX = 0; - - /** - * The angle, in radians, by which to skew the DOM Element on the vertical axis. - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @name Phaser.GameObjects.DOMElement#skewY - * @type {number} - * @since 3.17.0 - */ - this.skewY = 0; - - /** - * A Vector4 that contains the 3D rotation of this DOM Element around a fixed axis in 3D space. - * - * All values in the Vector4 are treated as degrees, unless the `rotate3dAngle` property is changed. - * - * For more details see the following MDN page: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d - * - * @name Phaser.GameObjects.DOMElement#rotate3d - * @type {Phaser.Math.Vector4} - * @since 3.17.0 - */ - this.rotate3d = new Vector4(); - - /** - * The unit that represents the 3D rotation values. By default this is `deg` for degrees, but can - * be changed to any supported unit. See this page for further details: - * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d - * - * @name Phaser.GameObjects.DOMElement#rotate3dAngle - * @type {string} - * @since 3.17.0 - */ - this.rotate3dAngle = 'deg'; - - /** - * The native (un-scaled) width of this Game Object. - * - * For a DOM Element this property is read-only. - * - * The property `displayWidth` holds the computed bounds of this DOM Element, factoring in scaling. - * - * @name Phaser.GameObjects.DOMElement#width - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.width = 0; - - /** - * The native (un-scaled) height of this Game Object. - * - * For a DOM Element this property is read-only. - * - * The property `displayHeight` holds the computed bounds of this DOM Element, factoring in scaling. - * - * @name Phaser.GameObjects.DOMElement#height - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.height = 0; - - /** - * The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call. - * - * The property `width` holds the un-scaled width of this DOM Element. - * - * @name Phaser.GameObjects.DOMElement#displayWidth - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.displayWidth = 0; - - /** - * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. - * - * The property `height` holds the un-scaled height of this DOM Element. - * - * @name Phaser.GameObjects.DOMElement#displayHeight - * @type {number} - * @readonly - * @since 3.17.0 - */ - this.displayHeight = 0; - - /** - * Internal native event handler. - * - * @name Phaser.GameObjects.DOMElement#handler - * @type {number} - * @private - * @since 3.17.0 - */ - this.handler = this.dispatchNativeEvent.bind(this); - - this.setPosition(x, y); - - if (typeof element === 'string') - { - // hash? - if (element[0] === '#') - { - this.setElement(element.substr(1), style, innerText); - } - else - { - this.createElement(element, style, innerText); - } - } - else if (element) - { - this.setElement(element, style, innerText); - } - - scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); - }, - - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, - - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); - }, - - /** - * Handles a Scene Sleep and Wake event. - * - * @method Phaser.GameObjects.DOMElement#handleSceneEvent - * @private - * @since 3.22.0 - * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems. - */ - handleSceneEvent: function (sys) - { - var node = this.node; - var style = node.style; - - if (node) - { - style.display = (sys.settings.visible) ? 'block' : 'none'; - } - }, - - /** - * Sets the horizontal and vertical skew values of this DOM Element. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform - * - * @method Phaser.GameObjects.DOMElement#setSkew - * @since 3.17.0 - * - * @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis. - * @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis. - * - * @return {this} This DOM Element instance. - */ - setSkew: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.skewX = x; - this.skewY = y; - - return this; - }, - - /** - * Sets the perspective CSS property of the _parent DOM Container_. This determines the distance between the z=0 - * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with - * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined - * by the value of this property. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective - * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** - * - * @method Phaser.GameObjects.DOMElement#setPerspective - * @since 3.17.0 - * - * @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user. - * - * @return {this} This DOM Element instance. - */ - setPerspective: function (value) - { - this.parent.style.perspective = value + 'px'; - - return this; - }, - - /** - * The perspective CSS property value of the _parent DOM Container_. This determines the distance between the z=0 - * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with - * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined - * by the value of this property. - * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective - * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** - * - * @name Phaser.GameObjects.DOMElement#perspective - * @type {number} - * @since 3.17.0 - */ - perspective: { - - get: function () - { - return parseFloat(this.parent.style.perspective); - }, - - set: function (value) - { - this.parent.style.perspective = value + 'px'; - } - - }, - - /** - * Adds one or more native DOM event listeners onto the underlying Element of this Game Object. - * The event is then dispatched via this Game Objects standard event emitter. - * - * For example: - * - * ```javascript - * var div = this.add.dom(x, y, element); - * - * div.addListener('click'); - * - * div.on('click', handler); - * ``` - * - * @method Phaser.GameObjects.DOMElement#addListener - * @since 3.17.0 - * - * @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces. - * - * @return {this} This DOM Element instance. - */ - addListener: function (events) - { - if (this.node) - { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.addEventListener(events[i], this.handler, false); - } - } - - return this; - }, - - /** - * Removes one or more native DOM event listeners from the underlying Element of this Game Object. - * - * @method Phaser.GameObjects.DOMElement#removeListener - * @since 3.17.0 - * - * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. - * - * @return {this} This DOM Element instance. - */ - removeListener: function (events) - { - if (this.node) - { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.removeEventListener(events[i], this.handler); - } - } - - return this; - }, - - /** - * Internal event proxy to dispatch native DOM Events via this Game Object. - * - * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent - * @private - * @since 3.17.0 - * - * @param {any} event - The native DOM event. - */ - dispatchNativeEvent: function (event) - { - this.emit(event.type, event); - }, - - /** - * Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object, - * so you can control it. The `tagName` should be a string and is passed to `document.createElement`: - * - * ```javascript - * this.add.dom().createElement('div'); - * ``` - * - * For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement - * - * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` - * value as well. Here is an example of a DOMString: - * - * ```javascript - * this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * And using a style object: - * - * ```javascript - * var style = { - * 'background-color': 'lime'; - * 'width': '200px'; - * 'height': '100px'; - * 'font': '48px Arial'; - * }; - * - * this.add.dom().createElement('div', style, 'Phaser'); - * ``` - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createElement - * @since 3.17.0 - * - * @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method. - * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. - * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. - * - * @return {this} This DOM Element instance. - */ - createElement: function (tagName, style, innerText) - { - return this.setElement(document.createElement(tagName), style, innerText); - }, - - /** - * Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM - * entirely first. Any event listeners you may have previously created will need to be re-created on the new element. - * - * The `element` argument you pass to this method can be either a string tagName: - * - * ```javascript - *

Phaser

- * - * this.add.dom().setElement('heading'); - * ``` - * - * Or a reference to an Element instance: - * - * ```javascript - *

Phaser

- * - * var h1 = document.getElementById('heading'); - * - * this.add.dom().setElement(h1); - * ``` - * - * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` - * value as well. Here is an example of a DOMString: - * - * ```javascript - * this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); - * ``` - * - * And using a style object: - * - * ```javascript - * var style = { - * 'background-color': 'lime'; - * 'width': '200px'; - * 'height': '100px'; - * 'font': '48px Arial'; - * }; - * - * this.add.dom().setElement(h1, style, 'Phaser'); - * ``` - * - * @method Phaser.GameObjects.DOMElement#setElement - * @since 3.17.0 - * - * @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. - * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. - * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. - * - * @return {this} This DOM Element instance. - */ - setElement: function (element, style, innerText) - { - // Already got an element? Remove it first - this.removeElement(); - - var target; - - if (typeof element === 'string') - { - // hash? - if (element[0] === '#') - { - element = element.substr(1); - } - - target = document.getElementById(element); - } - else if (typeof element === 'object' && element.nodeType === 1) - { - target = element; - } - - if (!target) - { - return this; - } - - this.node = target; - - // style can be empty, a string or a plain object - if (style && IsPlainObject(style)) - { - for (var key in style) - { - target.style[key] = style[key]; - } - } - else if (typeof style === 'string') - { - target.style = style; - } - - // Add / Override the values we need - - target.style.zIndex = '0'; - target.style.display = 'inline'; - target.style.position = 'absolute'; - - // Node handler - - target.phaser = this; - - if (this.parent) - { - this.parent.appendChild(target); - } - - // InnerText - - if (innerText) - { - target.innerText = innerText; - } - - return this.updateSize(); - }, - - /** - * Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then - * creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created - * element. - * - * Assume the following html is stored in a file called `loginform.html`: - * - * ```html - * - * - * ``` - * - * Which is loaded into your game using the cache key 'login': - * - * ```javascript - * this.load.html('login', 'assets/loginform.html'); - * ``` - * - * You can create a DOM Element from it using the cache key: - * - * ```javascript - * this.add.dom().createFromCache('login'); - * ``` - * - * The optional `elementType` argument controls the container that is created, into which the loaded html is inserted. - * The default is a plain `div` object, but any valid tagName can be given. - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createFromCache - * @since 3.17.0 - * - * @param {string} The key of the html cache entry to use for this DOM Element. - * @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. - * - * @return {this} This DOM Element instance. - */ - createFromCache: function (key, tagName) - { - var html = this.cache.get(key); - - if (html) - { - this.createFromHTML(html, tagName); - } - - return this; - }, - - /** - * Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML` - * property of the created element. - * - * ```javascript - * let form = ` - * - * - * `; - * ``` - * - * You can create a DOM Element from it using the string: - * - * ```javascript - * this.add.dom().createFromHTML(form); - * ``` - * - * The optional `elementType` argument controls the type of container that is created, into which the html is inserted. - * The default is a plain `div` object, but any valid tagName can be given. - * - * If this Game Object already has an Element, it is removed from the DOM entirely first. - * Any event listeners you may have previously created will need to be re-created after this call. - * - * @method Phaser.GameObjects.DOMElement#createFromHTML - * @since 3.17.0 - * - * @param {string} A string of html to be set as the `innerHTML` property of the created element. - * @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. - * - * @return {this} This DOM Element instance. - */ - createFromHTML: function (html, tagName) - { - if (tagName === undefined) { tagName = 'div'; } - - // Already got an element? Remove it first - this.removeElement(); - - var element = document.createElement(tagName); - - this.node = element; - - element.style.zIndex = '0'; - element.style.display = 'inline'; - element.style.position = 'absolute'; - - // Node handler - - element.phaser = this; - - if (this.parent) - { - this.parent.appendChild(element); - } - - element.innerHTML = html; - - return this.updateSize(); - }, - - /** - * Removes the current DOM Element bound to this Game Object from the DOM entirely and resets the - * `node` property of this Game Object to be `null`. - * - * @method Phaser.GameObjects.DOMElement#removeElement - * @since 3.17.0 - * - * @return {this} This DOM Element instance. - */ - removeElement: function () - { - if (this.node) - { - RemoveFromDOM(this.node); - - this.node = null; - } - - return this; - }, - - /** - * Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width - * and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight` - * values into the `width` and `height` properties respectively. - * - * This is called automatically whenever a new element is created or set. - * - * @method Phaser.GameObjects.DOMElement#updateSize - * @since 3.17.0 - * - * @return {this} This DOM Element instance. - */ - updateSize: function () - { - var node = this.node; - - var nodeBounds = node.getBoundingClientRect(); - - this.width = node.clientWidth; - this.height = node.clientHeight; - - this.displayWidth = nodeBounds.width || 0; - this.displayHeight = nodeBounds.height || 0; - - return this; - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a property matching the given key and value. It then returns this child - * if found, or `null` if not. - * - * @method Phaser.GameObjects.DOMElement#getChildByProperty - * @since 3.17.0 - * - * @param {string} property - The property to search the children for. - * @param {string} value - The value the property must strictly equal. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByProperty: function (property, value) - { - if (this.node) - { - var children = this.node.querySelectorAll('*'); - - for (var i = 0; i < children.length; i++) - { - if (children[i][property] === value) - { - return children[i]; - } - } - } - - return null; - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not. - * - * Be aware that class and id names are case-sensitive. - * - * @method Phaser.GameObjects.DOMElement#getChildByID - * @since 3.17.0 - * - * @param {string} id - The id to search the children for. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByID: function (id) - { - return this.getChildByProperty('id', id); - }, - - /** - * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through - * them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not. - * - * Be aware that class and id names are case-sensitive. - * - * @method Phaser.GameObjects.DOMElement#getChildByName - * @since 3.17.0 - * - * @param {string} name - The name to search the children for. - * - * @return {?Element} The first matching child DOM Element, or `null` if not found. - */ - getChildByName: function (name) - { - return this.getChildByProperty('name', name); - }, - - /** - * Sets the `className` property of the DOM Element node and updates the internal sizes. - * - * @method Phaser.GameObjects.DOMElement#setClassName - * @since 3.17.0 - * - * @param {string} className - A string representing the class or space-separated classes of the element. - * - * @return {this} This DOM Element instance. - */ - setClassName: function (className) - { - if (this.node) - { - this.node.className = className; - - this.updateSize(); - } - - return this; - }, - - /** - * Sets the `innerText` property of the DOM Element node and updates the internal sizes. - * - * Note that only certain types of Elements can have `innerText` set on them. - * - * @method Phaser.GameObjects.DOMElement#setText - * @since 3.17.0 - * - * @param {string} text - A DOMString representing the rendered text content of the element. - * - * @return {this} This DOM Element instance. - */ - setText: function (text) - { - if (this.node) - { - this.node.innerText = text; - - this.updateSize(); - } - - return this; - }, - - /** - * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. - * - * @method Phaser.GameObjects.DOMElement#setHTML - * @since 3.17.0 - * - * @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element. - * - * @return {this} This DOM Element instance. - */ - setHTML: function (html) - { - if (this.node) - { - this.node.innerHTML = html; - - this.updateSize(); - } - - return this; - }, - - /** - * Runs internal update tasks. - * - * @method Phaser.GameObjects.DOMElement#preUpdate - * @private - * @since 3.17.0 - */ - preUpdate: function () - { - var parent = this.parentContainer; - var node = this.node; - - if (node && parent && !parent.willRender()) - { - node.style.display = 'none'; - } - }, - - /** - * Compares the renderMask with the renderFlags to see if this Game Object will render or not. - * - * DOMElements always return `true` as they need to still set values during the render pass, even if not visible. - * - * @method Phaser.GameObjects.DOMElement#willRender - * @since 3.17.0 - * - * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. - */ - willRender: function () - { - return true; - }, - - /** - * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. - * - * @method Phaser.GameObjects.DOMElement#preDestroy - * @private - * @since 3.17.0 - */ - preDestroy: function () - { - this.removeElement(); - - this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); - } - -}); - -module.exports = DOMElement; - - -/***/ }), -/* 421 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CSSBlendModes = __webpack_require__(1050); -var GameObject = __webpack_require__(15); -var TransformMatrix = __webpack_require__(25); - -var tempMatrix1 = new TransformMatrix(); -var tempMatrix2 = new TransformMatrix(); -var tempMatrix3 = new TransformMatrix(); - -/** - * 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.DOMElement#renderWebGL - * @since 3.17.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active renderer. - * @param {Phaser.GameObjects.DOMElement} 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 DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) -{ - var node = src.node; - var style = node.style; - var settings = src.scene.sys.settings; - - if (!node || !style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) - { - if (node) - { - style.display = 'none'; - } - - return; - } - - var parent = src.parentContainer; - var alpha = camera.alpha * src.alpha; - - if (parent) - { - alpha *= parent.alpha; - } - - var camMatrix = tempMatrix1; - var srcMatrix = tempMatrix2; - var calcMatrix = tempMatrix3; - - var dx = 0; - var dy = 0; - - var tx = '0%'; - var ty = '0%'; - - if (parentMatrix) - { - dx = (src.width * src.scaleX) * src.originX; - dy = (src.height * src.scaleY) * src.originY; - - srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); - - camMatrix.copyFrom(camera.matrix); - - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); - - // Undo the camera scroll - srcMatrix.e = src.x - dx; - srcMatrix.f = src.y - dy; - - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } - else - { - dx = (src.width) * src.originX; - dy = (src.height) * src.originY; - - srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); - - camMatrix.copyFrom(camera.matrix); - - tx = (100 * src.originX) + '%'; - ty = (100 * src.originY) + '%'; - - srcMatrix.e -= camera.scrollX * src.scrollFactorX; - srcMatrix.f -= camera.scrollY * src.scrollFactorY; - - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } - - if (!src.transformOnly) - { - style.display = 'block'; - style.opacity = alpha; - style.zIndex = src._depth; - style.pointerEvents = 'auto'; - style.mixBlendMode = CSSBlendModes[src._blendMode]; - } - - // https://developer.mozilla.org/en-US/docs/Web/CSS/transform - - style.transform = - calcMatrix.getCSSMatrix() + - ' skew(' + src.skewX + 'rad, ' + src.skewY + 'rad)' + - ' rotate3d(' + src.rotate3d.x + ',' + src.rotate3d.y + ',' + src.rotate3d.z + ',' + src.rotate3d.w + src.rotate3dAngle + ')'; - - style.transformOrigin = tx + ' ' + ty; -}; - -module.exports = DOMElementCSSRenderer; - - -/***/ }), -/* 422 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var ExternRender = __webpack_require__(1054); - -/** - * @classdesc - * An Extern Game Object is a special type of Game Object that allows you to pass - * rendering off to a 3rd party. - * - * When you create an Extern and place it in the display list of a Scene, the renderer will - * process the list as usual. When it finds an Extern it will flush the current batch, - * clear down the pipeline and prepare a transform matrix which your render function can - * take advantage of, if required. - * - * The WebGL context is then left is a 'clean' state, ready for you to bind your own shaders, - * or draw to it, whatever you wish to do. Once you've finished, you should free-up any - * of your resources. The Extern will then rebind the Phaser pipeline and carry on - * rendering the display list. - * - * Although this object has lots of properties such as Alpha, Blend Mode and Tint, none of - * them are used during rendering unless you take advantage of them in your own render code. - * - * @class Extern - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.16.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Tint - * @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. - */ -var Extern = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Flip, - Components.Origin, - Components.ScrollFactor, - Components.Size, - Components.Texture, - Components.Tint, - Components.Transform, - Components.Visible, - ExternRender - ], - - initialize: - - function Extern (scene) - { - GameObject.call(this, scene, 'Extern'); - }, - - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, - - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); - }, - - preUpdate: function () - { - // override this! - // Arguments: time, delta - }, - - render: function () - { - // override this! - // Arguments: renderer, camera, calcMatrix - } - -}); - -module.exports = Extern; - - -/***/ }), -/* 423 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircumferencePoint = __webpack_require__(213); -var FromPercent = __webpack_require__(95); -var MATH_CONST = __webpack_require__(14); -var Point = __webpack_require__(4); - -/** - * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse - * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point - * at 180 degrees around the circle. - * - * @function Phaser.Geom.Ellipse.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. - * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the ellipse. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. - */ -var GetPoint = function (ellipse, position, out) -{ - if (out === undefined) { out = new Point(); } - - var angle = FromPercent(position, 0, MATH_CONST.PI2); - - return CircumferencePoint(ellipse, angle, out); -}; - -module.exports = GetPoint; - - -/***/ }), -/* 424 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Circumference = __webpack_require__(425); -var CircumferencePoint = __webpack_require__(213); -var FromPercent = __webpack_require__(95); -var MATH_CONST = __webpack_require__(14); - -/** - * Returns an array of Point objects containing the coordinates of the points around the circumference of the Ellipse, - * based on the given quantity or stepRate values. - * - * @function Phaser.Geom.Ellipse.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the points from. - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the circumference of the ellipse and dividing it by the stepRate. - * @param {(array|Phaser.Geom.Point[])} [out] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse. - */ -var GetPoints = function (ellipse, 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 = Circumference(ellipse) / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); - - out.push(CircumferencePoint(ellipse, angle)); - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 425 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns the circumference of the given Ellipse. - * - * @function Phaser.Geom.Ellipse.Circumference - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference of. - * - * @return {number} The circumference of th Ellipse. - */ -var Circumference = function (ellipse) -{ - var rx = ellipse.width / 2; - var ry = ellipse.height / 2; - var h = Math.pow((rx - ry), 2) / Math.pow((rx + ry), 2); - - return (Math.PI * (rx + ry)) * (1 + ((3 * h) / (10 + Math.sqrt(4 - (3 * h))))); -}; - -module.exports = Circumference; - - -/***/ }), -/* 426 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Commands = __webpack_require__(212); -var SetTransform = __webpack_require__(30); - -/** - * 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.Graphics#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Graphics} 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 - * @param {CanvasRenderingContext2D} [renderTargetCtx] - The target rendering context. - * @param {boolean} allowClip - If `true` then path operations will be used instead of fill operations. - */ -var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) -{ - var commandBuffer = src.commandBuffer; - var commandBufferLength = commandBuffer.length; - - var ctx = renderTargetCtx || renderer.currentContext; - - if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - return; - } - - var lineAlpha = 1; - var fillAlpha = 1; - var lineColor = 0; - var fillColor = 0; - var lineWidth = 1; - var red = 0; - var green = 0; - var blue = 0; - - // Reset any currently active paths - ctx.beginPath(); - - for (var index = 0; index < commandBufferLength; ++index) - { - var commandID = commandBuffer[index]; - - switch (commandID) - { - case Commands.ARC: - ctx.arc( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4], - commandBuffer[index + 5], - commandBuffer[index + 6] - ); - - // +7 because overshoot is the 7th value, not used in Canvas - index += 7; - break; - - case Commands.LINE_STYLE: - lineWidth = commandBuffer[index + 1]; - lineColor = commandBuffer[index + 2]; - lineAlpha = commandBuffer[index + 3]; - red = ((lineColor & 0xFF0000) >>> 16); - green = ((lineColor & 0xFF00) >>> 8); - blue = (lineColor & 0xFF); - ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + lineAlpha + ')'; - ctx.lineWidth = lineWidth; - index += 3; - break; - - case Commands.FILL_STYLE: - fillColor = commandBuffer[index + 1]; - fillAlpha = commandBuffer[index + 2]; - red = ((fillColor & 0xFF0000) >>> 16); - green = ((fillColor & 0xFF00) >>> 8); - blue = (fillColor & 0xFF); - ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; - index += 2; - break; - - case Commands.BEGIN_PATH: - ctx.beginPath(); - break; - - case Commands.CLOSE_PATH: - ctx.closePath(); - break; - - case Commands.FILL_PATH: - if (!allowClip) - { - ctx.fill(); - } - break; - - case Commands.STROKE_PATH: - if (!allowClip) - { - ctx.stroke(); - } - break; - - case Commands.FILL_RECT: - if (!allowClip) - { - ctx.fillRect( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4] - ); - } - else - { - ctx.rect( - commandBuffer[index + 1], - commandBuffer[index + 2], - commandBuffer[index + 3], - commandBuffer[index + 4] - ); - } - index += 4; - break; - - case Commands.FILL_TRIANGLE: - ctx.beginPath(); - ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); - ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); - ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); - ctx.closePath(); - if (!allowClip) - { - ctx.fill(); - } - index += 6; - break; - - case Commands.STROKE_TRIANGLE: - ctx.beginPath(); - ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); - ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); - ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); - ctx.closePath(); - if (!allowClip) - { - ctx.stroke(); - } - index += 6; - break; - - case Commands.LINE_TO: - ctx.lineTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.MOVE_TO: - ctx.moveTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.LINE_FX_TO: - ctx.lineTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 5; - break; - - case Commands.MOVE_FX_TO: - ctx.moveTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 5; - break; - - case Commands.SAVE: - ctx.save(); - break; - - case Commands.RESTORE: - ctx.restore(); - break; - - case Commands.TRANSLATE: - ctx.translate( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.SCALE: - ctx.scale( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; - - case Commands.ROTATE: - ctx.rotate( - commandBuffer[index + 1] - ); - index += 1; - break; - - case Commands.GRADIENT_FILL_STYLE: - index += 5; - break; - - case Commands.GRADIENT_LINE_STYLE: - index += 6; - break; - } - } - - // Restore the context saved in SetTransform - ctx.restore(); -}; - -module.exports = GraphicsCanvasRenderer; - - -/***/ }), -/* 427 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var FloatBetween = __webpack_require__(135); -var GetEaseFunction = __webpack_require__(80); -var GetFastValue = __webpack_require__(2); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * A Particle Emitter property. - * - * Facilitates changing Particle properties as they are emitted and throughout their lifetime. - * - * @class EmitterOp - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for the Particle Emitter that owns this property. - * @param {string} key - The name of the property. - * @param {number} defaultValue - The default value of the property. - * @param {boolean} [emitOnly=false] - Whether the property can only be modified when a Particle is emitted. - */ -var EmitterOp = new Class({ - - initialize: - - function EmitterOp (config, key, defaultValue, emitOnly) - { - if (emitOnly === undefined) - { - emitOnly = false; - } - - /** - * The name of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#propertyKey - * @type {string} - * @since 3.0.0 - */ - this.propertyKey = key; - - /** - * The value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue - * @type {number} - * @since 3.0.0 - */ - this.propertyValue = defaultValue; - - /** - * The default value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue - * @type {number} - * @since 3.0.0 - */ - this.defaultValue = defaultValue; - - /** - * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. - * - * @name Phaser.GameObjects.Particles.EmitterOp#steps - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.steps = 0; - - /** - * The step counter for stepped easing, per emit. - * - * @name Phaser.GameObjects.Particles.EmitterOp#counter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.counter = 0; - - /** - * The start value for this property to ease between. - * - * @name Phaser.GameObjects.Particles.EmitterOp#start - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.start = 0; - - /** - * The end value for this property to ease between. - * - * @name Phaser.GameObjects.Particles.EmitterOp#end - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.end = 0; - - /** - * The easing function to use for updating this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#ease - * @type {?function} - * @since 3.0.0 - */ - this.ease; - - /** - * Whether this property can only be modified when a Particle is emitted. - * - * Set to `true` to allow only {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} callbacks to be set and - * affect this property. - * - * Set to `false` to allow both {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and - * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks to be set and affect this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#emitOnly - * @type {boolean} - * @since 3.0.0 - */ - this.emitOnly = emitOnly; - - /** - * The callback to run for Particles when they are emitted from the Particle Emitter. - * - * @name Phaser.GameObjects.Particles.EmitterOp#onEmit - * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback} - * @since 3.0.0 - */ - this.onEmit = this.defaultEmit; - - /** - * The callback to run for Particles when they are updated. - * - * @name Phaser.GameObjects.Particles.EmitterOp#onUpdate - * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} - * @since 3.0.0 - */ - this.onUpdate = this.defaultUpdate; - - this.loadConfig(config); - }, - - /** - * Load the property from a Particle Emitter configuration object. - * - * Optionally accepts a new property key to use, replacing the current one. - * - * @method Phaser.GameObjects.Particles.EmitterOp#loadConfig - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Settings for the Particle Emitter that owns this property. - * @param {string} [newKey] - The new key to use for this property, if any. - */ - loadConfig: function (config, newKey) - { - if (config === undefined) - { - config = {}; - } - - if (newKey) - { - this.propertyKey = newKey; - } - - this.propertyValue = GetFastValue( - config, - this.propertyKey, - this.defaultValue - ); - - this.setMethods(); - - if (this.emitOnly) - { - // Reset it back again - this.onUpdate = this.defaultUpdate; - } - }, - - /** - * Build a JSON representation of this Particle Emitter property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#toJSON - * @since 3.0.0 - * - * @return {object} A JSON representation of this Particle Emitter property. - */ - toJSON: function () - { - return this.propertyValue; - }, - - /** - * Change the current value of the property and update its callback methods. - * - * @method Phaser.GameObjects.Particles.EmitterOp#onChange - * @since 3.0.0 - * - * @param {number} value - The value of the property. - * - * @return {this} This Emitter Op object. - */ - onChange: function (value) - { - this.propertyValue = value; - - return this.setMethods(); - }, - - /** - * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and - * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the type of the current - * {@link Phaser.GameObjects.Particles.EmitterOp#propertyValue}. - * - * @method Phaser.GameObjects.Particles.EmitterOp#setMethods - * @since 3.0.0 - * - * @return {this} This Emitter Op object. - */ - setMethods: function () - { - var value = this.propertyValue; - - var t = typeof value; - - // Reset them in case they're not changed below - this.onEmit = this.defaultEmit; - this.onUpdate = this.defaultUpdate; - - if (t === 'number') - { - // Explicit static value: - // x: 400 - - this.onEmit = this.staticValueEmit; - this.onUpdate = this.staticValueUpdate; // How? - } - else if (Array.isArray(value)) - { - // Picks a random element from the array: - // x: [ 100, 200, 300, 400 ] - - this.onEmit = this.randomStaticValueEmit; - } - else if (t === 'function') - { - // The same as setting just the onUpdate function and no onEmit (unless this op is an emitOnly one) - // Custom callback, must return a value: - - /* - x: function (particle, key, t, value) - { - return value + 50; - } - */ - - if (this.emitOnly) - { - this.onEmit = value; - } - else - { - this.onUpdate = value; - } - } - else if (t === 'object' && this.hasBoth(value, 'start', 'end')) - { - this.start = value.start; - this.end = value.end; - - // x: { start: 100, end: 400, random: true } (random optional) = eases between start and end - - var isRandom = this.has(value, 'random'); - - if (isRandom) - { - this.onEmit = this.randomRangedValueEmit; - } - - if (this.has(value, 'steps')) - { - // A stepped (per emit) range - - // x: { start: 100, end: 400, steps: 64 } - - // Increments a value stored in the emitter - - this.steps = value.steps; - this.counter = this.start; - - this.onEmit = this.steppedEmit; - } - else - { - // An eased range (defaults to Linear if not specified) - - // x: { start: 100, end: 400, [ ease: 'Linear' ] } - - var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; - - this.ease = GetEaseFunction(easeType, value.easeParams); - - if (!isRandom) - { - this.onEmit = this.easedValueEmit; - } - - this.onUpdate = this.easeValueUpdate; - } - } - else if (t === 'object' && this.hasBoth(value, 'min', 'max')) - { - // { min: 100, max: 400 } = pick a random number between min and max - - this.start = value.min; - this.end = value.max; - this.onEmit = this.randomRangedValueEmit; - } - else if (t === 'object' && this.has(value, 'random')) - { - // { random: [ 100, 400 ] } = pick a random number between the two elements of the array - - var rnd = value.random; - - if (Array.isArray(rnd)) - { - this.start = rnd[0]; - this.end = rnd[1]; - } - - this.onEmit = this.randomRangedValueEmit; - } - else if (t === 'object' && this.hasEither(value, 'onEmit', 'onUpdate')) - { - // Custom onEmit and onUpdate callbacks - - /* - x: { - // Called at the start of the particles life, when it is being created - onEmit: function (particle, key, t, value) - { - return value; - }, - - // Called during the particles life on each update - onUpdate: function (particle, key, t, value) - { - return value; - } - } - */ - - if (this.has(value, 'onEmit')) - { - this.onEmit = value.onEmit; - } - - if (this.has(value, 'onUpdate')) - { - this.onUpdate = value.onUpdate; - } - } - - return this; - }, - - /** - * Check whether an object has the given property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#has - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key - The key of the property to look for in the object. - * - * @return {boolean} `true` if the property exists in the object, `false` otherwise. - */ - has: function (object, key) - { - return object.hasOwnProperty(key); - }, - - /** - * Check whether an object has both of the given properties. - * - * @method Phaser.GameObjects.Particles.EmitterOp#hasBoth - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key1 - The key of the first property to check the object for. - * @param {string} key2 - The key of the second property to check the object for. - * - * @return {boolean} `true` if both properties exist in the object, `false` otherwise. - */ - hasBoth: function (object, key1, key2) - { - return object.hasOwnProperty(key1) && object.hasOwnProperty(key2); - }, - - /** - * Check whether an object has at least one of the given properties. - * - * @method Phaser.GameObjects.Particles.EmitterOp#hasEither - * @since 3.0.0 - * - * @param {object} object - The object to check. - * @param {string} key1 - The key of the first property to check the object for. - * @param {string} key2 - The key of the second property to check the object for. - * - * @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist. - */ - hasEither: function (object, key1, key2) - { - return object.hasOwnProperty(key1) || object.hasOwnProperty(key2); - }, - - /** - * The returned value sets what the property will be at the START of the particles life, on emit. - * - * @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} [value] - The current value of the property. - * - * @return {number} The new value of the property. - */ - defaultEmit: function (particle, key, value) - { - return value; - }, - - /** - * The returned value updates the property for the duration of the particles life. - * - * @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} t - The T value (between 0 and 1) - * @param {number} value - The current value of the property. - * - * @return {number} The new value of the property. - */ - defaultUpdate: function (particle, key, t, value) - { - return value; - }, - - /** - * An `onEmit` callback that returns the current value of the property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit - * @since 3.0.0 - * - * @return {number} The current value of the property. - */ - staticValueEmit: function () - { - return this.propertyValue; - }, - - /** - * An `onUpdate` callback that returns the current value of the property. - * - * @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate - * @since 3.0.0 - * - * @return {number} The current value of the property. - */ - staticValueUpdate: function () - { - return this.propertyValue; - }, - - /** - * An `onEmit` callback that returns a random value from the current value array. - * - * @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit - * @since 3.0.0 - * - * @return {number} The new value of the property. - */ - randomStaticValueEmit: function () - { - var randomIndex = Math.floor(Math.random() * this.propertyValue.length); - - return this.propertyValue[randomIndex]; - }, - - /** - * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The key of the property. - * - * @return {number} The new value of the property. - */ - randomRangedValueEmit: function (particle, key) - { - var value = FloatBetween(this.start, this.end); - - if (particle && particle.data[key]) - { - particle.data[key].min = value; - } - - return value; - }, - - /** - * An `onEmit` callback that returns a stepped value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit - * @since 3.0.0 - * - * @return {number} The new value of the property. - */ - steppedEmit: function () - { - var current = this.counter; - - var next = this.counter + (this.end - this.start) / this.steps; - - this.counter = Wrap(next, this.start, this.end); - - return current; - }, - - /** - * An `onEmit` callback for an eased property. - * - * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. - * - * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * - * @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property. - */ - easedValueEmit: function (particle, key) - { - if (particle && particle.data[key]) - { - var data = particle.data[key]; - - data.min = this.start; - data.max = this.end; - } - - return this.start; - }, - - /** - * An `onUpdate` callback that returns an eased value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. - * - * @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. - * @param {string} key - The name of the property. - * @param {number} t - The T value (between 0 and 1) - * - * @return {number} The new value of the property. - */ - easeValueUpdate: function (particle, key, t) - { - var data = particle.data[key]; - - return (data.max - data.min) * this.ease(t) + data.min; - } -}); - -module.exports = EmitterOp; - - -/***/ }), -/* 428 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * The GravityWell action applies a force on the particle to draw it towards, or repel it from, a single point. - * - * The force applied is inversely proportional to the square of the distance from the particle to the point, in accordance with Newton's law of gravity. - * - * This simulates the effect of gravity over large distances (as between planets, for example). - * - * @class GravityWell - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {(number|Phaser.Types.GameObjects.Particles.GravityWellConfig)} [x=0] - The x coordinate of the Gravity Well, in world space. - * @param {number} [y=0] - The y coordinate of the Gravity Well, in world space. - * @param {number} [power=0] - The strength of the gravity force - larger numbers produce a stronger force. - * @param {number} [epsilon=100] - The minimum distance for which the gravity force is calculated. - * @param {number} [gravity=50] - The gravitational force of this Gravity Well. - */ -var GravityWell = new Class({ - - initialize: - - function GravityWell (x, y, power, epsilon, gravity) - { - if (typeof x === 'object') - { - var config = x; - - x = GetFastValue(config, 'x', 0); - y = GetFastValue(config, 'y', 0); - power = GetFastValue(config, 'power', 0); - epsilon = GetFastValue(config, 'epsilon', 100); - gravity = GetFastValue(config, 'gravity', 50); - } - else - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (power === undefined) { power = 0; } - if (epsilon === undefined) { epsilon = 100; } - if (gravity === undefined) { gravity = 50; } - } - - /** - * The x coordinate of the Gravity Well, in world space. - * - * @name Phaser.GameObjects.Particles.GravityWell#x - * @type {number} - * @since 3.0.0 - */ - this.x = x; - - /** - * The y coordinate of the Gravity Well, in world space. - * - * @name Phaser.GameObjects.Particles.GravityWell#y - * @type {number} - * @since 3.0.0 - */ - this.y = y; - - /** - * The active state of the Gravity Well. An inactive Gravity Well will not influence any particles. - * - * @name Phaser.GameObjects.Particles.GravityWell#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Internal gravity value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_gravity - * @type {number} - * @private - * @since 3.0.0 - */ - this._gravity = gravity; - - /** - * Internal power value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_power - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._power = 0; - - /** - * Internal epsilon value. - * - * @name Phaser.GameObjects.Particles.GravityWell#_epsilon - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._epsilon = 0; - - /** - * The strength of the gravity force - larger numbers produce a stronger force. - * - * @name Phaser.GameObjects.Particles.GravityWell#power - * @type {number} - * @since 3.0.0 - */ - this.power = power; - - /** - * The minimum distance for which the gravity force is calculated. - * - * @name Phaser.GameObjects.Particles.GravityWell#epsilon - * @type {number} - * @since 3.0.0 - */ - this.epsilon = epsilon; - }, - - /** - * Takes a Particle and updates it based on the properties of this Gravity Well. - * - * @method Phaser.GameObjects.Particles.GravityWell#update - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update. - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - */ - update: function (particle, delta) - { - var x = this.x - particle.x; - var y = this.y - particle.y; - var dSq = x * x + y * y; - - if (dSq === 0) - { - return; - } - - var d = Math.sqrt(dSq); - - if (dSq < this._epsilon) - { - dSq = this._epsilon; - } - - var factor = ((this._power * delta) / (dSq * d)) * 100; - - particle.velocityX += x * factor; - particle.velocityY += y * factor; - }, - - epsilon: { - - get: function () - { - return Math.sqrt(this._epsilon); - }, - - set: function (value) - { - this._epsilon = value * value; - } - - }, - - power: { - - get: function () - { - return this._power / this._gravity; - }, - - set: function (value) - { - this._power = value * this._gravity; - } - - }, - - gravity: { - - get: function () - { - return this._gravity; - }, - - set: function (value) - { - var pwr = this.power; - this._gravity = value; - this.power = pwr; - } - - } - -}); - -module.exports = GravityWell; - - -/***/ }), -/* 429 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var DistanceBetween = __webpack_require__(48); - -/** - * @classdesc - * A Particle is a simple Game Object controlled by a Particle Emitter and Manager, and rendered by the Manager. - * It uses its own lightweight physics system, and can interact only with its Emitter's bounds and zones. - * - * @class Particle - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. - */ -var Particle = new Class({ - - initialize: - - function Particle (emitter) - { - /** - * The Emitter to which this Particle belongs. - * - * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. - * - * @name Phaser.GameObjects.Particles.Particle#emitter - * @type {Phaser.GameObjects.Particles.ParticleEmitter} - * @since 3.0.0 - */ - this.emitter = emitter; - - /** - * The texture frame used to render this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#frame - * @type {Phaser.Textures.Frame} - * @default null - * @since 3.0.0 - */ - this.frame = null; - - /** - * The x coordinate of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = 0; - - /** - * The y coordinate of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = 0; - - /** - * The x velocity of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#velocityX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.velocityX = 0; - - /** - * The y velocity of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#velocityY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.velocityY = 0; - - /** - * The x acceleration of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#accelerationX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelerationX = 0; - - /** - * The y acceleration of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#accelerationY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelerationY = 0; - - /** - * The maximum horizontal velocity this Particle can travel at. - * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityX - * @type {number} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityX = 10000; - - /** - * The maximum vertical velocity this Particle can travel at. - * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityY - * @type {number} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityY = 10000; - - /** - * The bounciness, or restitution, of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#bounce - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.bounce = 0; - - /** - * The horizontal scale of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#scaleX - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.scaleX = 1; - - /** - * The vertical scale of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#scaleY - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.scaleY = 1; - - /** - * The alpha value of this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#alpha - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.alpha = 1; - - /** - * The angle of this Particle in degrees. - * - * @name Phaser.GameObjects.Particles.Particle#angle - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angle = 0; - - /** - * The angle of this Particle in radians. - * - * @name Phaser.GameObjects.Particles.Particle#rotation - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.rotation = 0; - - /** - * The tint applied to this Particle. - * - * @name Phaser.GameObjects.Particles.Particle#tint - * @type {number} - * @webglOnly - * @since 3.0.0 - */ - this.tint = 0xffffff; - - /** - * The lifespan of this Particle in ms. - * - * @name Phaser.GameObjects.Particles.Particle#life - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.life = 1000; - - /** - * The current life of this Particle in ms. - * - * @name Phaser.GameObjects.Particles.Particle#lifeCurrent - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.lifeCurrent = 1000; - - /** - * The delay applied to this Particle upon emission, in ms. - * - * @name Phaser.GameObjects.Particles.Particle#delayCurrent - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.delayCurrent = 0; - - /** - * The normalized lifespan T value, where 0 is the start and 1 is the end. - * - * @name Phaser.GameObjects.Particles.Particle#lifeT - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lifeT = 0; - - /** - * The data used by the ease equation. - * - * @name Phaser.GameObjects.Particles.Particle#data - * @type {object} - * @since 3.0.0 - */ - this.data = { - tint: { min: 0xffffff, max: 0xffffff, current: 0xffffff }, - alpha: { min: 1, max: 1 }, - rotate: { min: 0, max: 0 }, - scaleX: { min: 1, max: 1 }, - scaleY: { min: 1, max: 1 } - }; - }, - - /** - * Checks to see if this Particle is alive and updating. - * - * @method Phaser.GameObjects.Particles.Particle#isAlive - * @since 3.0.0 - * - * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. - */ - isAlive: function () - { - return (this.lifeCurrent > 0); - }, - - /** - * Resets the position of this particle back to zero. - * - * @method Phaser.GameObjects.Particles.Particle#resetPosition - * @since 3.16.0 - */ - resetPosition: function () - { - this.x = 0; - this.y = 0; - }, - - /** - * Starts this Particle from the given coordinates. - * - * @method Phaser.GameObjects.Particles.Particle#fire - * @since 3.0.0 - * - * @param {number} x - The x coordinate to launch this Particle from. - * @param {number} y - The y coordinate to launch this Particle from. - */ - fire: function (x, y) - { - var emitter = this.emitter; - - this.frame = emitter.getFrame(); - - if (emitter.emitZone) - { - // Updates particle.x and particle.y during this call - emitter.emitZone.getPoint(this); - } - - if (x === undefined) - { - this.x += emitter.x.onEmit(this, 'x'); - } - else - { - this.x += x; - } - - if (y === undefined) - { - this.y += emitter.y.onEmit(this, 'y'); - } - else - { - this.y += y; - } - - this.life = emitter.lifespan.onEmit(this, 'lifespan'); - this.lifeCurrent = this.life; - this.lifeT = 0; - - var sx = emitter.speedX.onEmit(this, 'speedX'); - var sy = (emitter.speedY) ? emitter.speedY.onEmit(this, 'speedY') : sx; - - if (emitter.radial) - { - var rad = DegToRad(emitter.angle.onEmit(this, 'angle')); - - this.velocityX = Math.cos(rad) * Math.abs(sx); - this.velocityY = Math.sin(rad) * Math.abs(sy); - } - else if (emitter.moveTo) - { - var mx = emitter.moveToX.onEmit(this, 'moveToX'); - var my = (emitter.moveToY) ? emitter.moveToY.onEmit(this, 'moveToY') : mx; - - var angle = Math.atan2(my - this.y, mx - this.x); - - var speed = DistanceBetween(this.x, this.y, mx, my) / (this.life / 1000); - - // We know how many pixels we need to move, but how fast? - // var speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000); - - this.velocityX = Math.cos(angle) * speed; - this.velocityY = Math.sin(angle) * speed; - } - else - { - this.velocityX = sx; - this.velocityY = sy; - } - - if (emitter.acceleration) - { - this.accelerationX = emitter.accelerationX.onEmit(this, 'accelerationX'); - this.accelerationY = emitter.accelerationY.onEmit(this, 'accelerationY'); - } - - this.maxVelocityX = emitter.maxVelocityX.onEmit(this, 'maxVelocityX'); - this.maxVelocityY = emitter.maxVelocityY.onEmit(this, 'maxVelocityY'); - - this.delayCurrent = emitter.delay.onEmit(this, 'delay'); - - this.scaleX = emitter.scaleX.onEmit(this, 'scaleX'); - this.scaleY = (emitter.scaleY) ? emitter.scaleY.onEmit(this, 'scaleY') : this.scaleX; - - this.angle = emitter.rotate.onEmit(this, 'rotate'); - this.rotation = DegToRad(this.angle); - - this.bounce = emitter.bounce.onEmit(this, 'bounce'); - - this.alpha = emitter.alpha.onEmit(this, 'alpha'); - - this.tint = emitter.tint.onEmit(this, 'tint'); - }, - - /** - * An internal method that calculates the velocity of the Particle. - * - * @method Phaser.GameObjects.Particles.Particle#computeVelocity - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle. - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - * @param {array} processors - Particle processors (gravity wells). - */ - computeVelocity: function (emitter, delta, step, processors) - { - var vx = this.velocityX; - var vy = this.velocityY; - - var ax = this.accelerationX; - var ay = this.accelerationY; - - var mx = this.maxVelocityX; - var my = this.maxVelocityY; - - vx += (emitter.gravityX * step); - vy += (emitter.gravityY * step); - - if (ax) - { - vx += (ax * step); - } - - if (ay) - { - vy += (ay * step); - } - - if (vx > mx) - { - vx = mx; - } - else if (vx < -mx) - { - vx = -mx; - } - - if (vy > my) - { - vy = my; - } - else if (vy < -my) - { - vy = -my; - } - - this.velocityX = vx; - this.velocityY = vy; - - // Apply any additional processors - for (var i = 0; i < processors.length; i++) - { - processors[i].update(this, delta, step); - } - }, - - /** - * Checks if this Particle is still within the bounds defined by the given Emitter. - * - * If not, and depending on the Emitter collision flags, the Particle may either stop or rebound. - * - * @method Phaser.GameObjects.Particles.Particle#checkBounds - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against. - */ - checkBounds: function (emitter) - { - var bounds = emitter.bounds; - var bounce = -this.bounce; - - if (this.x < bounds.x && emitter.collideLeft) - { - this.x = bounds.x; - this.velocityX *= bounce; - } - else if (this.x > bounds.right && emitter.collideRight) - { - this.x = bounds.right; - this.velocityX *= bounce; - } - - if (this.y < bounds.y && emitter.collideTop) - { - this.y = bounds.y; - this.velocityY *= bounce; - } - else if (this.y > bounds.bottom && emitter.collideBottom) - { - this.y = bounds.bottom; - this.velocityY *= bounce; - } - }, - - /** - * The main update method for this Particle. - * - * Updates its life values, computes the velocity and repositions the Particle. - * - * @method Phaser.GameObjects.Particles.Particle#update - * @since 3.0.0 - * - * @param {number} delta - The delta time in ms. - * @param {number} step - The delta value divided by 1000. - * @param {array} processors - An optional array of update processors. - * - * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. - */ - update: function (delta, step, processors) - { - if (this.delayCurrent > 0) - { - this.delayCurrent -= delta; - - return false; - } - - var emitter = this.emitter; - - // How far along in life is this particle? (t = 0 to 1) - var t = 1 - (this.lifeCurrent / this.life); - - this.lifeT = t; - - this.computeVelocity(emitter, delta, step, processors); - - this.x += this.velocityX * step; - this.y += this.velocityY * step; - - if (emitter.bounds) - { - this.checkBounds(emitter); - } - - if (emitter.deathZone && emitter.deathZone.willKill(this)) - { - this.lifeCurrent = 0; - - // No need to go any further, particle has been killed - return true; - } - - this.scaleX = emitter.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); - - if (emitter.scaleY) - { - this.scaleY = emitter.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); - } - else - { - this.scaleY = this.scaleX; - } - - this.angle = emitter.rotate.onUpdate(this, 'rotate', t, this.angle); - this.rotation = DegToRad(this.angle); - - this.alpha = emitter.alpha.onUpdate(this, 'alpha', t, this.alpha); - - this.tint = emitter.tint.onUpdate(this, 'tint', t, this.tint); - - this.lifeCurrent -= delta; - - return (this.lifeCurrent <= 0); - } - -}); - -module.exports = Particle; - - -/***/ }), -/* 430 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BlendModes = __webpack_require__(38); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DeathZone = __webpack_require__(431); -var EdgeZone = __webpack_require__(432); -var EmitterOp = __webpack_require__(427); -var GetFastValue = __webpack_require__(2); -var GetRandom = __webpack_require__(205); -var HasAny = __webpack_require__(433); -var HasValue = __webpack_require__(125); -var Particle = __webpack_require__(429); -var RandomZone = __webpack_require__(434); -var Rectangle = __webpack_require__(10); -var StableSort = __webpack_require__(79); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * A particle emitter represents a single particle stream. - * It controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles} and is controlled by a {@link Phaser.GameObjects.Particles.ParticleEmitterManager Particle Emitter Manager}. - * - * @class ParticleEmitter - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} manager - The Emitter Manager this Emitter belongs to. - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. - */ -var ParticleEmitter = new Class({ - - Mixins: [ - Components.BlendMode, - Components.Mask, - Components.ScrollFactor, - Components.Visible - ], - - initialize: - - function ParticleEmitter (manager, config) - { - /** - * The Emitter Manager this Emitter belongs to. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#manager - * @type {Phaser.GameObjects.Particles.ParticleEmitterManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * The texture assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 - */ - this.texture = manager.texture; - - /** - * The texture frames assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frames - * @type {Phaser.Textures.Frame[]} - * @since 3.0.0 - */ - this.frames = [ manager.defaultFrame ]; - - /** - * The default texture frame assigned to particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#defaultFrame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 - */ - this.defaultFrame = manager.defaultFrame; - - /** - * Names of simple configuration properties. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configFastMap - * @type {object} - * @since 3.0.0 - */ - this.configFastMap = [ - 'active', - 'blendMode', - 'collideBottom', - 'collideLeft', - 'collideRight', - 'collideTop', - 'deathCallback', - 'deathCallbackScope', - 'emitCallback', - 'emitCallbackScope', - 'follow', - 'frequency', - 'gravityX', - 'gravityY', - 'maxParticles', - 'name', - 'on', - 'particleBringToTop', - 'particleClass', - 'radial', - 'timeScale', - 'trackVisible', - 'visible' - ]; - - /** - * Names of complex configuration properties. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configOpMap - * @type {object} - * @since 3.0.0 - */ - this.configOpMap = [ - 'accelerationX', - 'accelerationY', - 'angle', - 'alpha', - 'bounce', - 'delay', - 'lifespan', - 'maxVelocityX', - 'maxVelocityY', - 'moveToX', - 'moveToY', - 'quantity', - 'rotate', - 'scaleX', - 'scaleY', - 'speedX', - 'speedY', - 'tint', - 'x', - 'y' - ]; - - /** - * The name of this Particle Emitter. - * - * Empty by default and never populated by Phaser, this is left for developers to use. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#name - * @type {string} - * @default '' - * @since 3.0.0 - */ - this.name = ''; - - /** - * The Particle Class which will be emitted by this Emitter. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass - * @type {Phaser.GameObjects.Particles.Particle} - * @default Phaser.GameObjects.Particles.Particle - * @since 3.0.0 - */ - this.particleClass = Particle; - - /** - * The x-coordinate of the particle origin (where particles will be emitted). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#x - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition - */ - this.x = new EmitterOp(config, 'x', 0, true); - - /** - * The y-coordinate of the particle origin (where particles will be emitted). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#y - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition - */ - this.y = new EmitterOp(config, 'y', 0, true); - - /** - * A radial emitter will emit particles in all directions between angle min and max, - * using {@link Phaser.GameObjects.Particles.ParticleEmitter#speed} as the value. If set to false then this acts as a point Emitter. - * A point emitter will emit particles only in the direction derived from the speedX and speedY values. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#radial - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial - */ - this.radial = true; - - /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity - */ - this.gravityX = 0; - - /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity - */ - this.gravityY = 0; - - /** - * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#acceleration - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.acceleration = false; - - /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.accelerationX = new EmitterOp(config, 'accelerationX', 0, true); - - /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.accelerationY = new EmitterOp(config, 'accelerationY', 0, true); - - /** - * The maximum horizontal velocity of emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityX = new EmitterOp(config, 'maxVelocityX', 10000, true); - - /** - * The maximum vertical velocity of emitted particles, in pixels per second squared. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 10000 - * @since 3.0.0 - */ - this.maxVelocityY = new EmitterOp(config, 'maxVelocityY', 10000, true); - - /** - * The initial horizontal speed of emitted particles, in pixels per second. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#speedX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX - */ - this.speedX = new EmitterOp(config, 'speedX', 0, true); - - /** - * The initial vertical speed of emitted particles, in pixels per second. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#speedY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY - */ - this.speedY = new EmitterOp(config, 'speedY', 0, true); - - /** - * Whether moveToX and moveToY are nonzero. Set automatically during configuration. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveTo - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.moveTo = false; - - /** - * The x-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.moveToX = new EmitterOp(config, 'moveToX', 0, true); - - /** - * The y-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.moveToY = new EmitterOp(config, 'moveToY', 0, true); - - /** - * Whether particles will rebound when they meet the emitter bounds. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#bounce - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.bounce = new EmitterOp(config, 'bounce', 0, true); - - /** - * The horizontal scale of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleX - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleX - */ - this.scaleX = new EmitterOp(config, 'scaleX', 1); - - /** - * The vertical scale of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleY - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleY - */ - this.scaleY = new EmitterOp(config, 'scaleY', 1); - - /** - * Color tint applied to emitted particles. Value must not include the alpha channel. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#tint - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0xffffff - * @since 3.0.0 - */ - this.tint = new EmitterOp(config, 'tint', 0xffffff); - - /** - * The alpha (transparency) of emitted particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#alpha - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setAlpha - */ - this.alpha = new EmitterOp(config, 'alpha', 1); - - /** - * The lifespan of emitted particles, in ms. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1000 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setLifespan - */ - this.lifespan = new EmitterOp(config, 'lifespan', 1000, true); - - /** - * The angle of the initial velocity of emitted particles, in degrees. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#angle - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default { min: 0, max: 360 } - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setAngle - */ - this.angle = new EmitterOp(config, 'angle', { min: 0, max: 360 }, true); - - /** - * The rotation of emitted particles, in degrees. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#rotate - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.rotate = new EmitterOp(config, 'rotate', 0); - - /** - * A function to call when a particle is emitted. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallback - * @type {?Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} - * @default null - * @since 3.0.0 - */ - this.emitCallback = null; - - /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallbackScope - * @type {?*} - * @default null - * @since 3.0.0 - */ - this.emitCallbackScope = null; - - /** - * A function to call when a particle dies. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallback - * @type {?Phaser.Types.GameObjects.Particles.ParticleDeathCallback} - * @default null - * @since 3.0.0 - */ - this.deathCallback = null; - - /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallbackScope - * @type {?*} - * @default null - * @since 3.0.0 - */ - this.deathCallbackScope = null; - - /** - * Set to hard limit the amount of particle objects this emitter is allowed to create. - * 0 means unlimited. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#maxParticles - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxParticles = 0; - - /** - * How many particles are emitted each time particles are emitted (one explosion or one flow cycle). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#quantity - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - * @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity - */ - this.quantity = new EmitterOp(config, 'quantity', 1, true); - - /** - * How many ms to wait after emission before the particles start updating. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#delay - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - */ - this.delay = new EmitterOp(config, 'delay', 0, true); - - /** - * For a flow emitter, the time interval (>= 0) between particle flow cycles in ms. - * A value of 0 means there is one particle flow cycle for each logic update (the maximum flow frequency). This is the default setting. - * For an exploding emitter, this value will be -1. - * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} also puts the emitter in flow mode (frequency >= 0). - * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} also puts the emitter in explode mode (frequency = -1). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frequency - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - */ - this.frequency = 0; - - /** - * Controls if the emitter is currently emitting a particle flow (when frequency >= 0). - * Already alive particles will continue to update until they expire. - * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#start} and {@link Phaser.GameObjects.Particles.ParticleEmitter#stop}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#on - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.on = true; - - /** - * Newly emitted particles are added to the top of the particle list, i.e. rendered above those already alive. - * Set to false to send them to the back. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.particleBringToTop = true; - - /** - * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * An object describing a shape to emit particles from. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#emitZone - * @type {?Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone - */ - this.emitZone = null; - - /** - * An object describing a shape that deactivates particles when they interact with it. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#deathZone - * @type {?Phaser.GameObjects.Particles.Zones.DeathZone} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone - */ - this.deathZone = null; - - /** - * A rectangular boundary constraining particle movement. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#bounds - * @type {?Phaser.Geom.Rectangle} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setBounds - */ - this.bounds = null; - - /** - * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideLeft - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideLeft = true; - - /** - * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideRight - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideRight = true; - - /** - * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideTop - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideTop = true; - - /** - * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#collideBottom - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.collideBottom = true; - - /** - * Whether this emitter updates itself and its particles. - * - * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#pause} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#resume}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Set this to false to hide any active particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#visible - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setVisible - */ - this.visible = true; - - /** - * The blend mode of this emitter's particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#blendMode - * @type {number} - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setBlendMode - */ - this.blendMode = BlendModes.NORMAL; - - /** - * A Game Object whose position is used as the particle origin. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#follow - * @type {?Phaser.GameObjects.GameObject} - * @default null - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - * @see Phaser.GameObjects.Particles.ParticleEmitter#stopFollow - */ - this.follow = null; - - /** - * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#followOffset - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - */ - this.followOffset = new Vector2(); - - /** - * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track - * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#trackVisible - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow - */ - this.trackVisible = false; - - /** - * The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.currentFrame = 0; - - /** - * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#randomFrame - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.randomFrame = true; - - /** - * The number of consecutive particles that receive a single texture frame (per frame cycle). - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity - * @type {number} - * @default 1 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame - */ - this.frameQuantity = 1; - - /** - * Inactive particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#dead - * @type {Phaser.GameObjects.Particles.Particle[]} - * @private - * @since 3.0.0 - */ - this.dead = []; - - /** - * Active particles - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#alive - * @type {Phaser.GameObjects.Particles.Particle[]} - * @private - * @since 3.0.0 - */ - this.alive = []; - - /** - * The time until the next flow cycle. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#_counter - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._counter = 0; - - /** - * Counts up to {@link Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity}. - * - * @name Phaser.GameObjects.Particles.ParticleEmitter#_frameCounter - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._frameCounter = 0; - - if (config) - { - this.fromJSON(config); - } - }, - - /** - * Merges configuration settings into the emitter's current settings. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#fromJSON - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. - * - * @return {this} This Particle Emitter. - */ - fromJSON: function (config) - { - if (!config) - { - return this; - } - - // Only update properties from their current state if they exist in the given config - - var i = 0; - var key = ''; - - for (i = 0; i < this.configFastMap.length; i++) - { - key = this.configFastMap[i]; - - if (HasValue(config, key)) - { - this[key] = GetFastValue(config, key); - } - } - - for (i = 0; i < this.configOpMap.length; i++) - { - key = this.configOpMap[i]; - - if (HasValue(config, key)) - { - this[key].loadConfig(config); - } - } - - this.acceleration = (this.accelerationX.propertyValue !== 0 || this.accelerationY.propertyValue !== 0); - - this.moveTo = (this.moveToX.propertyValue !== 0 || this.moveToY.propertyValue !== 0); - - // Special 'speed' override - - if (HasValue(config, 'speed')) - { - this.speedX.loadConfig(config, 'speed'); - this.speedY = null; - } - - // If you specify speedX, speedY or moveTo then it changes the emitter from radial to a point emitter - if (HasAny(config, [ 'speedX', 'speedY' ]) || this.moveTo) - { - this.radial = false; - } - - // Special 'scale' override - - if (HasValue(config, 'scale')) - { - this.scaleX.loadConfig(config, 'scale'); - this.scaleY = null; - } - - if (HasValue(config, 'callbackScope')) - { - var callbackScope = GetFastValue(config, 'callbackScope', null); - - this.emitCallbackScope = callbackScope; - this.deathCallbackScope = callbackScope; - } - - if (HasValue(config, 'emitZone')) - { - this.setEmitZone(config.emitZone); - } - - if (HasValue(config, 'deathZone')) - { - this.setDeathZone(config.deathZone); - } - - if (HasValue(config, 'bounds')) - { - this.setBounds(config.bounds); - } - - if (HasValue(config, 'followOffset')) - { - this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); - } - - if (HasValue(config, 'frame')) - { - this.setFrame(config.frame); - } - - if (HasValue(config, 'reserve')) - { - this.reserve(config.reserve); - } - - return this; - }, - - /** - * Creates a description of this emitter suitable for JSON serialization. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON - * @since 3.0.0 - * - * @param {object} [output] - An object to copy output into. - * - * @return {object} - The output object. - */ - toJSON: function (output) - { - if (output === undefined) { output = {}; } - - var i = 0; - var key = ''; - - for (i = 0; i < this.configFastMap.length; i++) - { - key = this.configFastMap[i]; - - output[key] = this[key]; - } - - for (i = 0; i < this.configOpMap.length; i++) - { - key = this.configOpMap[i]; - - if (this[key]) - { - output[key] = this[key].toJSON(); - } - } - - // special handlers - if (!this.speedY) - { - delete output.speedX; - output.speed = this.speedX.toJSON(); - } - - if (!this.scaleY) - { - delete output.scaleX; - output.scale = this.scaleX.toJSON(); - } - - return output; - }, - - /** - * Continuously moves the particle origin to follow a Game Object's position. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} target - The Game Object to follow. - * @param {number} [offsetX=0] - Horizontal offset of the particle origin from the Game Object. - * @param {number} [offsetY=0] - Vertical offset of the particle origin from the Game Object. - * @param {boolean} [trackVisible=false] - Whether the emitter's visible state will track the target's visible state. - * - * @return {this} This Particle Emitter. - */ - startFollow: function (target, offsetX, offsetY, trackVisible) - { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - if (trackVisible === undefined) { trackVisible = false; } - - this.follow = target; - this.followOffset.set(offsetX, offsetY); - this.trackVisible = trackVisible; - - return this; - }, - - /** - * Stops following a Game Object. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - stopFollow: function () - { - this.follow = null; - this.followOffset.set(0, 0); - this.trackVisible = false; - - return this; - }, - - /** - * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame - * @since 3.0.0 - * - * @return {Phaser.Textures.Frame} The texture frame. - */ - getFrame: function () - { - if (this.frames.length === 1) - { - return this.defaultFrame; - } - else if (this.randomFrame) - { - return GetRandom(this.frames); - } - else - { - var frame = this.frames[this.currentFrame]; - - this._frameCounter++; - - if (this._frameCounter === this.frameQuantity) - { - this._frameCounter = 0; - this.currentFrame = Wrap(this.currentFrame + 1, 0, this._frameLength); - } - - return frame; - } - }, - - // frame: 0 - // frame: 'red' - // frame: [ 0, 1, 2, 3 ] - // frame: [ 'red', 'green', 'blue', 'pink', 'white' ] - // frame: { frames: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } - - /** - * Sets a pattern for assigning texture frames to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrame - * @since 3.0.0 - * - * @param {(array|string|number|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} frames - One or more texture frames, or a configuration object. - * @param {boolean} [pickRandom=true] - Whether frames should be assigned at random from `frames`. - * @param {number} [quantity=1] - The number of consecutive particles that will receive each frame. - * - * @return {this} This Particle Emitter. - */ - setFrame: function (frames, pickRandom, quantity) - { - if (pickRandom === undefined) { pickRandom = true; } - if (quantity === undefined) { quantity = 1; } - - this.randomFrame = pickRandom; - this.frameQuantity = quantity; - this.currentFrame = 0; - this._frameCounter = 0; - - var t = typeof (frames); - - if (Array.isArray(frames) || t === 'string' || t === 'number') - { - this.manager.setEmitterFrames(frames, this); - } - else if (t === 'object') - { - var frameConfig = frames; - - frames = GetFastValue(frameConfig, 'frames', null); - - if (frames) - { - this.manager.setEmitterFrames(frames, this); - } - - var isCycle = GetFastValue(frameConfig, 'cycle', false); - - this.randomFrame = (isCycle) ? false : true; - - this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); - } - - this._frameLength = this.frames.length; - - if (this._frameLength === 1) - { - this.frameQuantity = 1; - this.randomFrame = false; - } - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial - * @since 3.0.0 - * - * @param {boolean} [value=true] - Radial mode (true) or point mode (true). - * - * @return {this} This Particle Emitter. - */ - setRadial: function (value) - { - if (value === undefined) { value = true; } - - this.radial = value; - - return this; - }, - - /** - * Sets the position of the emitter's particle origin. - * New particles will be emitted here. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setPosition - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} x - The x-coordinate of the particle origin. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} y - The y-coordinate of the particle origin. - * - * @return {this} This Particle Emitter. - */ - setPosition: function (x, y) - { - this.x.onChange(x); - this.y.onChange(y); - - return this; - }, - - /** - * Sets or modifies a rectangular boundary constraining the particles. - * - * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setBounds - * @since 3.0.0 - * - * @param {(number|Phaser.Types.GameObjects.Particles.ParticleEmitterBounds|Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt)} x - The x-coordinate of the left edge of the boundary, or an object representing a rectangle. - * @param {number} y - The y-coordinate of the top edge of the boundary. - * @param {number} width - The width of the boundary. - * @param {number} height - The height of the boundary. - * - * @return {this} This Particle Emitter. - */ - setBounds: function (x, y, width, height) - { - if (typeof x === 'object') - { - var obj = x; - - x = obj.x; - y = obj.y; - width = (HasValue(obj, 'w')) ? obj.w : obj.width; - height = (HasValue(obj, 'h')) ? obj.h : obj.height; - } - - if (this.bounds) - { - this.bounds.setTo(x, y, width, height); - } - else - { - this.bounds = new Rectangle(x, y, width, height); - } - - return this; - }, - - /** - * Sets the initial horizontal speed of emitted particles. - * Changes the emitter to point mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeedX: function (value) - { - this.speedX.onChange(value); - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = false; - - return this; - }, - - /** - * Sets the initial vertical speed of emitted particles. - * Changes the emitter to point mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeedY: function (value) - { - if (this.speedY) - { - this.speedY.onChange(value); - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = false; - } - - return this; - }, - - /** - * Sets the initial radial speed of emitted particles. - * Changes the emitter to radial mode. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeed - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. - * - * @return {this} This Particle Emitter. - */ - setSpeed: function (value) - { - this.speedX.onChange(value); - this.speedY = null; - - // If you specify speedX and Y then it changes the emitter from radial to a point emitter - this.radial = true; - - return this; - }, - - /** - * Sets the horizontal scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleX - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScaleX: function (value) - { - this.scaleX.onChange(value); - - return this; - }, - - /** - * Sets the vertical scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleY - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScaleY: function (value) - { - this.scaleY.onChange(value); - - return this; - }, - - /** - * Sets the scale of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScale - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. - * - * @return {this} This Particle Emitter. - */ - setScale: function (value) - { - this.scaleX.onChange(value); - this.scaleY = null; - - return this; - }, - - /** - * Sets the horizontal gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityX - * @since 3.0.0 - * - * @param {number} value - Acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravityX: function (value) - { - this.gravityX = value; - - return this; - }, - - /** - * Sets the vertical gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityY - * @since 3.0.0 - * - * @param {number} value - Acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravityY: function (value) - { - this.gravityY = value; - - return this; - }, - - /** - * Sets the gravity applied to emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravity - * @since 3.0.0 - * - * @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. - * @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. - * - * @return {this} This Particle Emitter. - */ - setGravity: function (x, y) - { - this.gravityX = x; - this.gravityY = y; - - return this; - }, - - /** - * Sets the opacity of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAlpha - * @since 3.0.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 (transparent) and 1 (opaque). - * - * @return {this} This Particle Emitter. - */ - setAlpha: function (value) - { - this.alpha.onChange(value); - - return this; - }, - - /** - * Sets the color tint of emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setTint - * @since 3.22.0 - * - * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff. - * - * @return {this} This Particle Emitter. - */ - setTint: function (value) - { - this.tint.onChange(value); - - return this; - }, - - /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. - * - * @return {this} This Particle Emitter. - */ - setEmitterAngle: function (value) - { - this.angle.onChange(value); - - return this; - }, - - /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAngle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. - * - * @return {this} This Particle Emitter. - */ - setAngle: function (value) - { - this.angle.onChange(value); - - return this; - }, - - /** - * Sets the lifespan of newly emitted particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setLifespan - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The particle lifespan, in ms. - * - * @return {this} This Particle Emitter. - */ - setLifespan: function (value) - { - this.lifespan.onChange(value); - - return this; - }, - - /** - * Sets the number of particles released at each flow cycle or explosion. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} quantity - The number of particles to release at each flow cycle or explosion. - * - * @return {this} This Particle Emitter. - */ - setQuantity: function (quantity) - { - this.quantity.onChange(quantity); - - return this; - }, - - /** - * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency - * @since 3.0.0 - * - * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [quantity] - The number of particles to release at each flow cycle or explosion. - * - * @return {this} This Particle Emitter. - */ - setFrequency: function (frequency, quantity) - { - this.frequency = frequency; - - this._counter = 0; - - if (quantity) - { - this.quantity.onChange(quantity); - } - - return this; - }, - - /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#emitZone}. - * - * An {@link Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig EdgeZone} places particles on its edges. Its {@link Phaser.Types.GameObjects.Particles.EdgeZoneSource source} can be a Curve, Path, Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback getPoints} method. - * - * A {@link Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig RandomZone} places randomly within its interior. Its {@link RandomZoneSource source} can be a Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.RandomZoneSourceCallback getRandomPoint} method. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current emit zone. - * - * @return {this} This Particle Emitter. - */ - setEmitZone: function (zoneConfig) - { - if (zoneConfig === undefined) - { - this.emitZone = null; - } - else - { - // Where source = Geom like Circle, or a Path or Curve - // emitZone: { type: 'random', source: X } - // emitZone: { type: 'edge', source: X, quantity: 32, [stepRate=0], [yoyo=false], [seamless=true] } - - var type = GetFastValue(zoneConfig, 'type', 'random'); - var source = GetFastValue(zoneConfig, 'source', null); - - switch (type) - { - case 'random': - - this.emitZone = new RandomZone(source); - - break; - - case 'edge': - - var quantity = GetFastValue(zoneConfig, 'quantity', 1); - var stepRate = GetFastValue(zoneConfig, 'stepRate', 0); - var yoyo = GetFastValue(zoneConfig, 'yoyo', false); - var seamless = GetFastValue(zoneConfig, 'seamless', true); - - this.emitZone = new EdgeZone(source, quantity, stepRate, yoyo, seamless); - - break; - } - } - - return this; - }, - - /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current death zone. - * - * @return {this} This Particle Emitter. - */ - setDeathZone: function (zoneConfig) - { - if (zoneConfig === undefined) - { - this.deathZone = null; - } - else - { - // Where source = Geom like Circle or Rect that supports a 'contains' function - // deathZone: { type: 'onEnter', source: X } - // deathZone: { type: 'onLeave', source: X } - - var type = GetFastValue(zoneConfig, 'type', 'onEnter'); - var source = GetFastValue(zoneConfig, 'source', null); - - if (source && typeof source.contains === 'function') - { - var killOnEnter = (type === 'onEnter') ? true : false; - - this.deathZone = new DeathZone(source, killOnEnter); - } - } - - return this; - }, - - /** - * Creates inactive particles and adds them to this emitter's pool. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve - * @since 3.0.0 - * - * @param {number} particleCount - The number of particles to create. - * - * @return {this} This Particle Emitter. - */ - reserve: function (particleCount) - { - var dead = this.dead; - - for (var i = 0; i < particleCount; i++) - { - dead.push(new this.particleClass(this)); - } - - return this; - }, - - /** - * Gets the number of active (in-use) particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles with `active=true`. - */ - getAliveParticleCount: function () - { - return this.alive.length; - }, - - /** - * Gets the number of inactive (available) particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles with `active=false`. - */ - getDeadParticleCount: function () - { - return this.dead.length; - }, - - /** - * Gets the total number of particles in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount - * @since 3.0.0 - * - * @return {number} The number of particles, including both alive and dead. - */ - getParticleCount: function () - { - return this.getAliveParticleCount() + this.getDeadParticleCount(); - }, - - /** - * Whether this emitter is at its limit (if set). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit - * @since 3.0.0 - * - * @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level. - */ - atLimit: function () - { - return (this.maxParticles > 0 && this.getParticleCount() === this.maxParticles); - }, - - /** - * Sets a function to call for each newly emitted particle. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} [context] - The calling context. - * - * @return {this} This Particle Emitter. - */ - onParticleEmit: function (callback, context) - { - if (callback === undefined) - { - // Clear any previously set callback - this.emitCallback = null; - this.emitCallbackScope = null; - } - else if (typeof callback === 'function') - { - this.emitCallback = callback; - - if (context) - { - this.emitCallbackScope = context; - } - } - - return this; - }, - - /** - * Sets a function to call for each particle death. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleDeathCallback} callback - The function. - * @param {*} [context] - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - onParticleDeath: function (callback, context) - { - if (callback === undefined) - { - // Clear any previously set callback - this.deathCallback = null; - this.deathCallbackScope = null; - } - else if (typeof callback === 'function') - { - this.deathCallback = callback; - - if (context) - { - this.deathCallbackScope = context; - } - } - - return this; - }, - - /** - * Deactivates every particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - killAll: function () - { - var dead = this.dead; - var alive = this.alive; - - while (alive.length > 0) - { - dead.push(alive.pop()); - } - - return this; - }, - - /** - * Calls a function for each active particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} context - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - forEachAlive: function (callback, context) - { - var alive = this.alive; - var length = alive.length; - - for (var index = 0; index < length; ++index) - { - // Sends the Particle and the Emitter - callback.call(context, alive[index], this); - } - - return this; - }, - - /** - * Calls a function for each inactive particle in this emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. - * @param {*} context - The function's calling context. - * - * @return {this} This Particle Emitter. - */ - forEachDead: function (callback, context) - { - var dead = this.dead; - var length = dead.length; - - for (var index = 0; index < length; ++index) - { - // Sends the Particle and the Emitter - callback.call(context, dead[index], this); - } - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on} the emitter and resets the flow counter. - * - * If this emitter is in flow mode (frequency >= 0; the default), the particle flow will start (or restart). - * - * If this emitter is in explode mode (frequency = -1), nothing will happen. - * Use {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} or {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} instead. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#start - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - start: function () - { - this.on = true; - - this._counter = 0; - - return this; - }, - - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stop - * @since 3.11.0 - * - * @return {this} This Particle Emitter. - */ - stop: function () - { - this.on = false; - - return this; - }, - - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#pause - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - pause: function () - { - this.active = false; - - return this; - }, - - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#resume - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - resume: function () - { - this.active = true; - - return this; - }, - - /** - * Removes the emitter from its manager and the scene. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#remove - * @since 3.22.0 - * - * @return {this} This Particle Emitter. - */ - remove: function () - { - this.manager.removeEmitter(this); - - return this; - }, - - /** - * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort - * @since 3.0.0 - * - * @return {this} This Particle Emitter. - */ - depthSort: function () - { - StableSort(this.alive, this.depthSortCallback); - - return this; - }, - - /** - * Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow. - * - * To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#flow - * @since 3.0.0 - * - * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms. - * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [count=1] - The number of particles to emit at each flow cycle. - * - * @return {this} This Particle Emitter. - */ - flow: function (frequency, count) - { - if (count === undefined) { count = 1; } - - this.frequency = frequency; - - this.quantity.onChange(count); - - return this.start(); - }, - - /** - * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#explode - * @since 3.0.0 - * - * @param {number} count - The amount of Particles to emit. - * @param {number} x - The x coordinate to emit the Particles from. - * @param {number} y - The y coordinate to emit the Particles from. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - */ - explode: function (count, x, y) - { - this.frequency = -1; - - return this.emitParticle(count, x, y); - }, - - /** - * Emits particles at a given position (or the emitter's current position). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt - * @since 3.0.0 - * - * @param {number} [x=this.x] - The x coordinate to emit the Particles from. - * @param {number} [y=this.x] - The y coordinate to emit the Particles from. - * @param {number} [count=this.quantity] - The number of Particles to emit. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - */ - emitParticleAt: function (x, y, count) - { - return this.emitParticle(count, x, y); - }, - - /** - * Emits particles at a given position (or the emitter's current position). - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle - * @since 3.0.0 - * - * @param {number} [count=this.quantity] - The number of Particles to emit. - * @param {number} [x=this.x] - The x coordinate to emit the Particles from. - * @param {number} [y=this.x] - The y coordinate to emit the Particles from. - * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. - * - * @see Phaser.GameObjects.Particles.Particle#fire - */ - emitParticle: function (count, x, y) - { - if (this.atLimit()) - { - return; - } - - if (count === undefined) - { - count = this.quantity.onEmit(); - } - - var dead = this.dead; - - var followX = (this.follow) ? this.follow.x + this.followOffset.x : x; - var followY = (this.follow) ? this.follow.y + this.followOffset.y : y; - - for (var i = 0; i < count; i++) - { - var particle = dead.pop(); - - if (!particle) - { - particle = new this.particleClass(this); - } - - particle.fire(followX, followY); - - if (this.particleBringToTop) - { - this.alive.push(particle); - } - else - { - this.alive.unshift(particle); - } - - if (this.emitCallback) - { - this.emitCallback.call(this.emitCallbackScope, particle, this); - } - - if (this.atLimit()) - { - break; - } - } - - return particle; - }, - - /** - * Updates this emitter and its particles. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - preUpdate: function (time, delta) - { - // Scale the delta - delta *= this.timeScale; - - var step = (delta / 1000); - - if (this.trackVisible) - { - this.visible = this.follow.visible; - } - - // Any particle processors? - var processors = this.manager.getProcessors(); - - var particles = this.alive; - var dead = this.dead; - - var i = 0; - var rip = []; - var length = particles.length; - - for (i = 0; i < length; i++) - { - var particle = particles[i]; - - // update returns `true` if the particle is now dead (lifeCurrent <= 0) - if (particle.update(delta, step, processors)) - { - rip.push({ index: i, particle: particle }); - } - } - - // Move dead particles to the dead array - length = rip.length; - - if (length > 0) - { - var deathCallback = this.deathCallback; - var deathCallbackScope = this.deathCallbackScope; - - for (i = length - 1; i >= 0; i--) - { - var entry = rip[i]; - - // Remove from particles array - particles.splice(entry.index, 1); - - // Add to dead array - dead.push(entry.particle); - - // Callback - if (deathCallback) - { - deathCallback.call(deathCallbackScope, entry.particle); - } - - entry.particle.resetPosition(); - } - } - - if (!this.on) - { - return; - } - - if (this.frequency === 0) - { - this.emitParticle(); - } - else if (this.frequency > 0) - { - this._counter -= delta; - - if (this._counter <= 0) - { - this.emitParticle(); - - // counter = frequency - remained from previous delta - this._counter = (this.frequency - Math.abs(this._counter)); - } - } - }, - - /** - * Calculates the difference of two particles, for sorting them by depth. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback - * @since 3.0.0 - * - * @param {object} a - The first particle. - * @param {object} b - The second particle. - * - * @return {number} The difference of a and b's y coordinates. - */ - depthSortCallback: function (a, b) - { - return a.y - b.y; - } - -}); - -module.exports = ParticleEmitter; - - -/***/ }), -/* 431 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A Death Zone. - * - * A Death Zone is a special type of zone that will kill a Particle as soon as it either enters, or leaves, the zone. - * - * The zone consists of a `source` which could be a Geometric shape, such as a Rectangle or Ellipse, or your own - * object as long as it includes a `contains` method for which the Particles can be tested against. - * - * @class DeathZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.DeathZoneSource} source - An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. - * @param {boolean} killOnEnter - Should the Particle be killed when it enters the zone? `true` or leaves it? `false` - */ -var DeathZone = new Class({ - - initialize: - - function DeathZone (source, killOnEnter) - { - /** - * An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. - * This could be a Geometry shape, such as `Phaser.Geom.Circle`, or your own custom object. - * - * @name Phaser.GameObjects.Particles.Zones.DeathZone#source - * @type {Phaser.Types.GameObjects.Particles.DeathZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * Set to `true` if the Particle should be killed if it enters this zone. - * Set to `false` to kill the Particle if it leaves this zone. - * - * @name Phaser.GameObjects.Particles.Zones.DeathZone#killOnEnter - * @type {boolean} - * @since 3.0.0 - */ - this.killOnEnter = killOnEnter; - }, - - /** - * Checks if the given Particle will be killed or not by this zone. - * - * @method Phaser.GameObjects.Particles.Zones.DeathZone#willKill - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to be checked against this zone. - * - * @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`. - */ - willKill: function (particle) - { - var withinZone = this.source.contains(particle.x, particle.y); - - return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); - } - -}); - -module.exports = DeathZone; - - -/***/ }), -/* 432 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * A zone that places particles on a shape's edges. - * - * @class EdgeZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * @param {number} quantity - The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - * @param {number} stepRate - The distance between each particle. When set, `quantity` is implied and should be set to 0. - * @param {boolean} [yoyo=false] - Whether particles are placed from start to end and then end to start. - * @param {boolean} [seamless=true] - Whether one endpoint will be removed if it's identical to the other. - */ -var EdgeZone = new Class({ - - initialize: - - function EdgeZone (source, quantity, stepRate, yoyo, seamless) - { - if (yoyo === undefined) { yoyo = false; } - if (seamless === undefined) { seamless = true; } - - /** - * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source - * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * The points placed on the source edge. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points - * @type {Phaser.Geom.Point[]} - * @default [] - * @since 3.0.0 - */ - this.points = []; - - /** - * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#quantity - * @type {number} - * @since 3.0.0 - */ - this.quantity = quantity; - - /** - * The distance between each particle. When set, `quantity` is implied and should be set to 0. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#stepRate - * @type {number} - * @since 3.0.0 - */ - this.stepRate = stepRate; - - /** - * Whether particles are placed from start to end and then end to start. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#yoyo - * @type {boolean} - * @since 3.0.0 - */ - this.yoyo = yoyo; - - /** - * The counter used for iterating the EdgeZone's points. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.counter = -1; - - /** - * Whether one endpoint will be removed if it's identical to the other. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless - * @type {boolean} - * @since 3.0.0 - */ - this.seamless = seamless; - - /** - * An internal count of the points belonging to this EdgeZone. - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_length - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._length = 0; - - /** - * An internal value used to keep track of the current iteration direction for the EdgeZone's points. - * - * 0 = forwards, 1 = backwards - * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_direction - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._direction = 0; - - this.updateSource(); - }, - - /** - * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's - * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. - * - * Also updates internal properties. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource - * @since 3.0.0 - * - * @return {this} This Edge Zone. - */ - updateSource: function () - { - this.points = this.source.getPoints(this.quantity, this.stepRate); - - // Remove ends? - if (this.seamless) - { - var a = this.points[0]; - var b = this.points[this.points.length - 1]; - - if (a.x === b.x && a.y === b.y) - { - this.points.pop(); - } - } - - var oldLength = this._length; - - this._length = this.points.length; - - // Adjust counter if we now have less points than before - if (this._length < oldLength && this.counter > this._length) - { - this.counter = this._length - 1; - } - - return this; - }, - - /** - * Change the source of the EdgeZone. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * - * @return {this} This Edge Zone. - */ - changeSource: function (source) - { - this.source = source; - - return this.updateSource(); - }, - - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * - * @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. - */ - getPoint: function (particle) - { - if (this._direction === 0) - { - this.counter++; - - if (this.counter >= this._length) - { - if (this.yoyo) - { - this._direction = 1; - this.counter = this._length - 1; - } - else - { - this.counter = 0; - } - } - } - else - { - this.counter--; - - if (this.counter === -1) - { - if (this.yoyo) - { - this._direction = 0; - this.counter = 0; - } - else - { - this.counter = this._length - 1; - } - } - } - - var point = this.points[this.counter]; - - if (point) - { - particle.x = point.x; - particle.y = point.y; - } - } - -}); - -module.exports = EdgeZone; - - -/***/ }), -/* 433 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Verifies that an object contains at least one of the requested keys - * - * @function Phaser.Utils.Objects.HasAny - * @since 3.0.0 - * - * @param {object} source - an object on which to check for key existence - * @param {string[]} keys - an array of keys to search the object for - * - * @return {boolean} true if the source object contains at least one of the keys, false otherwise - */ -var HasAny = function (source, keys) -{ - for (var i = 0; i < keys.length; i++) - { - if (source.hasOwnProperty(keys[i])) - { - return true; - } - } - - return false; -}; - -module.exports = HasAny; - - -/***/ }), -/* 434 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A zone that places particles randomly within a shapes area. - * - * @class RandomZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Particles.RandomZoneSource} source - An object instance with a `getRandomPoint(point)` method. - */ -var RandomZone = new Class({ - - initialize: - - function RandomZone (source) - { - /** - * An object instance with a `getRandomPoint(point)` method. - * - * @name Phaser.GameObjects.Particles.Zones.RandomZone#source - * @type {Phaser.Types.GameObjects.Particles.RandomZoneSource} - * @since 3.0.0 - */ - this.source = source; - - /** - * Internal calculation vector. - * - * @name Phaser.GameObjects.Particles.Zones.RandomZone#_tempVec - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tempVec = new Vector2(); - }, - - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * - * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. - */ - getPoint: function (particle) - { - var vec = this._tempVec; - - this.source.getRandomPoint(vec); - - particle.x = vec.x; - particle.y = vec.y; - } - -}); - -module.exports = RandomZone; - - -/***/ }), -/* 435 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var Sprite = __webpack_require__(73); - -/** - * @classdesc - * A PathFollower Game Object. - * - * A PathFollower is a Sprite Game Object with some extra helpers to allow it to follow a Path automatically. - * - * Anything you can do with a standard Sprite can be done with this PathFollower, such as animate it, tint it, - * scale it and so on. - * - * PathFollowers are bound to a single Path at any one time and can traverse the length of the Path, from start - * to finish, forwards or backwards, or from any given point on the Path to its end. They can optionally rotate - * to face the direction of the path, be offset from the path coordinates or rotate independently of the Path. - * - * @class PathFollower - * @extends Phaser.GameObjects.Sprite - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.PathFollower - * - * @param {Phaser.Scene} scene - The Scene to which this PathFollower belongs. - * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. - * @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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - */ -var PathFollower = new Class({ - - Extends: Sprite, - - Mixins: [ - Components.PathFollower - ], - - initialize: - - function PathFollower (scene, path, x, y, texture, frame) - { - Sprite.call(this, scene, x, y, texture, frame); - - this.path = path; - }, - - /** - * 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.PathFollower#preUpdate - * @protected - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - preUpdate: function (time, delta) - { - this.anims.update(time, delta); - this.pathUpdate(time); - } - -}); - -module.exports = PathFollower; - - -/***/ }), -/* 436 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns an object containing dimensions of the Text object. - * - * @function Phaser.GameObjects.GetTextSize - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Text} text - The Text object to calculate the size from. - * @param {Phaser.Types.GameObjects.Text.TextMetrics} size - The Text metrics to use when calculating the size. - * @param {string[]} lines - The lines of text to calculate the size from. - * - * @return {Phaser.Types.GameObjects.Text.GetTextSizeObject} An object containing dimensions of the Text object. - */ -var GetTextSize = function (text, size, lines) -{ - var canvas = text.canvas; - var context = text.context; - var style = text.style; - - var lineWidths = []; - var maxLineWidth = 0; - var drawnLines = lines.length; - - if (style.maxLines > 0 && style.maxLines < lines.length) - { - drawnLines = style.maxLines; - } - - style.syncFont(canvas, context); - - // Text Width - - for (var i = 0; i < drawnLines; i++) - { - var lineWidth = style.strokeThickness; - - lineWidth += context.measureText(lines[i]).width; - - // Adjust for wrapped text - if (style.wordWrap) - { - lineWidth -= context.measureText(' ').width; - } - - lineWidths[i] = Math.ceil(lineWidth); - maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); - } - - // Text Height - - var lineHeight = size.fontSize + style.strokeThickness; - var height = lineHeight * drawnLines; - var lineSpacing = text.lineSpacing; - - // Adjust for line spacing - if (drawnLines > 1) - { - height += lineSpacing * (drawnLines - 1); - } - - return { - width: maxLineWidth, - height: height, - lines: drawnLines, - lineWidths: lineWidths, - lineSpacing: lineSpacing, - lineHeight: lineHeight - }; -}; - -module.exports = GetTextSize; - - -/***/ }), -/* 437 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetAdvancedValue = __webpack_require__(13); -var GetValue = __webpack_require__(6); -var MeasureText = __webpack_require__(438); - -// Key: [ Object Key, Default Value ] - -var propertyMap = { - fontFamily: [ 'fontFamily', 'Courier' ], - fontSize: [ 'fontSize', '16px' ], - fontStyle: [ 'fontStyle', '' ], - backgroundColor: [ 'backgroundColor', null ], - color: [ 'color', '#fff' ], - stroke: [ 'stroke', '#fff' ], - strokeThickness: [ 'strokeThickness', 0 ], - shadowOffsetX: [ 'shadow.offsetX', 0 ], - shadowOffsetY: [ 'shadow.offsetY', 0 ], - shadowColor: [ 'shadow.color', '#000' ], - shadowBlur: [ 'shadow.blur', 0 ], - shadowStroke: [ 'shadow.stroke', false ], - shadowFill: [ 'shadow.fill', false ], - align: [ 'align', 'left' ], - maxLines: [ 'maxLines', 0 ], - fixedWidth: [ 'fixedWidth', 0 ], - fixedHeight: [ 'fixedHeight', 0 ], - resolution: [ 'resolution', 0 ], - rtl: [ 'rtl', false ], - testString: [ 'testString', '|MÉqgy' ], - baselineX: [ 'baselineX', 1.2 ], - baselineY: [ 'baselineY', 1.4 ], - wordWrapWidth: [ 'wordWrap.width', null ], - wordWrapCallback: [ 'wordWrap.callback', null ], - wordWrapCallbackScope: [ 'wordWrap.callbackScope', null ], - wordWrapUseAdvanced: [ 'wordWrap.useAdvancedWrap', false ] -}; - -/** - * @classdesc - * A TextStyle class manages all of the style settings for a Text object. - * - * Text Game Objects create a TextStyle instance automatically, which is - * accessed via the `Text.style` property. You do not normally need to - * instantiate one yourself. - * - * @class TextStyle - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Text} text - The Text object that this TextStyle is styling. - * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. - */ -var TextStyle = new Class({ - - initialize: - - function TextStyle (text, style) - { - /** - * The Text object that this TextStyle is styling. - * - * @name Phaser.GameObjects.TextStyle#parent - * @type {Phaser.GameObjects.Text} - * @since 3.0.0 - */ - this.parent = text; - - /** - * The font family. - * - * @name Phaser.GameObjects.TextStyle#fontFamily - * @type {string} - * @default 'Courier' - * @since 3.0.0 - */ - this.fontFamily; - - /** - * The font size. - * - * @name Phaser.GameObjects.TextStyle#fontSize - * @type {string} - * @default '16px' - * @since 3.0.0 - */ - this.fontSize; - - /** - * The font style. - * - * @name Phaser.GameObjects.TextStyle#fontStyle - * @type {string} - * @since 3.0.0 - */ - this.fontStyle; - - /** - * The background color. - * - * @name Phaser.GameObjects.TextStyle#backgroundColor - * @type {string} - * @since 3.0.0 - */ - this.backgroundColor; - - /** - * The text fill color. - * - * @name Phaser.GameObjects.TextStyle#color - * @type {string} - * @default '#fff' - * @since 3.0.0 - */ - this.color; - - /** - * The text stroke color. - * - * @name Phaser.GameObjects.TextStyle#stroke - * @type {string} - * @default '#fff' - * @since 3.0.0 - */ - this.stroke; - - /** - * The text stroke thickness. - * - * @name Phaser.GameObjects.TextStyle#strokeThickness - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.strokeThickness; - - /** - * The horizontal shadow offset. - * - * @name Phaser.GameObjects.TextStyle#shadowOffsetX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowOffsetX; - - /** - * The vertical shadow offset. - * - * @name Phaser.GameObjects.TextStyle#shadowOffsetY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowOffsetY; - - /** - * The shadow color. - * - * @name Phaser.GameObjects.TextStyle#shadowColor - * @type {string} - * @default '#000' - * @since 3.0.0 - */ - this.shadowColor; - - /** - * The shadow blur radius. - * - * @name Phaser.GameObjects.TextStyle#shadowBlur - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.shadowBlur; - - /** - * Whether shadow stroke is enabled or not. - * - * @name Phaser.GameObjects.TextStyle#shadowStroke - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shadowStroke; - - /** - * Whether shadow fill is enabled or not. - * - * @name Phaser.GameObjects.TextStyle#shadowFill - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shadowFill; - - /** - * The text alignment. - * - * @name Phaser.GameObjects.TextStyle#align - * @type {string} - * @default 'left' - * @since 3.0.0 - */ - this.align; - - /** - * The maximum number of lines to draw. - * - * @name Phaser.GameObjects.TextStyle#maxLines - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxLines; - - /** - * The fixed width of the text. - * - * `0` means no fixed with. - * - * @name Phaser.GameObjects.TextStyle#fixedWidth - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.fixedWidth; - - /** - * The fixed height of the text. - * - * `0` means no fixed height. - * - * @name Phaser.GameObjects.TextStyle#fixedHeight - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.fixedHeight; - - /** - * The resolution the text is rendered to its internal canvas at. - * The default is 0, which means it will use the resolution set in the Game Config. - * - * @name Phaser.GameObjects.TextStyle#resolution - * @type {number} - * @default 0 - * @since 3.12.0 - */ - this.resolution; - - /** - * Whether the text should render right to left. - * - * @name Phaser.GameObjects.TextStyle#rtl - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.rtl; - - /** - * The test string to use when measuring the font. - * - * @name Phaser.GameObjects.TextStyle#testString - * @type {string} - * @default '|MÉqgy' - * @since 3.0.0 - */ - this.testString; - - /** - * The amount of horizontal padding added to the width of the text when calculating the font metrics. - * - * @name Phaser.GameObjects.TextStyle#baselineX - * @type {number} - * @default 1.2 - * @since 3.3.0 - */ - this.baselineX; - - /** - * The amount of vertical padding added to the height of the text when calculating the font metrics. - * - * @name Phaser.GameObjects.TextStyle#baselineY - * @type {number} - * @default 1.4 - * @since 3.3.0 - */ - this.baselineY; - - /** - * The maximum width of a line of text in pixels. Null means no line wrapping. Setting this - * property directly will not re-run the word wrapping algorithm. To change the width and - * re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapWidth - * @type {number | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapWidth; - - /** - * A custom function that will be responsible for wrapping the text. It will receive two - * arguments: text (the string to wrap), textObject (this Text instance). It should return - * the wrapped lines either as an array of lines or as a string with newline characters in - * place to indicate where breaks should happen. Setting this directly will not re-run the - * word wrapping algorithm. To change the callback and re-wrap, use - * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapCallback - * @type {TextStyleWordWrapCallback | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapCallback; - - /** - * The scope that will be applied when the wordWrapCallback is invoked. Setting this directly will not re-run the - * word wrapping algorithm. To change the callback and re-wrap, use - * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapCallbackScope - * @type {object | null} - * @default null - * @since 3.24.0 - */ - this.wordWrapCallbackScope; - - /** - * Whether or not to use the advanced wrapping algorithm. If true, spaces are collapsed and - * whitespace is trimmed from lines. If false, spaces and whitespace are left as is. Setting - * this property directly will not re-run the word wrapping algorithm. To change the - * advanced setting and re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. - * - * @name Phaser.GameObjects.TextStyle#wordWrapUseAdvanced - * @type {boolean} - * @default false - * @since 3.24.0 - */ - this.wordWrapUseAdvanced; - - /** - * The font style, size and family. - * - * @name Phaser.GameObjects.TextStyle#_font - * @type {string} - * @private - * @since 3.0.0 - */ - this._font; - - // Set to defaults + user style - this.setStyle(style, false, true); - - var metrics = GetValue(style, 'metrics', false); - - // Provide optional TextMetrics in the style object to avoid the canvas look-up / scanning - // Doing this is reset if you then change the font of this TextStyle after creation - if (metrics) - { - this.metrics = { - ascent: GetValue(metrics, 'ascent', 0), - descent: GetValue(metrics, 'descent', 0), - fontSize: GetValue(metrics, 'fontSize', 0) - }; - } - else - { - this.metrics = MeasureText(this); - } - }, - - /** - * Set the text style. - * - * @example - * text.setStyle({ - * fontSize: '64px', - * fontFamily: 'Arial', - * color: '#ffffff', - * align: 'center', - * backgroundColor: '#ff00ff' - * }); - * - * @method Phaser.GameObjects.TextStyle#setStyle - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. - * @param {boolean} [updateText=true] - Whether to update the text immediately. - * @param {boolean} [setDefaults=false] - Use the default values is not set, or the local values. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setStyle: function (style, updateText, setDefaults) - { - if (updateText === undefined) { updateText = true; } - if (setDefaults === undefined) { setDefaults = false; } - - // Avoid type mutation - // eslint-disable-next-line no-prototype-builtins - if (style && style.hasOwnProperty('fontSize') && typeof style.fontSize === 'number') - { - style.fontSize = style.fontSize.toString() + 'px'; - } - - for (var key in propertyMap) - { - var value = (setDefaults) ? propertyMap[key][1] : this[key]; - - if (key === 'wordWrapCallback' || key === 'wordWrapCallbackScope') - { - // Callback & scope should be set without processing the values - this[key] = GetValue(style, propertyMap[key][0], value); - } - else - { - this[key] = GetAdvancedValue(style, propertyMap[key][0], value); - } - } - - // Allow for 'font' override - var font = GetValue(style, 'font', null); - - if (font !== null) - { - this.setFont(font, false); - } - - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - - // Allow for 'fill' to be used in place of 'color' - var fill = GetValue(style, 'fill', null); - - if (fill !== null) - { - this.color = fill; - } - - if (updateText) - { - return this.update(true); - } - else - { - return this.parent; - } - }, - - /** - * Synchronize the font settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncFont - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The Canvas Element. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - */ - syncFont: function (canvas, context) - { - context.font = this._font; - }, - - /** - * Synchronize the text style settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncStyle - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The Canvas Element. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - */ - syncStyle: function (canvas, context) - { - context.textBaseline = 'alphabetic'; - - context.fillStyle = this.color; - context.strokeStyle = this.stroke; - - context.lineWidth = this.strokeThickness; - context.lineCap = 'round'; - context.lineJoin = 'round'; - }, - - /** - * Synchronize the shadow settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncShadow - * @since 3.0.0 - * - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - * @param {boolean} enabled - Whether shadows are enabled or not. - */ - syncShadow: function (context, enabled) - { - if (enabled) - { - context.shadowOffsetX = this.shadowOffsetX; - context.shadowOffsetY = this.shadowOffsetY; - context.shadowColor = this.shadowColor; - context.shadowBlur = this.shadowBlur; - } - else - { - context.shadowOffsetX = 0; - context.shadowOffsetY = 0; - context.shadowColor = 0; - context.shadowBlur = 0; - } - }, - - /** - * Update the style settings for the parent Text object. - * - * @method Phaser.GameObjects.TextStyle#update - * @since 3.0.0 - * - * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - update: function (recalculateMetrics) - { - if (recalculateMetrics) - { - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - - this.metrics = MeasureText(this); - } - - return this.parent.updateText(); - }, - - /** - * Set the font. - * - * If a string is given, the font family is set. - * - * If an object is given, the `fontFamily`, `fontSize` and `fontStyle` - * properties of that object are set. - * - * @method Phaser.GameObjects.TextStyle#setFont - * @since 3.0.0 - * - * @param {(string|object)} font - The font family or font settings to set. - * @param {boolean} [updateText=true] - Whether to update the text immediately. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFont: function (font, updateText) - { - if (updateText === undefined) { updateText = true; } - - var fontFamily = font; - var fontSize = ''; - var fontStyle = ''; - - if (typeof font !== 'string') - { - fontFamily = GetValue(font, 'fontFamily', 'Courier'); - fontSize = GetValue(font, 'fontSize', '16px'); - fontStyle = GetValue(font, 'fontStyle', ''); - } - else - { - var fontSplit = font.split(' '); - - var i = 0; - - fontStyle = (fontSplit.length > 2) ? fontSplit[i++] : ''; - fontSize = fontSplit[i++] || '16px'; - fontFamily = fontSplit[i++] || 'Courier'; - } - - if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) - { - this.fontFamily = fontFamily; - this.fontSize = fontSize; - this.fontStyle = fontStyle; - - if (updateText) - { - this.update(true); - } - } - - return this.parent; - }, - - /** - * Set the font family. - * - * @method Phaser.GameObjects.TextStyle#setFontFamily - * @since 3.0.0 - * - * @param {string} family - The font family. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontFamily: function (family) - { - if (this.fontFamily !== family) - { - this.fontFamily = family; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the font style. - * - * @method Phaser.GameObjects.TextStyle#setFontStyle - * @since 3.0.0 - * - * @param {string} style - The font style. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontStyle: function (style) - { - if (this.fontStyle !== style) - { - this.fontStyle = style; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the font size. - * - * @method Phaser.GameObjects.TextStyle#setFontSize - * @since 3.0.0 - * - * @param {(number|string)} size - The font size. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFontSize: function (size) - { - if (typeof size === 'number') - { - size = size.toString() + 'px'; - } - - if (this.fontSize !== size) - { - this.fontSize = size; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the test string to use when measuring the font. - * - * @method Phaser.GameObjects.TextStyle#setTestString - * @since 3.0.0 - * - * @param {string} string - The test string to use when measuring the font. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setTestString: function (string) - { - this.testString = string; - - return this.update(true); - }, - - /** - * Set a fixed width and height for the text. - * - * Pass in `0` for either of these parameters to disable fixed width or height respectively. - * - * @method Phaser.GameObjects.TextStyle#setFixedSize - * @since 3.0.0 - * - * @param {number} width - The fixed width to set. - * @param {number} height - The fixed height to set. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFixedSize: function (width, height) - { - this.fixedWidth = width; - this.fixedHeight = height; - - if (width) - { - this.parent.width = width; - } - - if (height) - { - this.parent.height = height; - } - - return this.update(false); - }, - - /** - * Set the background color. - * - * @method Phaser.GameObjects.TextStyle#setBackgroundColor - * @since 3.0.0 - * - * @param {string} color - The background color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setBackgroundColor: function (color) - { - this.backgroundColor = color; - - return this.update(false); - }, - - /** - * Set the text fill color. - * - * @method Phaser.GameObjects.TextStyle#setFill - * @since 3.0.0 - * - * @param {string} color - The text fill color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFill: function (color) - { - this.color = color; - - return this.update(false); - }, - - /** - * Set the text fill color. - * - * @method Phaser.GameObjects.TextStyle#setColor - * @since 3.0.0 - * - * @param {string} color - The text fill color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setColor: function (color) - { - this.color = color; - - return this.update(false); - }, - - /** - * Set the resolution used by the Text object. - * - * By default it will be set to match the resolution set in the Game Config, - * but you can override it via this method. It allows for much clearer text on High DPI devices, - * at the cost of memory because it uses larger internal Canvas textures for the Text. - * - * Please use with caution, as the more high res Text you have, the more memory it uses up. - * - * @method Phaser.GameObjects.TextStyle#setResolution - * @since 3.12.0 - * - * @param {number} value - The resolution for this Text object to use. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setResolution: function (value) - { - this.resolution = value; - - return this.update(false); - }, - - /** - * Set the stroke settings. - * - * @method Phaser.GameObjects.TextStyle#setStroke - * @since 3.0.0 - * - * @param {string} color - The stroke color. - * @param {number} thickness - The stroke thickness. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setStroke: function (color, thickness) - { - if (thickness === undefined) { thickness = this.strokeThickness; } - - if (color === undefined && this.strokeThickness !== 0) - { - // Reset the stroke to zero (disabling it) - this.strokeThickness = 0; - - this.update(true); - } - else if (this.stroke !== color || this.strokeThickness !== thickness) - { - this.stroke = color; - this.strokeThickness = thickness; - - this.update(true); - } - - return this.parent; - }, - - /** - * Set the shadow settings. - * - * Calling this method always re-measures the parent Text object, - * so only call it when you actually change the shadow settings. - * - * @method Phaser.GameObjects.TextStyle#setShadow - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal shadow offset. - * @param {number} [y=0] - The vertical shadow offset. - * @param {string} [color='#000'] - The shadow color. - * @param {number} [blur=0] - The shadow blur radius. - * @param {boolean} [shadowStroke=false] - Whether to stroke the shadow. - * @param {boolean} [shadowFill=true] - Whether to fill the shadow. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadow: function (x, y, color, blur, shadowStroke, shadowFill) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (color === undefined) { color = '#000'; } - if (blur === undefined) { blur = 0; } - if (shadowStroke === undefined) { shadowStroke = false; } - if (shadowFill === undefined) { shadowFill = true; } - - this.shadowOffsetX = x; - this.shadowOffsetY = y; - this.shadowColor = color; - this.shadowBlur = blur; - this.shadowStroke = shadowStroke; - this.shadowFill = shadowFill; - - return this.update(false); - }, - - /** - * Set the shadow offset. - * - * @method Phaser.GameObjects.TextStyle#setShadowOffset - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal shadow offset. - * @param {number} [y=0] - The vertical shadow offset. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowOffset: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.shadowOffsetX = x; - this.shadowOffsetY = y; - - return this.update(false); - }, - - /** - * Set the shadow color. - * - * @method Phaser.GameObjects.TextStyle#setShadowColor - * @since 3.0.0 - * - * @param {string} [color='#000'] - The shadow color. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowColor: function (color) - { - if (color === undefined) { color = '#000'; } - - this.shadowColor = color; - - return this.update(false); - }, - - /** - * Set the shadow blur radius. - * - * @method Phaser.GameObjects.TextStyle#setShadowBlur - * @since 3.0.0 - * - * @param {number} [blur=0] - The shadow blur radius. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowBlur: function (blur) - { - if (blur === undefined) { blur = 0; } - - this.shadowBlur = blur; - - return this.update(false); - }, - - /** - * Enable or disable shadow stroke. - * - * @method Phaser.GameObjects.TextStyle#setShadowStroke - * @since 3.0.0 - * - * @param {boolean} enabled - Whether shadow stroke is enabled or not. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowStroke: function (enabled) - { - this.shadowStroke = enabled; - - return this.update(false); - }, - - /** - * Enable or disable shadow fill. - * - * @method Phaser.GameObjects.TextStyle#setShadowFill - * @since 3.0.0 - * - * @param {boolean} enabled - Whether shadow fill is enabled or not. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowFill: function (enabled) - { - this.shadowFill = enabled; - - return this.update(false); - }, - - /** - * Set the width (in pixels) to use for wrapping lines. - * - * Pass in null to remove wrapping by width. - * - * @method Phaser.GameObjects.TextStyle#setWordWrapWidth - * @since 3.0.0 - * - * @param {number} width - The maximum width of a line in pixels. Set to null to remove wrapping. - * @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping - * algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false, - * spaces and whitespace are left as is. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setWordWrapWidth: function (width, useAdvancedWrap) - { - if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } - - this.wordWrapWidth = width; - this.wordWrapUseAdvanced = useAdvancedWrap; - - return this.update(false); - }, - - /** - * Set a custom callback for wrapping lines. - * - * Pass in null to remove wrapping by callback. - * - * @method Phaser.GameObjects.TextStyle#setWordWrapCallback - * @since 3.0.0 - * - * @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the - * text. It will receive two arguments: text (the string to wrap), textObject (this Text - * instance). It should return the wrapped lines either as an array of lines or as a string with - * newline characters in place to indicate where breaks should happen. - * @param {object} [scope=null] - The scope that will be applied when the callback is invoked. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setWordWrapCallback: function (callback, scope) - { - if (scope === undefined) { scope = null; } - - this.wordWrapCallback = callback; - this.wordWrapCallbackScope = scope; - - return this.update(false); - }, - - /** - * Set the alignment of the text in this Text object. - * - * The argument can be one of: `left`, `right`, `center` or `justify`. - * - * Alignment only works if the Text object has more than one line of text. - * - * @method Phaser.GameObjects.TextStyle#setAlign - * @since 3.0.0 - * - * @param {string} [align='left'] - The text alignment for multi-line text. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setAlign: function (align) - { - if (align === undefined) { align = 'left'; } - - this.align = align; - - return this.update(false); - }, - - /** - * Set the maximum number of lines to draw. - * - * @method Phaser.GameObjects.TextStyle#setMaxLines - * @since 3.0.0 - * - * @param {number} [max=0] - The maximum number of lines to draw. - * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setMaxLines: function (max) - { - if (max === undefined) { max = 0; } - - this.maxLines = max; - - return this.update(false); - }, - - /** - * Get the current text metrics. - * - * @method Phaser.GameObjects.TextStyle#getTextMetrics - * @since 3.0.0 - * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. - */ - getTextMetrics: function () - { - var metrics = this.metrics; - - return { - ascent: metrics.ascent, - descent: metrics.descent, - fontSize: metrics.fontSize - }; - }, - - /** - * Build a JSON representation of this Text Style. - * - * @method Phaser.GameObjects.TextStyle#toJSON - * @since 3.0.0 - * - * @return {object} A JSON representation of this Text Style. - */ - toJSON: function () - { - var output = {}; - - for (var key in propertyMap) - { - output[key] = this[key]; - } - - output.metrics = this.getTextMetrics(); - - return output; - }, - - /** - * Destroy this Text Style. - * - * @method Phaser.GameObjects.TextStyle#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.parent = undefined; - } - -}); - -module.exports = TextStyle; - - -/***/ }), -/* 438 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CanvasPool = __webpack_require__(31); - -/** - * Calculates the ascent, descent and fontSize of a given font style. - * - * @function Phaser.GameObjects.MeasureText - * @since 3.0.0 - * - * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. - * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. - */ -var MeasureText = function (textStyle) -{ - var canvas = CanvasPool.create(this); - var context = canvas.getContext('2d'); - - textStyle.syncFont(canvas, context); - - var metrics = context.measureText(textStyle.testString); - - if (metrics.hasOwnProperty('actualBoundingBoxAscent')) - { - var ascent = metrics.actualBoundingBoxAscent; - var descent = metrics.actualBoundingBoxDescent; - - CanvasPool.remove(canvas); - - return { - ascent: ascent, - descent: descent, - fontSize: ascent + descent - }; - } - - var width = Math.ceil(metrics.width * textStyle.baselineX); - var baseline = width; - var height = 2 * baseline; - - baseline = baseline * textStyle.baselineY | 0; - - canvas.width = width; - canvas.height = height; - - context.fillStyle = '#f00'; - context.fillRect(0, 0, width, height); - - context.font = textStyle._font; - - context.textBaseline = 'alphabetic'; - context.fillStyle = '#000'; - context.fillText(textStyle.testString, 0, baseline); - - var output = { - ascent: 0, - descent: 0, - fontSize: 0 - }; - - if (!context.getImageData(0, 0, width, height)) - { - output.ascent = baseline; - output.descent = baseline + 6; - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; - } - - var imagedata = context.getImageData(0, 0, width, height).data; - var pixels = imagedata.length; - var line = width * 4; - var i; - var j; - var idx = 0; - var stop = false; - - // ascent. scan from top to bottom until we find a non red pixel - for (i = 0; i < baseline; i++) - { - for (j = 0; j < line; j += 4) - { - if (imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx += line; - } - else - { - break; - } - } - - output.ascent = baseline - i; - - idx = pixels - line; - stop = false; - - // descent. scan from bottom to top until we find a non red pixel - for (i = height; i > baseline; i--) - { - for (j = 0; j < line; j += 4) - { - if (imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx -= line; - } - else - { - break; - } - } - - output.descent = (i - baseline); - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; -}; - -module.exports = MeasureText; - - -/***/ }), -/* 439 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcRender = __webpack_require__(1091); -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var Earcut = __webpack_require__(67); -var GeomCircle = __webpack_require__(61); -var MATH_CONST = __webpack_require__(14); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Arc Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * When it renders it displays an arc shape. You can control the start and end angles of the arc, - * as well as if the angles are winding clockwise or anti-clockwise. With the default settings - * it renders as a complete circle. By changing the angles you can create other arc shapes, - * such as half-circles. - * - * Arcs also have an `iterations` property and corresponding `setIterations` method. This allows - * you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. - * - * @class Arc - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [radius=128] - The radius of the arc. - * @param {number} [startAngle=0] - The start angle of the arc, in degrees. - * @param {number} [endAngle=360] - The end angle of the arc, in degrees. - * @param {boolean} [anticlockwise=false] - The winding order of the start and end angles. - * @param {number} [fillColor] - The color the arc will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Arc = new Class({ - - Extends: Shape, - - Mixins: [ - ArcRender - ], - - initialize: - - function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 128; } - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 360; } - if (anticlockwise === undefined) { anticlockwise = false; } - - Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius)); - - /** - * Private internal value. Holds the start angle in degrees. - * - * @name Phaser.GameObjects.Arc#_startAngle - * @type {number} - * @private - * @since 3.13.0 - */ - this._startAngle = startAngle; - - /** - * Private internal value. Holds the end angle in degrees. - * - * @name Phaser.GameObjects.Arc#_endAngle - * @type {number} - * @private - * @since 3.13.0 - */ - this._endAngle = endAngle; - - /** - * Private internal value. Holds the winding order of the start and end angles. - * - * @name Phaser.GameObjects.Arc#_anticlockwise - * @type {boolean} - * @private - * @since 3.13.0 - */ - this._anticlockwise = anticlockwise; - - /** - * Private internal value. Holds the number of iterations used when drawing the arc. - * - * @name Phaser.GameObjects.Arc#_iterations - * @type {number} - * @default 0.01 - * @private - * @since 3.13.0 - */ - this._iterations = 0.01; - - this.setPosition(x, y); - - var diameter = this.geom.radius * 2; - this.setSize(diameter, diameter); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * The number of iterations used when drawing the arc. - * Increase this value for smoother arcs, at the cost of more polygons being rendered. - * Modify this value by small amounts, such as 0.01. - * - * @name Phaser.GameObjects.Arc#iterations - * @type {number} - * @default 0.01 - * @since 3.13.0 - */ - iterations: { - - get: function () - { - return this._iterations; - }, - - set: function (value) - { - this._iterations = value; - - this.updateData(); - } - - }, - - /** - * The radius of the arc. - * - * @name Phaser.GameObjects.Arc#radius - * @type {number} - * @since 3.13.0 - */ - radius: { - - get: function () - { - return this.geom.radius; - }, - - set: function (value) - { - this.geom.radius = value; - - var diameter = value * 2; - this.setSize(diameter, diameter); - this.updateDisplayOrigin(); - this.updateData(); - } - - }, - - /** - * The start angle of the arc, in degrees. - * - * @name Phaser.GameObjects.Arc#startAngle - * @type {number} - * @since 3.13.0 - */ - startAngle: { - - get: function () - { - return this._startAngle; - }, - - set: function (value) - { - this._startAngle = value; - - this.updateData(); - } - - }, - - /** - * The end angle of the arc, in degrees. - * - * @name Phaser.GameObjects.Arc#endAngle - * @type {number} - * @since 3.13.0 - */ - endAngle: { - - get: function () - { - return this._endAngle; - }, - - set: function (value) - { - this._endAngle = value; - - this.updateData(); - } - - }, - - /** - * The winding order of the start and end angles. - * - * @name Phaser.GameObjects.Arc#anticlockwise - * @type {boolean} - * @since 3.13.0 - */ - anticlockwise: { - - get: function () - { - return this._anticlockwise; - }, - - set: function (value) - { - this._anticlockwise = value; - - this.updateData(); - } - - }, - - /** - * Sets the radius of the arc. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setRadius - * @since 3.13.0 - * - * @param {number} value - The value to set the radius to. - * - * @return {this} This Game Object instance. - */ - setRadius: function (value) - { - this.radius = value; - - return this; - }, - - /** - * Sets the number of iterations used when drawing the arc. - * Increase this value for smoother arcs, at the cost of more polygons being rendered. - * Modify this value by small amounts, such as 0.01. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setIterations - * @since 3.13.0 - * - * @param {number} value - The value to set the iterations to. - * - * @return {this} This Game Object instance. - */ - setIterations: function (value) - { - if (value === undefined) { value = 0.01; } - - this.iterations = value; - - return this; - }, - - /** - * Sets the starting angle of the arc, in degrees. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setStartAngle - * @since 3.13.0 - * - * @param {number} value - The value to set the starting angle to. - * - * @return {this} This Game Object instance. - */ - setStartAngle: function (angle, anticlockwise) - { - this._startAngle = angle; - - if (anticlockwise !== undefined) - { - this._anticlockwise = anticlockwise; - } - - return this.updateData(); - }, - - /** - * Sets the ending angle of the arc, in degrees. - * This call can be chained. - * - * @method Phaser.GameObjects.Arc#setEndAngle - * @since 3.13.0 - * - * @param {number} value - The value to set the ending angle to. - * - * @return {this} This Game Object instance. - */ - setEndAngle: function (angle, anticlockwise) - { - this._endAngle = angle; - - if (anticlockwise !== undefined) - { - this._anticlockwise = anticlockwise; - } - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Arc#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var step = this._iterations; - var iteration = step; - - var radius = this.geom.radius; - var startAngle = DegToRad(this._startAngle); - var endAngle = DegToRad(this._endAngle); - var anticlockwise = this._anticlockwise; - - var x = radius; - var y = radius; - - endAngle -= startAngle; - - if (anticlockwise) - { - if (endAngle < -MATH_CONST.PI2) - { - endAngle = -MATH_CONST.PI2; - } - else if (endAngle > 0) - { - endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; - } - } - else if (endAngle > MATH_CONST.PI2) - { - endAngle = MATH_CONST.PI2; - } - else if (endAngle < 0) - { - endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; - } - - var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; - - var ta; - - while (iteration < 1) - { - ta = endAngle * iteration + startAngle; - - path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); - - iteration += step; - } - - ta = endAngle + startAngle; - - path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); - - path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Arc; - - -/***/ }), -/* 440 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CurveRender = __webpack_require__(1094); -var Earcut = __webpack_require__(67); -var Rectangle = __webpack_require__(10); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Curve Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to - * the Curve Shape in the constructor. - * - * The Curve shape also has a `smoothness` property and corresponding `setSmoothness` method. - * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. Increase and decrease the default value for smoother, or more - * jagged, shapes. - * - * @class Curve - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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.Curves.Curve} [curve] - The Curve object to use to create the Shape. - * @param {number} [fillColor] - The color the curve will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Curve = new Class({ - - Extends: Shape, - - Mixins: [ - CurveRender - ], - - initialize: - - function Curve (scene, x, y, curve, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - Shape.call(this, scene, 'Curve', curve); - - /** - * Private internal value. - * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. - * - * @name Phaser.GameObjects.Curve#_smoothness - * @type {number} - * @private - * @since 3.13.0 - */ - this._smoothness = 32; - - /** - * Private internal value. - * The Curve bounds rectangle. - * - * @name Phaser.GameObjects.Curve#_curveBounds - * @type {Phaser.Geom.Rectangle} - * @private - * @since 3.13.0 - */ - this._curveBounds = new Rectangle(); - - this.closePath = false; - - this.setPosition(x, y); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateData(); - }, - - /** - * The smoothness of the curve. The number of points used when rendering it. - * Increase this value for smoother curves, at the cost of more polygons being rendered. - * - * @name Phaser.GameObjects.Curve#smoothness - * @type {number} - * @default 32 - * @since 3.13.0 - */ - smoothness: { - - get: function () - { - return this._smoothness; - }, - - set: function (value) - { - this._smoothness = value; - - this.updateData(); - } - - }, - - /** - * Sets the smoothness of the curve. The number of points used when rendering it. - * Increase this value for smoother curves, at the cost of more polygons being rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.Curve#setSmoothness - * @since 3.13.0 - * - * @param {number} value - The value to set the smoothness to. - * - * @return {this} This Game Object instance. - */ - setSmoothness: function (value) - { - this._smoothness = value; - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Curve#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var bounds = this._curveBounds; - var smoothness = this._smoothness; - - // Update the bounds in case the underlying data has changed - this.geom.getBounds(bounds, smoothness); - - this.setSize(bounds.width, bounds.height); - this.updateDisplayOrigin(); - - var path = []; - var points = this.geom.getPoints(smoothness); - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Curve; - - -/***/ }), -/* 441 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var EllipseRender = __webpack_require__(1097); -var GeomEllipse = __webpack_require__(106); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * When it renders it displays an ellipse shape. You can control the width and height of the ellipse. - * If the width and height match it will render as a circle. If the width is less than the height, - * it will look more like an egg shape. - * - * The Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method. - * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations - * that take place during construction. Increase and decrease the default value for smoother, or more - * jagged, shapes. - * - * @class Ellipse - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [width=128] - The width of the ellipse. An ellipse with equal width and height renders as a circle. - * @param {number} [height=128] - The height of the ellipse. An ellipse with equal width and height renders as a circle. - * @param {number} [fillColor] - The color the ellipse will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Ellipse = new Class({ - - Extends: Shape, - - Mixins: [ - EllipseRender - ], - - initialize: - - function Ellipse (scene, x, y, width, height, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - - Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); - - /** - * Private internal value. - * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. - * - * @name Phaser.GameObjects.Ellipse#_smoothness - * @type {number} - * @private - * @since 3.13.0 - */ - this._smoothness = 64; - - this.setPosition(x, y); - - this.width = width; - this.height = height; - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * The smoothness of the ellipse. The number of points used when rendering it. - * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. - * - * @name Phaser.GameObjects.Ellipse#smoothness - * @type {number} - * @default 64 - * @since 3.13.0 - */ - smoothness: { - - get: function () - { - return this._smoothness; - }, - - set: function (value) - { - this._smoothness = value; - - this.updateData(); - } - - }, - - /** - * Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object. - * This call can be chained. - * - * @method Phaser.GameObjects.Ellipse#setSize - * @since 3.13.0 - * - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * - * @return {this} This Game Object instance. - */ - setSize: function (width, height) - { - this.width = width; - this.height = height; - this.geom.setPosition(width / 2, height / 2); - this.geom.setSize(width, height); - - return this.updateData(); - }, - - /** - * Sets the smoothness of the ellipse. The number of points used when rendering it. - * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.Ellipse#setSmoothness - * @since 3.13.0 - * - * @param {number} value - The value to set the smoothness to. - * - * @return {this} This Game Object instance. - */ - setSmoothness: function (value) - { - this._smoothness = value; - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Ellipse#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var points = this.geom.getPoints(this._smoothness); - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Ellipse; - - -/***/ }), -/* 442 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GridRender = __webpack_require__(1100); - -/** - * @classdesc - * The Grid Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * A Grid Shape allows you to display a grid in your game, where you can control the size of the - * grid as well as the width and height of the grid cells. You can set a fill color for each grid - * cell as well as an alternate fill color. When the alternate fill color is set then the grid - * cells will alternate the fill colors as they render, creating a chess-board effect. You can - * also optionally have an outline fill color. If set, this draws lines between the grid cells - * in the given color. If you specify an outline color with an alpha of zero, then it will draw - * the cells spaced out, but without the lines between them. - * - * @class Grid - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [width=128] - The width of the grid. - * @param {number} [height=128] - The height of the grid. - * @param {number} [cellWidth=32] - The width of one cell in the grid. - * @param {number} [cellHeight=32] - The height of one cell in the grid. - * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * @param {number} [outlineFillColor] - The color of the lines between the grid cells. See the `setOutline` method. - * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. - */ -var Grid = new Class({ - - Extends: Shape, - - Mixins: [ - GridRender - ], - - initialize: - - function Grid (scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - if (cellWidth === undefined) { cellWidth = 32; } - if (cellHeight === undefined) { cellHeight = 32; } - - Shape.call(this, scene, 'Grid', null); - - /** - * The width of each grid cell. - * Must be a positive value. - * - * @name Phaser.GameObjects.Grid#cellWidth - * @type {number} - * @since 3.13.0 - */ - this.cellWidth = cellWidth; - - /** - * The height of each grid cell. - * Must be a positive value. - * - * @name Phaser.GameObjects.Grid#cellHeight - * @type {number} - * @since 3.13.0 - */ - this.cellHeight = cellHeight; - - /** - * Will the grid render its cells in the `fillColor`? - * - * @name Phaser.GameObjects.Grid#showCells - * @type {boolean} - * @since 3.13.0 - */ - this.showCells = true; - - /** - * The color of the lines between each grid cell. - * - * @name Phaser.GameObjects.Grid#outlineFillColor - * @type {number} - * @since 3.13.0 - */ - this.outlineFillColor = 0; - - /** - * The alpha value for the color of the lines between each grid cell. - * - * @name Phaser.GameObjects.Grid#outlineFillAlpha - * @type {number} - * @since 3.13.0 - */ - this.outlineFillAlpha = 0; - - /** - * Will the grid display the lines between each cell when it renders? - * - * @name Phaser.GameObjects.Grid#showOutline - * @type {boolean} - * @since 3.13.0 - */ - this.showOutline = true; - - /** - * Will the grid render the alternating cells in the `altFillColor`? - * - * @name Phaser.GameObjects.Grid#showAltCells - * @type {boolean} - * @since 3.13.0 - */ - this.showAltCells = false; - - /** - * The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. - * - * @name Phaser.GameObjects.Grid#altFillColor - * @type {number} - * @since 3.13.0 - */ - this.altFillColor; - - /** - * The alpha the alternating grid cells will be filled with. - * You can also set the alpha of the overall Shape using its `alpha` property. - * - * @name Phaser.GameObjects.Grid#altFillAlpha - * @type {number} - * @since 3.13.0 - */ - this.altFillAlpha; - - this.setPosition(x, y); - this.setSize(width, height); - - this.setFillStyle(fillColor, fillAlpha); - - if (outlineFillColor !== undefined) - { - this.setOutlineStyle(outlineFillColor, outlineFillAlpha); - } - - this.updateDisplayOrigin(); - }, - - /** - * Sets the fill color and alpha level the grid cells will use when rendering. - * - * If this method is called with no values then the grid cells will not be rendered, - * however the grid lines and alternating cells may still be. - * - * Also see the `setOutlineStyle` and `setAltFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showCells = false; - } - else - { - this.fillColor = fillColor; - this.fillAlpha = fillAlpha; - this.showCells = true; - } - - return this; - }, - - /** - * Sets the fill color and alpha level that the alternating grid cells will use. - * - * If this method is called with no values then alternating grid cells will not be rendered in a different color. - * - * Also see the `setOutlineStyle` and `setFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setAltFillStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the alternating grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setAltFillStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showAltCells = false; - } - else - { - this.altFillColor = fillColor; - this.altFillAlpha = fillAlpha; - this.showAltCells = true; - } - - return this; - }, - - /** - * Sets the fill color and alpha level that the lines between each grid cell will use. - * - * If this method is called with no values then the grid lines will not be rendered at all, however - * the cells themselves may still be if they have colors set. - * - * Also see the `setFillStyle` and `setAltFillStyle` methods. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Grid#setOutlineStyle - * @since 3.13.0 - * - * @param {number} [fillColor] - The color the lines between the grid cells will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha=1] - The alpha the lines between the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {this} This Game Object instance. - */ - setOutlineStyle: function (fillColor, fillAlpha) - { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showOutline = false; - } - else - { - this.outlineFillColor = fillColor; - this.outlineFillAlpha = fillAlpha; - this.showOutline = true; - } - - return this; - } - -}); - -module.exports = Grid; - - -/***/ }), -/* 443 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var IsoBoxRender = __webpack_require__(1103); -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The IsoBox Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * An IsoBox is an 'isometric' rectangle. Each face of it has a different fill color. You can set - * the color of the top, left and right faces of the rectangle respectively. You can also choose - * which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. - * - * You cannot view an IsoBox from under-neath, however you can change the 'angle' by setting - * the `projection` property. - * - * @class IsoBox - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [size=48] - The width of the iso box in pixels. The left and right faces will be exactly half this value. - * @param {number} [height=32] - The height of the iso box. The left and right faces will be this tall. The overall height of the isobox will be this value plus half the `size` value. - * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso box. - * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso box. - * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso box. - */ -var IsoBox = new Class({ - - Extends: Shape, - - Mixins: [ - IsoBoxRender - ], - - initialize: - - function IsoBox (scene, x, y, size, height, fillTop, fillLeft, fillRight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (size === undefined) { size = 48; } - if (height === undefined) { height = 32; } - if (fillTop === undefined) { fillTop = 0xeeeeee; } - if (fillLeft === undefined) { fillLeft = 0x999999; } - if (fillRight === undefined) { fillRight = 0xcccccc; } - - Shape.call(this, scene, 'IsoBox', null); - - /** - * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * - * @name Phaser.GameObjects.IsoBox#projection - * @type {number} - * @default 4 - * @since 3.13.0 - */ - this.projection = 4; - - /** - * The color used to fill in the top of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillTop - * @type {number} - * @since 3.13.0 - */ - this.fillTop = fillTop; - - /** - * The color used to fill in the left-facing side of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillLeft - * @type {number} - * @since 3.13.0 - */ - this.fillLeft = fillLeft; - - /** - * The color used to fill in the right-facing side of the iso box. - * - * @name Phaser.GameObjects.IsoBox#fillRight - * @type {number} - * @since 3.13.0 - */ - this.fillRight = fillRight; - - /** - * Controls if the top-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showTop - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showTop = true; - - /** - * Controls if the left-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showLeft - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showLeft = true; - - /** - * Controls if the right-face of the iso box be rendered. - * - * @name Phaser.GameObjects.IsoBox#showRight - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showRight = true; - - this.isFilled = true; - - this.setPosition(x, y); - this.setSize(size, height); - - this.updateDisplayOrigin(); - }, - - /** - * Sets the projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setProjection - * @since 3.13.0 - * - * @param {number} value - The value to set the projection to. - * - * @return {this} This Game Object instance. - */ - setProjection: function (value) - { - this.projection = value; - - return this; - }, - - /** - * Sets which faces of the iso box will be rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setFaces - * @since 3.13.0 - * - * @param {boolean} [showTop=true] - Show the top-face of the iso box. - * @param {boolean} [showLeft=true] - Show the left-face of the iso box. - * @param {boolean} [showRight=true] - Show the right-face of the iso box. - * - * @return {this} This Game Object instance. - */ - setFaces: function (showTop, showLeft, showRight) - { - if (showTop === undefined) { showTop = true; } - if (showLeft === undefined) { showLeft = true; } - if (showRight === undefined) { showRight = true; } - - this.showTop = showTop; - this.showLeft = showLeft; - this.showRight = showRight; - - return this; - }, - - /** - * Sets the fill colors for each face of the iso box. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoBox#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillTop] - The color used to fill the top of the iso box. - * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso box. - * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso box. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillTop, fillLeft, fillRight) - { - this.fillTop = fillTop; - this.fillLeft = fillLeft; - this.fillRight = fillRight; - - this.isFilled = true; - - return this; - } - -}); - -module.exports = IsoBox; - - -/***/ }), -/* 444 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var IsoTriangleRender = __webpack_require__(1106); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The IsoTriangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only fill colors and cannot be stroked. - * - * An IsoTriangle is an 'isometric' triangle. Think of it like a pyramid. Each face has a different - * fill color. You can set the color of the top, left and right faces of the triangle respectively - * You can also choose which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. - * - * You cannot view an IsoTriangle from under-neath, however you can change the 'angle' by setting - * the `projection` property. The `reversed` property controls if the IsoTriangle is rendered upside - * down or not. - * - * @class IsoTriangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [size=48] - The width of the iso triangle in pixels. The left and right faces will be exactly half this value. - * @param {number} [height=32] - The height of the iso triangle. The left and right faces will be this tall. The overall height of the iso triangle will be this value plus half the `size` value. - * @param {boolean} [reversed=false] - Is the iso triangle upside down? - * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso triangle. - * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso triangle. - * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso triangle. - */ -var IsoTriangle = new Class({ - - Extends: Shape, - - Mixins: [ - IsoTriangleRender - ], - - initialize: - - function IsoTriangle (scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (size === undefined) { size = 48; } - if (height === undefined) { height = 32; } - if (reversed === undefined) { reversed = false; } - if (fillTop === undefined) { fillTop = 0xeeeeee; } - if (fillLeft === undefined) { fillLeft = 0x999999; } - if (fillRight === undefined) { fillRight = 0xcccccc; } - - Shape.call(this, scene, 'IsoTriangle', null); - - /** - * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. - * - * @name Phaser.GameObjects.IsoTriangle#projection - * @type {number} - * @default 4 - * @since 3.13.0 - */ - this.projection = 4; - - /** - * The color used to fill in the top of the iso triangle. This is only used if the triangle is reversed. - * - * @name Phaser.GameObjects.IsoTriangle#fillTop - * @type {number} - * @since 3.13.0 - */ - this.fillTop = fillTop; - - /** - * The color used to fill in the left-facing side of the iso triangle. - * - * @name Phaser.GameObjects.IsoTriangle#fillLeft - * @type {number} - * @since 3.13.0 - */ - this.fillLeft = fillLeft; - - /** - * The color used to fill in the right-facing side of the iso triangle. - * - * @name Phaser.GameObjects.IsoTriangle#fillRight - * @type {number} - * @since 3.13.0 - */ - this.fillRight = fillRight; - - /** - * Controls if the top-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showTop - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showTop = true; - - /** - * Controls if the left-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showLeft - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showLeft = true; - - /** - * Controls if the right-face of the iso triangle be rendered. - * - * @name Phaser.GameObjects.IsoTriangle#showRight - * @type {boolean} - * @default true - * @since 3.13.0 - */ - this.showRight = true; - - /** - * Sets if the iso triangle will be rendered upside down or not. - * - * @name Phaser.GameObjects.IsoTriangle#isReversed - * @type {boolean} - * @default false - * @since 3.13.0 - */ - this.isReversed = reversed; - - this.isFilled = true; - - this.setPosition(x, y); - this.setSize(size, height); - - this.updateDisplayOrigin(); - }, - - /** - * Sets the projection level of the iso triangle. Change this to change the 'angle' at which you are looking at the pyramid. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setProjection - * @since 3.13.0 - * - * @param {number} value - The value to set the projection to. - * - * @return {this} This Game Object instance. - */ - setProjection: function (value) - { - this.projection = value; - - return this; - }, - - /** - * Sets if the iso triangle will be rendered upside down or not. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setReversed - * @since 3.13.0 - * - * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. - * - * @return {this} This Game Object instance. - */ - setReversed: function (reversed) - { - this.isReversed = reversed; - - return this; - }, - - /** - * Sets which faces of the iso triangle will be rendered. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setFaces - * @since 3.13.0 - * - * @param {boolean} [showTop=true] - Show the top-face of the iso triangle (only if `reversed` is true) - * @param {boolean} [showLeft=true] - Show the left-face of the iso triangle. - * @param {boolean} [showRight=true] - Show the right-face of the iso triangle. - * - * @return {this} This Game Object instance. - */ - setFaces: function (showTop, showLeft, showRight) - { - if (showTop === undefined) { showTop = true; } - if (showLeft === undefined) { showLeft = true; } - if (showRight === undefined) { showRight = true; } - - this.showTop = showTop; - this.showLeft = showLeft; - this.showRight = showRight; - - return this; - }, - - /** - * Sets the fill colors for each face of the iso triangle. - * This call can be chained. - * - * @method Phaser.GameObjects.IsoTriangle#setFillStyle - * @since 3.13.0 - * - * @param {number} [fillTop] - The color used to fill the top of the iso triangle. - * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso triangle. - * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso triangle. - * - * @return {this} This Game Object instance. - */ - setFillStyle: function (fillTop, fillLeft, fillRight) - { - this.fillTop = fillTop; - this.fillLeft = fillLeft; - this.fillRight = fillRight; - - this.isFilled = true; - - return this; - } - -}); - -module.exports = IsoTriangle; - - -/***/ }), -/* 445 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GeomLine = __webpack_require__(45); -var LineRender = __webpack_require__(1109); - -/** - * @classdesc - * The Line Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports only stroke colors and cannot be filled. - * - * A Line Shape allows you to draw a line between two points in your game. You can control the - * stroke color and thickness of the line. In WebGL only you can also specify a different - * thickness for the start and end of the line, allowing you to render lines that taper-off. - * - * If you need to draw multiple lines in a sequence you may wish to use the Polygon Shape instead. - * - * Be aware that as with all Game Objects the default origin is 0.5. If you need to draw a Line - * between two points and want the x1/y1 values to match the x/y values, then set the origin to 0. - * - * @class Line - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [x1=0] - The horizontal position of the start of the line. - * @param {number} [y1=0] - The vertical position of the start of the line. - * @param {number} [x2=128] - The horizontal position of the end of the line. - * @param {number} [y2=0] - The vertical position of the end of the line. - * @param {number} [strokeColor] - The color the line will be drawn in, i.e. 0xff0000 for red. - * @param {number} [strokeAlpha] - The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Line = new Class({ - - Extends: Shape, - - Mixins: [ - LineRender - ], - - initialize: - - function Line (scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 128; } - if (y2 === undefined) { y2 = 0; } - - Shape.call(this, scene, 'Line', new GeomLine(x1, y1, x2, y2)); - - var width = Math.max(1, this.geom.right - this.geom.left); - var height = Math.max(1, this.geom.bottom - this.geom.top); - - /** - * The width (or thickness) of the line. - * See the setLineWidth method for extra details on changing this on WebGL. - * - * @name Phaser.GameObjects.Line#lineWidth - * @type {number} - * @since 3.13.0 - */ - this.lineWidth = 1; - - /** - * Private internal value. Holds the start width of the line. - * - * @name Phaser.GameObjects.Line#_startWidth - * @type {number} - * @private - * @since 3.13.0 - */ - this._startWidth = 1; - - /** - * Private internal value. Holds the end width of the line. - * - * @name Phaser.GameObjects.Line#_endWidth - * @type {number} - * @private - * @since 3.13.0 - */ - this._endWidth = 1; - - this.setPosition(x, y); - this.setSize(width, height); - - if (strokeColor !== undefined) - { - this.setStrokeStyle(1, strokeColor, strokeAlpha); - } - - this.updateDisplayOrigin(); - }, - - /** - * Sets the width of the line. - * - * When using the WebGL renderer you can have different start and end widths. - * When using the Canvas renderer only the `startWidth` value is used. The `endWidth` is ignored. - * - * This call can be chained. - * - * @method Phaser.GameObjects.Line#setLineWidth - * @since 3.13.0 - * - * @param {number} startWidth - The start width of the line. - * @param {number} [endWidth] - The end width of the line. Only used in WebGL. - * - * @return {this} This Game Object instance. - */ - setLineWidth: function (startWidth, endWidth) - { - if (endWidth === undefined) { endWidth = startWidth; } - - this._startWidth = startWidth; - this._endWidth = endWidth; - - this.lineWidth = startWidth; - - return this; - }, - - /** - * Sets the start and end coordinates of this Line. - * - * @method Phaser.GameObjects.Line#setTo - * @since 3.13.0 - * - * @param {number} [x1=0] - The horizontal position of the start of the line. - * @param {number} [y1=0] - The vertical position of the start of the line. - * @param {number} [x2=0] - The horizontal position of the end of the line. - * @param {number} [y2=0] - The vertical position of the end of the line. - * - * @return {this} This Line object. - */ - setTo: function (x1, y1, x2, y2) - { - this.geom.setTo(x1, y1, x2, y2); - - return this; - } - -}); - -module.exports = Line; - - -/***/ }), -/* 446 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var PolygonRender = __webpack_require__(1112); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var GetAABB = __webpack_require__(447); -var GeomPolygon = __webpack_require__(222); -var Shape = __webpack_require__(32); -var Smooth = __webpack_require__(450); - -/** - * @classdesc - * The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * The Polygon Shape is created by providing a list of points, which are then used to create an - * internal Polygon geometry object. The points can be set from a variety of formats: - * - * - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` - * - An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]` - * - An array of objects with public x/y properties: `[obj1, obj2, ...]` - * - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]` - * - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]` - * - * By default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending - * on the coordinates of the points provided, the final shape may be rendered offset from its origin. - * - * @class Polygon - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {any} [points] - The points that make up the polygon. - * @param {number} [fillColor] - The color the polygon will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Polygon = new Class({ - - Extends: Shape, - - Mixins: [ - PolygonRender - ], - - initialize: - - function Polygon (scene, x, y, points, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - Shape.call(this, scene, 'Polygon', new GeomPolygon(points)); - - var bounds = GetAABB(this.geom); - - this.setPosition(x, y); - this.setSize(bounds.width, bounds.height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Smooths the polygon over the number of iterations specified. - * The base polygon data will be updated and replaced with the smoothed values. - * This call can be chained. - * - * @method Phaser.GameObjects.Polygon#smooth - * @since 3.13.0 - * - * @param {number} [iterations=1] - The number of times to apply the polygon smoothing. - * - * @return {this} This Game Object instance. - */ - smooth: function (iterations) - { - if (iterations === undefined) { iterations = 1; } - - for (var i = 0; i < iterations; i++) - { - Smooth(this.geom); - } - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Polygon#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var points = this.geom.points; - - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } - - path.push(points[0].x, points[0].y); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Polygon; - - -/***/ }), -/* 447 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -/** - * Calculates the bounding AABB rectangle of a polygon. - * - * @function Phaser.Geom.Polygon.GetAABB - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The polygon that should be calculated. - * @param {(Phaser.Geom.Rectangle|object)} [out] - The rectangle or object that has x, y, width, and height properties to store the result. Optional. - * - * @return {(Phaser.Geom.Rectangle|object)} The resulting rectangle or object that is passed in with position and dimensions of the polygon's AABB. - */ -var GetAABB = function (polygon, out) -{ - if (out === undefined) { out = new Rectangle(); } - - var minX = Infinity; - var minY = Infinity; - var maxX = -minX; - var maxY = -minY; - var p; - - for (var i = 0; i < polygon.points.length; i++) - { - p = polygon.points[i]; - - minX = Math.min(minX, p.x); - minY = Math.min(minY, p.y); - maxX = Math.max(maxX, p.x); - maxY = Math.max(maxY, p.y); - } - - out.x = minX; - out.y = minY; - out.width = maxX - minX; - out.height = maxY - minY; - - return out; -}; - -module.exports = GetAABB; - - -/***/ }), -/* 448 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Line = __webpack_require__(45); -var Perimeter = __webpack_require__(449); - -/** - * Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon, - * based on the given quantity or stepRate values. - * - * @function Phaser.Geom.Polygon.GetPoints - * @since 3.12.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the points from. - * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. - * @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate. - * @param {array} [output] - An array to insert the points in to. If not provided a new array will be created. - * - * @return {Phaser.Geom.Point[]} An array of Point objects pertaining to the points around the perimeter of the Polygon. - */ -var GetPoints = function (polygon, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } - - var points = polygon.points; - var perimeter = Perimeter(polygon); - - // 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 / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var position = perimeter * (i / quantity); - var accumulatedPerimeter = 0; - - for (var j = 0; j < points.length; j++) - { - var pointA = points[j]; - var pointB = points[(j + 1) % points.length]; - var line = new Line( - pointA.x, - pointA.y, - pointB.x, - pointB.y - ); - var length = Length(line); - - if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) - { - accumulatedPerimeter += length; - continue; - } - - var point = line.getPoint((position - accumulatedPerimeter) / length); - out.push(point); - - break; - } - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 449 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Line = __webpack_require__(45); - -/** - * Returns the perimeter of the given Polygon. - * - * @function Phaser.Geom.Polygon.Perimeter - * @since 3.12.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the perimeter of. - * - * @return {number} The perimeter of the Polygon. - */ -var Perimeter = function (polygon) -{ - var points = polygon.points; - var perimeter = 0; - - for (var i = 0; i < points.length; i++) - { - var pointA = points[i]; - var pointB = points[(i + 1) % points.length]; - var line = new Line( - pointA.x, - pointA.y, - pointB.x, - pointB.y - ); - - perimeter += Length(line); - } - - return perimeter; -}; - -module.exports = Perimeter; - - -/***/ }), -/* 450 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Igor Ognichenko - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @ignore - */ -var copy = function (out, a) -{ - out[0] = a[0]; - out[1] = a[1]; - - return out; -}; - -/** - * Takes a Polygon object and applies Chaikin's smoothing algorithm on its points. - * - * @function Phaser.Geom.Polygon.Smooth - * @since 3.13.0 - * - * @generic {Phaser.Geom.Polygon} O - [polygon,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The polygon to be smoothed. The polygon will be modified in-place and returned. - * - * @return {Phaser.Geom.Polygon} The input polygon. - */ -var Smooth = function (polygon) -{ - var i; - var points = []; - var data = polygon.points; - - for (i = 0; i < data.length; i++) - { - points.push([ data[i].x, data[i].y ]); - } - - var output = []; - - if (points.length > 0) - { - output.push(copy([ 0, 0 ], points[0])); - } - - for (i = 0; i < points.length - 1; i++) - { - var p0 = points[i]; - var p1 = points[i + 1]; - var p0x = p0[0]; - var p0y = p0[1]; - var p1x = p1[0]; - var p1y = p1[1]; - - output.push([ 0.85 * p0x + 0.15 * p1x, 0.85 * p0y + 0.15 * p1y ]); - output.push([ 0.15 * p0x + 0.85 * p1x, 0.15 * p0y + 0.85 * p1y ]); - } - - if (points.length > 1) - { - output.push(copy([ 0, 0 ], points[points.length - 1])); - } - - return polygon.setTo(output); -}; - -module.exports = Smooth; - - -/***/ }), -/* 451 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GeomRectangle = __webpack_require__(10); -var Shape = __webpack_require__(32); -var RectangleRender = __webpack_require__(1115); - -/** - * @classdesc - * The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * You can change the size of the rectangle by changing the `width` and `height` properties. - * - * @class Rectangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 - The horizontal position of this Game Object in the world. - * @param {number} y - The vertical position of this Game Object in the world. - * @param {number} [width=128] - The width of the rectangle. - * @param {number} [height=128] - The height of the rectangle. - * @param {number} [fillColor] - The color the rectangle will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Rectangle = new Class({ - - Extends: Shape, - - Mixins: [ - RectangleRender - ], - - initialize: - - function Rectangle (scene, x, y, width, height, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - - Shape.call(this, scene, 'Rectangle', new GeomRectangle(0, 0, width, height)); - - this.setPosition(x, y); - this.setSize(width, height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * 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.Rectangle#setSize - * @since 3.13.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; - - this.geom.setSize(width, height); - - this.updateData(); - - return this; - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Rectangle#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var rect = this.geom; - var line = this._tempLine; - - rect.getLineA(line); - - path.push(line.x1, line.y1, line.x2, line.y2); - - rect.getLineB(line); - - path.push(line.x2, line.y2); - - rect.getLineC(line); - - path.push(line.x2, line.y2); - - rect.getLineD(line); - - path.push(line.x2, line.y2); - - this.pathData = path; - - return this; - } - -}); - -module.exports = Rectangle; - - -/***/ }), -/* 452 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var StarRender = __webpack_require__(1118); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); -var Shape = __webpack_require__(32); - -/** - * @classdesc - * The Star Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * As the name implies, the Star shape will display a star in your game. You can control several - * aspects of it including the number of points that constitute the star. The default is 5. If - * you change it to 4 it will render as a diamond. If you increase them, you'll get a more spiky - * star shape. - * - * You can also control the inner and outer radius, which is how 'long' each point of the star is. - * Modify these values to create more interesting shapes. - * - * @class Star - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [points=5] - The number of points on the star. - * @param {number} [innerRadius=32] - The inner radius of the star. - * @param {number} [outerRadius=64] - The outer radius of the star. - * @param {number} [fillColor] - The color the star will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Star = new Class({ - - Extends: Shape, - - Mixins: [ - StarRender - ], - - initialize: - - function Star (scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (points === undefined) { points = 5; } - if (innerRadius === undefined) { innerRadius = 32; } - if (outerRadius === undefined) { outerRadius = 64; } - - Shape.call(this, scene, 'Star', null); - - /** - * Private internal value. - * The number of points in the star. - * - * @name Phaser.GameObjects.Star#_points - * @type {number} - * @private - * @since 3.13.0 - */ - this._points = points; - - /** - * Private internal value. - * The inner radius of the star. - * - * @name Phaser.GameObjects.Star#_innerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._innerRadius = innerRadius; - - /** - * Private internal value. - * The outer radius of the star. - * - * @name Phaser.GameObjects.Star#_outerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._outerRadius = outerRadius; - - this.setPosition(x, y); - this.setSize(outerRadius * 2, outerRadius * 2); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Sets the number of points that make up the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setPoints - * @since 3.13.0 - * - * @param {number} value - The amount of points the Star will have. - * - * @return {this} This Game Object instance. - */ - setPoints: function (value) - { - this._points = value; - - return this.updateData(); - }, - - /** - * Sets the inner radius of the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setInnerRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the inner radius to. - * - * @return {this} This Game Object instance. - */ - setInnerRadius: function (value) - { - this._innerRadius = value; - - return this.updateData(); - }, - - /** - * Sets the outer radius of the Star shape. - * This call can be chained. - * - * @method Phaser.GameObjects.Star#setOuterRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the outer radius to. - * - * @return {this} This Game Object instance. - */ - setOuterRadius: function (value) - { - this._outerRadius = value; - - return this.updateData(); - }, - - /** - * The number of points that make up the Star shape. - * - * @name Phaser.GameObjects.Star#points - * @type {number} - * @default 5 - * @since 3.13.0 - */ - points: { - - get: function () - { - return this._points; - }, - - set: function (value) - { - this._points = value; - - this.updateData(); - } - - }, - - /** - * The inner radius of the Star shape. - * - * @name Phaser.GameObjects.Star#innerRadius - * @type {number} - * @default 32 - * @since 3.13.0 - */ - innerRadius: { - - get: function () - { - return this._innerRadius; - }, - - set: function (value) - { - this._innerRadius = value; - - this.updateData(); - } - - }, - - /** - * The outer radius of the Star shape. - * - * @name Phaser.GameObjects.Star#outerRadius - * @type {number} - * @default 64 - * @since 3.13.0 - */ - outerRadius: { - - get: function () - { - return this._outerRadius; - }, - - set: function (value) - { - this._outerRadius = value; - - this.updateData(); - } - - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Star#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - - var points = this._points; - var innerRadius = this._innerRadius; - var outerRadius = this._outerRadius; - - var rot = Math.PI / 2 * 3; - var step = Math.PI / points; - - // So origin 0.5 = the center of the star - var x = outerRadius; - var y = outerRadius; - - path.push(x, y + -outerRadius); - - for (var i = 0; i < points; i++) - { - path.push(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius); - - rot += step; - - path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius); - - rot += step; - } - - path.push(x, y + -outerRadius); - - this.pathIndexes = Earcut(path); - this.pathData = path; - - return this; - } - -}); - -module.exports = Star; - - -/***/ }), -/* 453 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Shape = __webpack_require__(32); -var GeomTriangle = __webpack_require__(82); -var TriangleRender = __webpack_require__(1121); - -/** - * @classdesc - * The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can - * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling - * it for input or physics. It provides a quick and easy way for you to render this shape in your - * game without using a texture, while still taking advantage of being fully batched in WebGL. - * - * This shape supports both fill and stroke colors. - * - * The Triangle consists of 3 lines, joining up to form a triangular shape. You can control the - * position of each point of these lines. The triangle is always closed and cannot have an open - * face. If you require that, consider using a Polygon instead. - * - * @class Triangle - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 - * - * @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 {number} [x1=0] - The horizontal position of the first point in the triangle. - * @param {number} [y1=128] - The vertical position of the first point in the triangle. - * @param {number} [x2=64] - The horizontal position of the second point in the triangle. - * @param {number} [y2=0] - The vertical position of the second point in the triangle. - * @param {number} [x3=128] - The horizontal position of the third point in the triangle. - * @param {number} [y3=128] - The vertical position of the third point in the triangle. - * @param {number} [fillColor] - The color the triangle will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - */ -var Triangle = new Class({ - - Extends: Shape, - - Mixins: [ - TriangleRender - ], - - initialize: - - function Triangle (scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 128; } - if (x2 === undefined) { x2 = 64; } - if (y2 === undefined) { y2 = 0; } - if (x3 === undefined) { x3 = 128; } - if (y3 === undefined) { y3 = 128; } - - Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); - - var width = this.geom.right - this.geom.left; - var height = this.geom.bottom - this.geom.top; - - this.setPosition(x, y); - this.setSize(width, height); - - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } - - this.updateDisplayOrigin(); - this.updateData(); - }, - - /** - * Sets the data for the lines that make up this Triangle shape. - * - * @method Phaser.GameObjects.Triangle#setTo - * @since 3.13.0 - * - * @param {number} [x1=0] - The horizontal position of the first point in the triangle. - * @param {number} [y1=0] - The vertical position of the first point in the triangle. - * @param {number} [x2=0] - The horizontal position of the second point in the triangle. - * @param {number} [y2=0] - The vertical position of the second point in the triangle. - * @param {number} [x3=0] - The horizontal position of the third point in the triangle. - * @param {number} [y3=0] - The vertical position of the third point in the triangle. - * - * @return {this} This Game Object instance. - */ - setTo: function (x1, y1, x2, y2, x3, y3) - { - this.geom.setTo(x1, y1, x2, y2, x3, y3); - - return this.updateData(); - }, - - /** - * Internal method that updates the data and path values. - * - * @method Phaser.GameObjects.Triangle#updateData - * @private - * @since 3.13.0 - * - * @return {this} This Game Object instance. - */ - updateData: function () - { - var path = []; - var tri = this.geom; - var line = this._tempLine; - - tri.getLineA(line); - - path.push(line.x1, line.y1, line.x2, line.y2); - - tri.getLineB(line); - - path.push(line.x2, line.y2); - - tri.getLineC(line); - - path.push(line.x2, line.y2); - - this.pathData = path; - - return this; - } - -}); - -module.exports = Triangle; - - -/***/ }), -/* 454 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); -var Length = __webpack_require__(63); - -/** - * Returns a Point from around the perimeter of a Triangle. - * - * @function Phaser.Geom.Triangle.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the point on its perimeter from. - * @param {number} position - The position along the perimeter of the triangle. A value between 0 and 1. - * @param {(Phaser.Geom.Point|object)} [out] - An option Point, or Point-like object to store the value in. If not given a new Point will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point object containing the given position from the perimeter of the triangle. - */ -var GetPoint = function (triangle, position, out) -{ - if (out === undefined) { out = new Point(); } - - var line1 = triangle.getLineA(); - var line2 = triangle.getLineB(); - var line3 = triangle.getLineC(); - - if (position <= 0 || position >= 1) - { - out.x = line1.x1; - out.y = line1.y1; - - return out; - } - - var length1 = Length(line1); - var length2 = Length(line2); - var length3 = Length(line3); - - var perimeter = length1 + length2 + length3; - - var p = perimeter * position; - var localPosition = 0; - - // Which line is it on? - - if (p < length1) - { - // Line 1 - localPosition = p / length1; - - out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; - out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; - } - else if (p > length1 + length2) - { - // Line 3 - p -= length1 + length2; - localPosition = p / length3; - - out.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; - out.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; - } - else - { - // Line 2 - p -= length1; - localPosition = p / length2; - - out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } - - return out; -}; - -module.exports = GetPoint; - - -/***/ }), -/* 455 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Length = __webpack_require__(63); -var Point = __webpack_require__(4); - -/** - * Returns an array of evenly spaced points on the perimeter of a Triangle. - * - * @function Phaser.Geom.Triangle.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the points from. - * @param {number} quantity - The number of evenly spaced points to return. Set to 0 to return an arbitrary number of points based on the `stepRate`. - * @param {number} stepRate - If `quantity` is 0, the distance between each returned point. - * @param {(array|Phaser.Geom.Point[])} [out] - An array to which the points should be appended. - * - * @return {(array|Phaser.Geom.Point[])} The modified `out` array, or a new array if none was provided. - */ -var GetPoints = function (triangle, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } - - var line1 = triangle.getLineA(); - var line2 = triangle.getLineB(); - var line3 = triangle.getLineC(); - - var length1 = Length(line1); - var length2 = Length(line2); - var length3 = Length(line3); - - var perimeter = length1 + length2 + length3; - - // 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 / stepRate; - } - - for (var i = 0; i < quantity; i++) - { - var p = perimeter * (i / quantity); - var localPosition = 0; - - var point = new Point(); - - // Which line is it on? - - if (p < length1) - { - // Line 1 - localPosition = p / length1; - - point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; - point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; - } - else if (p > length1 + length2) - { - // Line 3 - p -= length1 + length2; - localPosition = p / length3; - - point.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; - point.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; - } - else - { - // Line 2 - p -= length1; - localPosition = p / length2; - - point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } - - out.push(point); - } - - return out; -}; - -module.exports = GetPoints; - - -/***/ }), -/* 456 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets a value in an object, allowing for dot notation to control the depth of the property. - * - * For example: - * - * ```javascript - * var data = { - * world: { - * position: { - * x: 200, - * y: 100 - * } - * } - * }; - * - * SetValue(data, 'world.position.y', 300); - * - * console.log(data.world.position.y); // 300 - * ``` - * - * @function Phaser.Utils.Objects.SetValue - * @since 3.17.0 - * - * @param {object} source - The object to set the value in. - * @param {string} key - The name of the property in the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - * @param {any} value - The value to set into the property, if found in the source object. - * - * @return {boolean} `true` if the property key was valid and the value was set, otherwise `false`. - */ -var SetValue = function (source, key, value) -{ - if (!source || typeof source === 'number') - { - return false; - } - else if (source.hasOwnProperty(key)) - { - source[key] = value; - - return true; - } - else if (key.indexOf('.') !== -1) - { - var keys = key.split('.'); - var parent = source; - var prev = source; - - // 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 - prev = parent; - parent = parent[keys[i]]; - } - else - { - return false; - } - } - - prev[keys[keys.length - 1]] = value; - - return true; - } - - return false; -}; - -module.exports = SetValue; - - -/***/ }), -/* 457 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Face = __webpack_require__(111); -var Vertex = __webpack_require__(113); - -/** - * Generates a set of Face and Vertex objects by parsing the given data. - * - * This method will take vertex data in one of two formats, based on the `containsZ` parameter. - * - * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default) - * - * If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true. - * - * The `uvs` parameter is a numeric array consisting of `u` and `v` pairs. - * - * The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well. - * - * The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added. - * - * The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created. - * - * The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created. - * - * When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices. - * - * The following example will create a 256 x 256 sized quad using an index array: - * - * ```javascript - * const vertices = [ - * -128, 128, - * 128, 128, - * -128, -128, - * 128, -128 - * ]; - * - * const uvs = [ - * 0, 1, - * 1, 1, - * 0, 0, - * 1, 0 - * ]; - * - * const indices = [ 0, 2, 1, 2, 3, 1 ]; - * - * GenerateVerts(vertices, uvs, indicies); - * ``` - * - * If the data is not indexed, it's assumed that the arrays all contain sequential data. - * - * @function Phaser.Geom.Mesh.GenerateVerts - * @since 3.50.0 - * - * @param {number[]} vertices - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. - * @param {number[]} uvs - The UVs pairs array. - * @param {number[]} [indicies] - Optional vertex indicies array. If you don't have one, pass `null` or an empty array. - * @param {boolean} [containsZ=false] - Does the vertices data include a `z` component? - * @param {number[]} [normals] - Optional vertex normals array. If you don't have one, pass `null` or an empty array. - * @param {number|number[]} [colors=0xffffff] - An array of colors, one per vertex, or a single color value applied to all vertices. - * @param {number|number[]} [alphas=1] - An array of alpha values, one per vertex, or a single alpha value applied to all vertices. - * - * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. - */ -var GenerateVerts = function (vertices, uvs, indicies, containsZ, normals, colors, alphas) -{ - if (containsZ === undefined) { containsZ = false; } - if (colors === undefined) { colors = 0xffffff; } - if (alphas === undefined) { alphas = 1; } - - if (vertices.length !== uvs.length) - { - console.warn('GenerateVerts: vertices and uvs count not equal'); - return; - } - - var result = { - faces: [], - verts: [] - }; - - var i; - - var x; - var y; - var z; - - var u; - var v; - - var color; - var alpha; - - var normalX; - var normalY; - var normalZ; - - var iInc = (containsZ) ? 3 : 2; - - var isColorArray = Array.isArray(colors); - var isAlphaArray = Array.isArray(alphas); - - if (Array.isArray(indicies) && indicies.length > 0) - { - for (i = 0; i < indicies.length; i++) - { - var index1 = indicies[i]; - var index2 = indicies[i] * 2; - var index3 = indicies[i] * iInc; - - x = vertices[index3]; - y = vertices[index3 + 1]; - z = (containsZ) ? vertices[index3 + 2] : 0; - - u = uvs[index2]; - v = uvs[index2 + 1]; - - color = (isColorArray) ? colors[index1] : colors; - alpha = (isAlphaArray) ? alphas[index1] : alphas; - - normalX = 0; - normalY = 0; - normalZ = 0; - - if (normals) - { - normalX = normals[index3]; - normalY = normals[index3 + 1]; - normalZ = (containsZ) ? normals[index3 + 2] : 0; - } - - result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); - } - } - else - { - var uvIndex = 0; - var colorIndex = 0; - - for (i = 0; i < vertices.length; i += iInc) - { - x = vertices[i]; - y = vertices[i + 1]; - z = (containsZ) ? vertices[i + 2] : 0; - - u = uvs[uvIndex]; - v = uvs[uvIndex + 1]; - - color = (isColorArray) ? colors[colorIndex] : colors; - alpha = (isAlphaArray) ? alphas[colorIndex] : alphas; - - normalX = 0; - normalY = 0; - normalZ = 0; - - if (normals) - { - normalX = normals[i]; - normalY = normals[i + 1]; - normalZ = (containsZ) ? normals[i + 2] : 0; - } - - result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); - - uvIndex += 2; - colorIndex++; - } - } - - for (i = 0; i < result.verts.length; i += 3) - { - var vert1 = result.verts[i]; - var vert2 = result.verts[i + 1]; - var vert3 = result.verts[i + 2]; - - result.faces.push(new Face(vert1, vert2, vert3)); - } - - return result; -}; - -module.exports = GenerateVerts; - - -/***/ }), -/* 458 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Face = __webpack_require__(111); -var Matrix4 = __webpack_require__(65); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); - -var tempPosition = new Vector3(); -var tempRotation = new Vector3(); -var tempMatrix = new Matrix4(); - -/** - * This method will return an object containing Face and Vertex instances, generated - * from the parsed triangulated OBJ Model data given to this function. - * - * The obj data should have been parsed in advance via the ParseObj function: - * - * ```javascript - * var data = Phaser.Geom.Mesh.ParseObj(rawData, flipUV); - * - * var results = GenerateObjVerts(data); - * ``` - * - * Alternatively, you can parse obj files loaded via the OBJFile loader: - * - * ```javascript - * preload () - * { - * this.load.obj('alien', 'assets/3d/alien.obj); - * } - * - * var results = GenerateObjVerts(this.cache.obj.get('alien)); - * ``` - * - * Make sure your 3D package has triangulated the model data prior to exporting it. - * - * You can use the data returned by this function to populate the vertices of a Mesh Game Object. - * - * You may add multiple models to a single Mesh, although they will act as one when - * moved or rotated. You can scale the model data, should it be too small (or large) to visualize. - * You can also offset the model via the `x`, `y` and `z` parameters. - * - * @function Phaser.Geom.Mesh.GenerateObjVerts - * @since 3.50.0 - * - * @param {Phaser.Types.Geom.Mesh.OBJData} data - The parsed OBJ model data. - * @param {Phaser.GameObjects.Mesh} [mesh] - An optional Mesh Game Object. If given, the generated Faces will be automatically added to this Mesh. Set to `null` to skip. - * @param {number} [scale=1] - An amount to scale the model data by. Use this if the model has exported too small, or large, to see. - * @param {number} [x=0] - Translate the model x position by this amount. - * @param {number} [y=0] - Translate the model y position by this amount. - * @param {number} [z=0] - Translate the model z position by this amount. - * @param {number} [rotateX=0] - Rotate the model on the x axis by this amount, in radians. - * @param {number} [rotateY=0] - Rotate the model on the y axis by this amount, in radians. - * @param {number} [rotateZ=0] - Rotate the model on the z axis by this amount, in radians. - * @param {boolean} [zIsUp=true] - Is the z axis up (true), or is y axis up (false)? - * - * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. - */ -var GenerateObjVerts = function (data, mesh, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) -{ - if (scale === undefined) { scale = 1; } - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (z === undefined) { z = 0; } - if (rotateX === undefined) { rotateX = 0; } - if (rotateY === undefined) { rotateY = 0; } - if (rotateZ === undefined) { rotateZ = 0; } - if (zIsUp === undefined) { zIsUp = true; } - - var result = { - faces: [], - verts: [] - }; - - var materials = data.materials; - - tempPosition.set(x, y, z); - tempRotation.set(rotateX, rotateY, rotateZ); - tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); - - for (var m = 0; m < data.models.length; m++) - { - var model = data.models[m]; - - var vertices = model.vertices; - var textureCoords = model.textureCoords; - var faces = model.faces; - - for (var i = 0; i < faces.length; i++) - { - var face = faces[i]; - - var v1 = face.vertices[0]; - var v2 = face.vertices[1]; - var v3 = face.vertices[2]; - - var m1 = vertices[v1.vertexIndex]; - var m2 = vertices[v2.vertexIndex]; - var m3 = vertices[v3.vertexIndex]; - - var t1 = v1.textureCoordsIndex; - var t2 = v2.textureCoordsIndex; - var t3 = v3.textureCoordsIndex; - - var uv1 = (t1 === -1) ? { u: 0, v: 1 } : textureCoords[t1]; - var uv2 = (t2 === -1) ? { u: 0, v: 0 } : textureCoords[t2]; - var uv3 = (t3 === -1) ? { u: 1, v: 1 } : textureCoords[t3]; - - var color = 0xffffff; - - if (face.material !== '' && materials[face.material]) - { - color = materials[face.material]; - } - - var vert1 = new Vertex(m1.x * scale, m1.y * scale, m1.z * scale, uv1.u, uv1.v, color).transformMat4(tempMatrix); - var vert2 = new Vertex(m2.x * scale, m2.y * scale, m2.z * scale, uv2.u, uv2.v, color).transformMat4(tempMatrix); - var vert3 = new Vertex(m3.x * scale, m3.y * scale, m3.z * scale, uv3.u, uv3.v, color).transformMat4(tempMatrix); - - result.verts.push(vert1, vert2, vert3); - result.faces.push(new Face(vert1, vert2, vert3)); - } - } - - if (mesh) - { - mesh.faces = mesh.faces.concat(result.faces); - mesh.vertices = mesh.vertices.concat(result.verts); - } - - return result; -}; - -module.exports = GenerateObjVerts; - - -/***/ }), -/* 459 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Circle = __webpack_require__(61); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var RGB = __webpack_require__(195); -var Utils = __webpack_require__(12); - -/** - * @classdesc - * A 2D point light. - * - * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. - * - * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. - * - * They can also simply be used to represent a point light for your own purposes. - * - * @class Light - * @extends Phaser.Geom.Circle - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible - * - * @param {number} x - The horizontal position of the light. - * @param {number} y - The vertical position of the light. - * @param {number} radius - The radius of the light. - * @param {number} r - The red color of the light. A value between 0 and 1. - * @param {number} g - The green color of the light. A value between 0 and 1. - * @param {number} b - The blue color of the light. A value between 0 and 1. - * @param {number} intensity - The intensity of the light. - */ -var Light = new Class({ - - Extends: Circle, - - Mixins: [ - Components.ScrollFactor, - Components.Visible - ], - - initialize: - - function Light (x, y, radius, r, g, b, intensity) - { - Circle.call(this, x, y, radius); - - /** - * The color of the light. - * - * @name Phaser.GameObjects.Light#color - * @type {Phaser.Display.RGB} - * @since 3.50.0 - */ - this.color = new RGB(r, g, b); - - /** - * The intensity of the light. - * - * @name Phaser.GameObjects.Light#intensity - * @type {number} - * @since 3.50.0 - */ - this.intensity = intensity; - - /** - * 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 {number} - * @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; - - this.setScrollFactor(1, 1); - }, - - /** - * 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.Light#willRender - * @since 3.50.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 !(Light.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); - }, - - /** - * Set the color of the light from a single integer RGB value. - * - * @method Phaser.GameObjects.Light#setColor - * @since 3.0.0 - * - * @param {number} rgb - The integer RGB color of the light. - * - * @return {this} This Light object. - */ - setColor: function (rgb) - { - var color = Utils.getFloatsFromUintRGB(rgb); - - this.color.set(color[0], color[1], color[2]); - - return this; - }, - - /** - * Set the intensity of the light. - * - * @method Phaser.GameObjects.Light#setIntensity - * @since 3.0.0 - * - * @param {number} intensity - The intensity of the light. - * - * @return {this} This Light object. - */ - setIntensity: function (intensity) - { - this.intensity = intensity; - - return this; - }, - - /** - * Set the radius of the light. - * - * @method Phaser.GameObjects.Light#setRadius - * @since 3.0.0 - * - * @param {number} radius - The radius of the light. - * - * @return {this} This Light object. - */ - setRadius: function (radius) - { - this.radius = radius; - - return this; - } - -}); - -/** - * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. - * - * @constant {number} RENDER_MASK - * @memberof Phaser.GameObjects.Light - * @default - */ -Light.RENDER_MASK = 15; - -module.exports = Light; - - -/***/ }), -/* 460 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircleToRectangle = __webpack_require__(149); -var Class = __webpack_require__(0); -var DistanceBetween = __webpack_require__(48); -var Light = __webpack_require__(459); -var PointLight = __webpack_require__(148); -var RGB = __webpack_require__(195); -var SpliceOne = __webpack_require__(74); -var StableSort = __webpack_require__(79); -var Utils = __webpack_require__(12); - -/** - * @callback LightForEach - * - * @param {Phaser.GameObjects.Light} light - The Light. - */ - -/** - * @classdesc - * Manages Lights for a Scene. - * - * Affects the rendering of Game Objects using the `Light2D` pipeline. - * - * @class LightsManager - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - */ -var LightsManager = new Class({ - - initialize: - - function LightsManager () - { - /** - * The Lights in the Scene. - * - * @name Phaser.GameObjects.LightsManager#lights - * @type {Phaser.GameObjects.Light[]} - * @default [] - * @since 3.0.0 - */ - this.lights = []; - - /** - * The ambient color. - * - * @name Phaser.GameObjects.LightsManager#ambientColor - * @type {Phaser.Display.RGB} - * @since 3.50.0 - */ - this.ambientColor = new RGB(0.1, 0.1, 0.1); - - /** - * Whether the Lights Manager is enabled. - * - * @name Phaser.GameObjects.LightsManager#active - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.active = false; - - /** - * The maximum number of lights that a single Camera and the lights shader can process. - * Change this via the `maxLights` property in your game config, as it cannot be changed at runtime. - * - * @name Phaser.GameObjects.LightsManager#maxLights - * @type {number} - * @readonly - * @since 3.15.0 - */ - this.maxLights = -1; - - /** - * The number of lights that the LightPipeline processed in the _previous_ frame. - * - * @name Phaser.GameObjects.LightsManager#visibleLights - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.visibleLights = 0; - }, - - addPointLight: function (x, y, color, radius, intensity) - { - return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity)); - }, - - /** - * Enable the Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#enable - * @since 3.0.0 - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - enable: function () - { - if (this.maxLights === -1) - { - this.maxLights = this.scene.sys.renderer.config.maxLights; - } - - this.active = true; - - return this; - }, - - /** - * Disable the Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#disable - * @since 3.0.0 - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - disable: function () - { - this.active = false; - - return this; - }, - - /** - * Get all lights that can be seen by the given Camera. - * - * It will automatically cull lights that are outside the world view of the Camera. - * - * If more lights are returned than supported by the pipeline, the lights are then culled - * based on the distance from the center of the camera. Only those closest are rendered. - * - * @method Phaser.GameObjects.LightsManager#getLights - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. - * - * @return {Phaser.GameObjects.Light[]} The culled Lights. - */ - getLights: function (camera) - { - var lights = this.lights; - var worldView = camera.worldView; - - var visibleLights = []; - - for (var i = 0; i < lights.length; i++) - { - var light = lights[i]; - - if (light.willRender(camera) && CircleToRectangle(light, worldView)) - { - visibleLights.push({ - light: light, - distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY) - }); - } - } - - if (visibleLights.length > this.maxLights) - { - // We've got too many lights, so sort by distance from camera and cull those far away - // This isn't ideal because it doesn't factor in the radius of the lights, but it'll do for now - // and is significantly better than we had before! - - StableSort(visibleLights, this.sortByDistance); - - visibleLights = visibleLights.slice(0, this.maxLights); - } - - this.visibleLights = visibleLights.length; - - return visibleLights; - }, - - sortByDistance: function (a, b) - { - return (a.distance >= b.distance); - }, - - /** - * Set the ambient light color. - * - * @method Phaser.GameObjects.LightsManager#setAmbientColor - * @since 3.0.0 - * - * @param {number} rgb - The integer RGB color of the ambient light. - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - setAmbientColor: function (rgb) - { - var color = Utils.getFloatsFromUintRGB(rgb); - - this.ambientColor.set(color[0], color[1], color[2]); - - return this; - }, - - /** - * Returns the maximum number of Lights allowed to appear at once. - * - * @method Phaser.GameObjects.LightsManager#getMaxVisibleLights - * @since 3.0.0 - * - * @return {number} The maximum number of Lights allowed to appear at once. - */ - getMaxVisibleLights: function () - { - return this.maxLights; - }, - - /** - * Get the number of Lights managed by this Lights Manager. - * - * @method Phaser.GameObjects.LightsManager#getLightCount - * @since 3.0.0 - * - * @return {number} The number of Lights managed by this Lights Manager. - */ - getLightCount: function () - { - return this.lights.length; - }, - - /** - * Add a Light. - * - * @method Phaser.GameObjects.LightsManager#addLight - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal position of the Light. - * @param {number} [y=0] - The vertical position of the Light. - * @param {number} [radius=100] - The radius of the Light. - * @param {number} [rgb=0xffffff] - The integer RGB color of the light. - * @param {number} [intensity=1] - The intensity of the Light. - * - * @return {Phaser.GameObjects.Light} The Light that was added. - */ - addLight: function (x, y, radius, rgb, intensity) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (radius === undefined) { radius = 128; } - if (rgb === undefined) { rgb = 0xffffff; } - if (intensity === undefined) { intensity = 1; } - - var color = Utils.getFloatsFromUintRGB(rgb); - - var light = new Light(x, y, radius, color[0], color[1], color[2], intensity); - - this.lights.push(light); - - return light; - }, - - /** - * Remove a Light. - * - * @method Phaser.GameObjects.LightsManager#removeLight - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Light} light - The Light to remove. - * - * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. - */ - removeLight: function (light) - { - var index = this.lights.indexOf(light); - - if (index >= 0) - { - SpliceOne(this.lights, index); - } - - return this; - }, - - /** - * Shut down the Lights Manager. - * - * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and - * culled Lights. - * - * @method Phaser.GameObjects.LightsManager#shutdown - * @since 3.0.0 - */ - shutdown: function () - { - this.lights.length = 0; - }, - - /** - * Destroy the Lights Manager. - * - * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. - * - * @method Phaser.GameObjects.LightsManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - } - -}); - -module.exports = LightsManager; - - -/***/ }), -/* 461 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(55); -var Extend = __webpack_require__(19); - -/** - * @namespace Phaser.Geom - */ - -var Geom = { - - Circle: __webpack_require__(1185), - Ellipse: __webpack_require__(1195), - Intersects: __webpack_require__(462), - Line: __webpack_require__(1215), - Mesh: __webpack_require__(1237), - Point: __webpack_require__(1240), - Polygon: __webpack_require__(1254), - Rectangle: __webpack_require__(480), - Triangle: __webpack_require__(1287) - -}; - -// Merge in the consts -Geom = Extend(false, Geom, CONST); - -module.exports = Geom; - - -/***/ }), -/* 462 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Geom.Intersects - */ - -module.exports = { - - CircleToCircle: __webpack_require__(226), - CircleToRectangle: __webpack_require__(149), - GetCircleToCircle: __webpack_require__(1205), - GetCircleToRectangle: __webpack_require__(1206), - GetLineToCircle: __webpack_require__(227), - GetLineToLine: __webpack_require__(463), - GetLineToPoints: __webpack_require__(464), - GetLineToPolygon: __webpack_require__(465), - GetLineToRectangle: __webpack_require__(229), - GetRaysFromPointToPolygon: __webpack_require__(1207), - GetRectangleIntersection: __webpack_require__(1208), - GetRectangleToRectangle: __webpack_require__(1209), - GetRectangleToTriangle: __webpack_require__(1210), - GetTriangleToCircle: __webpack_require__(1211), - GetTriangleToLine: __webpack_require__(470), - GetTriangleToTriangle: __webpack_require__(1212), - LineToCircle: __webpack_require__(228), - LineToLine: __webpack_require__(91), - LineToRectangle: __webpack_require__(466), - PointToLine: __webpack_require__(474), - PointToLineSegment: __webpack_require__(1213), - RectangleToRectangle: __webpack_require__(112), - RectangleToTriangle: __webpack_require__(467), - RectangleToValues: __webpack_require__(1214), - TriangleToCircle: __webpack_require__(469), - TriangleToLine: __webpack_require__(471), - TriangleToTriangle: __webpack_require__(472) - -}; - - -/***/ }), -/* 463 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); - -/** - * Checks for intersection between the two line segments and returns the intersection point as a Vector3, - * or `null` if the lines are parallel, or do not intersect. - * - * The `z` property of the Vector3 contains the intersection distance, which can be used to find - * the closest intersecting point from a group of line segments. - * - * @function Phaser.Geom.Intersects.GetLineToLine - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line1 - The first line segment to check. - * @param {Phaser.Geom.Line} line2 - The second line segment to check. - * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. - * - * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. - */ -var GetLineToLine = function (line1, line2, out) -{ - var x1 = line1.x1; - var y1 = line1.y1; - var x2 = line1.x2; - var y2 = line1.y2; - - var x3 = line2.x1; - var y3 = line2.y1; - var x4 = line2.x2; - var y4 = line2.y2; - - var dx1 = x2 - x1; - var dy1 = y2 - y1; - - var dx2 = x4 - x3; - var dy2 = y4 - y3; - - var denom = dy2 * dx1 - dx2 * dy1; - - // Make sure there is not a division by zero - this also indicates that the lines are parallel. - // If numA and numB were both equal to zero the lines would be on top of each other (coincidental). - // This check is not done because it is not necessary for this implementation (the parallel check accounts for this). - - if (dx1 === 0 || denom === 0) - { - return false; - } - - var T2 = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); - var T1 = (x3 + dx2 * T2 - x1) / dx1; - - // Intersects? - if (T1 < 0 || T2 < 0 || T2 > 1) - { - return null; - } - - if (out === undefined) - { - out = new Vector3(); - } - - return out.set( - x1 + dx1 * T1, - y1 + dy1 * T1, - T1 - ); -}; - -module.exports = GetLineToLine; - - -/***/ }), -/* 464 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); -var GetLineToLine = __webpack_require__(463); -var Line = __webpack_require__(45); - -// Temp calculation segment -var segment = new Line(); - -// Temp vec3 -var tempIntersect = new Vector3(); - -/** - * Checks for the closest point of intersection between a line segment and an array of points, where each pair - * of points are converted to line segments for the intersection tests. - * - * If no intersection is found, this function returns `null`. - * - * If intersection was found, a Vector3 is returned with the following properties: - * - * The `x` and `y` components contain the point of the intersection. - * The `z` component contains the closest distance. - * - * @function Phaser.Geom.Intersects.GetLineToPoints - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Math.Vector2[] | Phaser.Geom.Point[]} points - An array of points to check. - * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. - * - * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. - */ -var GetLineToPoints = function (line, points, out) -{ - if (out === undefined) { out = new Vector3(); } - - var closestIntersect = false; - - // Reset our vec3s - out.set(); - tempIntersect.set(); - - var prev = points[0]; - - for (var i = 1; i < points.length; i++) - { - var current = points[i]; - - segment.setTo(prev.x, prev.y, current.x, current.y); - - prev = current; - - if (GetLineToLine(line, segment, tempIntersect)) - { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.copy(tempIntersect); - - closestIntersect = true; - } - } - } - - return (closestIntersect) ? out : null; -}; - -module.exports = GetLineToPoints; - - -/***/ }), -/* 465 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector3 = __webpack_require__(36); -var Vector4 = __webpack_require__(138); -var GetLineToPoints = __webpack_require__(464); - -// Temp vec3 -var tempIntersect = new Vector3(); - -/** - * Checks for the closest point of intersection between a line segment and an array of polygons. - * - * If no intersection is found, this function returns `null`. - * - * If intersection was found, a Vector4 is returned with the following properties: - * - * The `x` and `y` components contain the point of the intersection. - * The `z` component contains the closest distance. - * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. - * - * @function Phaser.Geom.Intersects.GetLineToPolygon - * @since 3.50.0 - * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check. - * @param {Phaser.Math.Vector4} [out] - A Vector4 to store the intersection results in. - * - * @return {Phaser.Math.Vector4} A Vector4 containing the intersection results, or `null`. - */ -var GetLineToPolygon = function (line, polygons, out) -{ - if (out === undefined) { out = new Vector4(); } - - if (!Array.isArray(polygons)) - { - polygons = [ polygons ]; - } - - var closestIntersect = false; - - // Reset our vec4s - out.set(); - tempIntersect.set(); - - for (var i = 0; i < polygons.length; i++) - { - if (GetLineToPoints(line, polygons[i].points, tempIntersect)) - { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); - - closestIntersect = true; - } - } - } - - return (closestIntersect) ? out : null; -}; - -module.exports = GetLineToPolygon; - - -/***/ }), -/* 466 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Checks for intersection between the Line and a Rectangle shape, or a rectangle-like - * object, with public `x`, `y`, `right` and `bottom` properties, such as a Sprite or Body. - * - * An intersection is considered valid if: - * - * The line starts within, or ends within, the Rectangle. - * The line segment intersects one of the 4 rectangle edges. - * - * The for the purposes of this function rectangles are considered 'solid'. - * - * @function Phaser.Geom.Intersects.LineToRectangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The Line to check for intersection. - * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle to check for intersection. - * - * @return {boolean} `true` if the Line and the Rectangle intersect, `false` otherwise. - */ -var LineToRectangle = function (line, rect) -{ - var x1 = line.x1; - var y1 = line.y1; - - var x2 = line.x2; - var y2 = line.y2; - - var bx1 = rect.x; - var by1 = rect.y; - var bx2 = rect.right; - var by2 = rect.bottom; - - var t = 0; - - // If the start or end of the line is inside the rect then we assume - // collision, as rects are solid for our use-case. - - if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || - (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) - { - return true; - } - - if (x1 < bx1 && x2 >= bx1) - { - // Left edge - t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); - - if (t > by1 && t <= by2) - { - return true; - } - } - else if (x1 > bx2 && x2 <= bx2) - { - // Right edge - t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); - - if (t >= by1 && t <= by2) - { - return true; - } - } - - if (y1 < by1 && y2 >= by1) - { - // Top edge - t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); - - if (t >= bx1 && t <= bx2) - { - return true; - } - } - else if (y1 > by2 && y2 <= by2) - { - // Bottom edge - t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); - - if (t >= bx1 && t <= bx2) - { - return true; - } - } - - return false; -}; - -module.exports = LineToRectangle; - - -/***/ }), -/* 467 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToLine = __webpack_require__(91); -var Contains = __webpack_require__(56); -var ContainsArray = __webpack_require__(230); -var Decompose = __webpack_require__(468); - -/** - * Checks for intersection between Rectangle shape and Triangle shape. - * - * @function Phaser.Geom.Intersects.RectangleToTriangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. - * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. - * - * @return {boolean} A value of `true` if objects intersect; otherwise `false`. - */ -var RectangleToTriangle = function (rect, triangle) -{ - // First the cheapest ones: - - if ( - triangle.left > rect.right || - triangle.right < rect.left || - triangle.top > rect.bottom || - triangle.bottom < rect.top) - { - return false; - } - - var triA = triangle.getLineA(); - var triB = triangle.getLineB(); - var triC = triangle.getLineC(); - - // Are any of the triangle points within the rectangle? - - if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) - { - return true; - } - - if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) - { - return true; - } - - if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) - { - return true; - } - - // Cheap tests over, now to see if any of the lines intersect ... - - var rectA = rect.getLineA(); - var rectB = rect.getLineB(); - var rectC = rect.getLineC(); - var rectD = rect.getLineD(); - - if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) - { - return true; - } - - if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) - { - return true; - } - - if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) - { - return true; - } - - // None of the lines intersect, so are any rectangle points within the triangle? - - var points = Decompose(rect); - var within = ContainsArray(triangle, points, true); - - return (within.length > 0); -}; - -module.exports = RectangleToTriangle; - - -/***/ }), -/* 468 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Create an array of points for each corner of a Rectangle - * If an array is specified, each point object will be added to the end of the array, otherwise a new array will be created. - * - * @function Phaser.Geom.Rectangle.Decompose - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle object to be decomposed. - * @param {array} [out] - If provided, each point will be added to this array. - * - * @return {array} Will return the array you specified or a new array containing the points of the Rectangle. - */ -var Decompose = function (rect, out) -{ - if (out === undefined) { out = []; } - - out.push({ x: rect.x, y: rect.y }); - out.push({ x: rect.right, y: rect.y }); - out.push({ x: rect.right, y: rect.bottom }); - out.push({ x: rect.x, y: rect.bottom }); - - return out; -}; - -module.exports = Decompose; - - -/***/ }), -/* 469 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToCircle = __webpack_require__(228); -var Contains = __webpack_require__(110); - -/** - * Checks if a Triangle and a Circle intersect. - * - * A Circle intersects a Triangle if its center is located within it or if any of the Triangle's sides intersect the Circle. As such, the Triangle and the Circle are considered "solid" for the intersection. - * - * @function Phaser.Geom.Intersects.TriangleToCircle - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check for intersection. - * @param {Phaser.Geom.Circle} circle - The Circle to check for intersection. - * - * @return {boolean} `true` if the Triangle and the `Circle` intersect, otherwise `false`. - */ -var TriangleToCircle = function (triangle, circle) -{ - // First the cheapest ones: - - if ( - triangle.left > circle.right || - triangle.right < circle.left || - triangle.top > circle.bottom || - triangle.bottom < circle.top) - { - return false; - } - - if (Contains(triangle, circle.x, circle.y)) - { - return true; - } - - if (LineToCircle(triangle.getLineA(), circle)) - { - return true; - } - - if (LineToCircle(triangle.getLineB(), circle)) - { - return true; - } - - if (LineToCircle(triangle.getLineC(), circle)) - { - return true; - } - - return false; -}; - -module.exports = TriangleToCircle; - - -/***/ }), -/* 470 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); -var TriangleToLine = __webpack_require__(471); -var LineToLine = __webpack_require__(91); - -/** - * Checks if a Triangle and a Line intersect, and returns the intersection points as a Point object array. - * - * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". - * - * @function Phaser.Geom.Intersects.GetTriangleToLine - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. - * @param {Phaser.Geom.Line} line - The Line to check with. - * @param {array} [out] - An optional array in which to store the points of intersection. - * - * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. - */ -var GetTriangleToLine = function (triangle, line, out) -{ - if (out === undefined) { out = []; } - - if (TriangleToLine(triangle, line)) - { - var lineA = triangle.getLineA(); - var lineB = triangle.getLineB(); - var lineC = triangle.getLineC(); - - var output = [ new Point(), new Point(), new Point() ]; - - var result = [ - LineToLine(lineA, line, output[0]), - LineToLine(lineB, line, output[1]), - LineToLine(lineC, line, output[2]) - ]; - - for (var i = 0; i < 3; i++) - { - if (result[i]) { out.push(output[i]); } - } - } - - return out; -}; - -module.exports = GetTriangleToLine; - - -/***/ }), -/* 471 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LineToLine = __webpack_require__(91); - -/** - * Checks if a Triangle and a Line intersect. - * - * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". - * - * @function Phaser.Geom.Intersects.TriangleToLine - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. - * @param {Phaser.Geom.Line} line - The Line to check with. - * - * @return {boolean} `true` if the Triangle and the Line intersect, otherwise `false`. - */ -var TriangleToLine = function (triangle, line) -{ - // If the Triangle contains either the start or end point of the line, it intersects - if (triangle.contains(line.x1, line.y1) || triangle.contains(line.x2, line.y2)) - { - return true; - } - - // Now check the line against each line of the Triangle - if (LineToLine(triangle.getLineA(), line)) - { - return true; - } - - if (LineToLine(triangle.getLineB(), line)) - { - return true; - } - - if (LineToLine(triangle.getLineC(), line)) - { - return true; - } - - return false; -}; - -module.exports = TriangleToLine; - - -/***/ }), -/* 472 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ContainsArray = __webpack_require__(230); -var Decompose = __webpack_require__(473); -var LineToLine = __webpack_require__(91); - -/** - * Checks if two Triangles intersect. - * - * A Triangle intersects another Triangle if any pair of their lines intersects or if any point of one Triangle is within the other Triangle. Thus, the Triangles are considered "solid". - * - * @function Phaser.Geom.Intersects.TriangleToTriangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangleA - The first Triangle to check for intersection. - * @param {Phaser.Geom.Triangle} triangleB - The second Triangle to check for intersection. - * - * @return {boolean} `true` if the Triangles intersect, otherwise `false`. - */ -var TriangleToTriangle = function (triangleA, triangleB) -{ - // First the cheapest ones: - - if ( - triangleA.left > triangleB.right || - triangleA.right < triangleB.left || - triangleA.top > triangleB.bottom || - triangleA.bottom < triangleB.top) - { - return false; - } - - var lineAA = triangleA.getLineA(); - var lineAB = triangleA.getLineB(); - var lineAC = triangleA.getLineC(); - - var lineBA = triangleB.getLineA(); - var lineBB = triangleB.getLineB(); - var lineBC = triangleB.getLineC(); - - // Now check the lines against each line of TriangleB - if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) - { - return true; - } - - if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) - { - return true; - } - - if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) - { - return true; - } - - // Nope, so check to see if any of the points of triangleA are within triangleB - - var points = Decompose(triangleA); - var within = ContainsArray(triangleB, points, true); - - if (within.length > 0) - { - return true; - } - - // Finally check to see if any of the points of triangleB are within triangleA - - points = Decompose(triangleB); - within = ContainsArray(triangleA, points, true); - - if (within.length > 0) - { - return true; - } - - return false; -}; - -module.exports = TriangleToTriangle; - - -/***/ }), -/* 473 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Decomposes a Triangle into an array of its points. - * - * @function Phaser.Geom.Triangle.Decompose - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to decompose. - * @param {array} [out] - An array to store the points into. - * - * @return {array} The provided `out` array, or a new array if none was provided, with three objects with `x` and `y` properties representing each point of the Triangle appended to it. - */ -var Decompose = function (triangle, out) -{ - if (out === undefined) { out = []; } - - out.push({ x: triangle.x1, y: triangle.y1 }); - out.push({ x: triangle.x2, y: triangle.y2 }); - out.push({ x: triangle.x3, y: triangle.y3 }); - - return out; -}; - -module.exports = Decompose; - - -/***/ }), -/* 474 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Florian Mertens - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Checks if the a Point falls between the two end-points of a Line, based on the given line thickness. - * - * Assumes that the line end points are circular, not square. - * - * @function Phaser.Geom.Intersects.PointToLine - * @since 3.0.0 - * - * @param {(Phaser.Geom.Point|any)} point - The point, or point-like object to check. - * @param {Phaser.Geom.Line} line - The line segment to test for intersection on. - * @param {number} [lineThickness=1] - The line thickness. Assumes that the line end points are circular. - * - * @return {boolean} `true` if the Point falls on the Line, otherwise `false`. - */ -var PointToLine = function (point, line, lineThickness) -{ - if (lineThickness === undefined) { lineThickness = 1; } - - var x1 = line.x1; - var y1 = line.y1; - - var x2 = line.x2; - var y2 = line.y2; - - var px = point.x; - var py = point.y; - - var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); - - if (L2 === 0) - { - return false; - } - - var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; - - // Assume line thickness is circular - if (r < 0) - { - // Outside line1 - return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); - } - else if ((r >= 0) && (r <= 1)) - { - // On the line segment - var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; - - return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); - } - else - { - // Outside line2 - return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); - } -}; - -module.exports = PointToLine; - - -/***/ }), -/* 475 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var MATH_CONST = __webpack_require__(14); -var Wrap = __webpack_require__(64); -var Angle = __webpack_require__(92); - -/** - * Get the angle of the normal of the given line in radians. - * - * @function Phaser.Geom.Line.NormalAngle - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the angle of the normal of. - * - * @return {number} The angle of the normal of the line in radians. - */ -var NormalAngle = function (line) -{ - var angle = Angle(line) - MATH_CONST.TAU; - - return Wrap(angle, -Math.PI, Math.PI); -}; - -module.exports = NormalAngle; - - -/***/ }), -/* 476 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var flip = true; - -var defaultModelName = 'untitled'; -var currentGroup = ''; -var currentMaterial = ''; - -/** - * @ignore - */ -function stripComments (line) -{ - var idx = line.indexOf('#'); - - return (idx > -1) ? line.substring(0, idx) : line; -} - -/** - * @ignore - */ -function currentModel (result) -{ - if (result.models.length === 0) - { - result.models.push({ - faces: [], - name: defaultModelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); - } - - currentGroup = ''; - - return result.models[result.models.length - 1]; -} - -/** - * @ignore - */ -function parseObject (lineItems, result) -{ - var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName; - - result.models.push({ - faces: [], - name: modelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); - - currentGroup = ''; -} - -/** - * @ignore - */ -function parseGroup (lineItems) -{ - if (lineItems.length === 2) - { - currentGroup = lineItems[1]; - } -} - -/** - * @ignore - */ -function parseVertexCoords (lineItems, result) -{ - var len = lineItems.length; - - var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - currentModel(result).vertices.push({ x: x, y: y, z: z }); -} - -/** - * @ignore - */ -function parseTextureCoords (lineItems, result) -{ - var len = lineItems.length; - - var u = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var v = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var w = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - if (isNaN(u)) - { - u = 0; - } - - if (isNaN(v)) - { - v = 0; - } - - if (isNaN(w)) - { - w = 0; - } - - if (flip) - { - v = 1 - v; - } - - currentModel(result).textureCoords.push({ u: u, v: v, w: w }); -} - -/** - * @ignore - */ -function parseVertexNormal (lineItems, result) -{ - var len = lineItems.length; - - var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; - - currentModel(result).vertexNormals.push({ x: x, y: y, z: z }); -} - -/** - * @ignore - */ -function parsePolygon (lineItems, result) -{ - var totalVertices = lineItems.length - 1; - - if (totalVertices < 3) - { - return; - } - - var face = { - group: currentGroup, - material: currentMaterial, - vertices: [] - }; - - for (var i = 0; i < totalVertices; i++) - { - var vertexString = lineItems[i + 1]; - var vertexValues = vertexString.split('/'); - var vvLen = vertexValues.length; - - if (vvLen < 1 || vvLen > 3) - { - continue; - } - - var vertexIndex = 0; - var textureCoordsIndex = 0; - var vertexNormalIndex = 0; - - vertexIndex = parseInt(vertexValues[0], 10); - - if (vvLen > 1 && vertexValues[1] !== '') - { - textureCoordsIndex = parseInt(vertexValues[1], 10); - } - - if (vvLen > 2) - { - vertexNormalIndex = parseInt(vertexValues[2], 10); - } - - if (vertexIndex !== 0) - { - // Negative vertex indices refer to the nth last defined vertex - // convert these to postive indices for simplicity - if (vertexIndex < 0) - { - vertexIndex = currentModel(result).vertices.length + 1 + vertexIndex; - } - - textureCoordsIndex -= 1; - vertexIndex -= 1; - vertexNormalIndex -= 1; - - face.vertices.push({ - textureCoordsIndex: textureCoordsIndex, - vertexIndex: vertexIndex, - vertexNormalIndex: vertexNormalIndex - }); - } - } - - currentModel(result).faces.push(face); -} - -/** - * @ignore - */ -function parseMtlLib (lineItems, result) -{ - if (lineItems.length >= 2) - { - result.materialLibraries.push(lineItems[1]); - } -} - -/** - * @ignore - */ -function parseUseMtl (lineItems) -{ - if (lineItems.length >= 2) - { - currentMaterial = lineItems[1]; - } -} - -/** - * Parses a Wavefront OBJ File, extracting the models from it and returning them in an array. - * - * The model data *must* be triangulated for a Mesh Game Object to be able to render it. - * - * @function Phaser.Geom.Mesh.ParseObj - * @since 3.50.0 - * - * @param {string} data - The OBJ File data as a raw string. - * @param {boolean} [flipUV=true] - Flip the UV coordinates? - * - * @return {Phaser.Types.Geom.Mesh.OBJData} The parsed model and material data. - */ -var ParseObj = function (data, flipUV) -{ - if (flipUV === undefined) { flipUV = true; } - - flip = flipUV; - - // Store results in here - var result = { - materials: {}, - materialLibraries: [], - models: [] - }; - - currentGroup = ''; - currentMaterial = ''; - - var lines = data.split('\n'); - - for (var i = 0; i < lines.length; i++) - { - var line = stripComments(lines[i]); - - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) - { - case 'o': - // Start A New Model - parseObject(lineItems, result); - break; - - case 'g': - // Start a new polygon group - parseGroup(lineItems); - break; - - case 'v': - // Define a vertex for the current model - parseVertexCoords(lineItems, result); - break; - - case 'vt': - // Texture Coords - parseTextureCoords(lineItems, result); - break; - - case 'vn': - // Define a vertex normal for the current model - parseVertexNormal(lineItems, result); - break; - - case 'f': - // Define a Face/Polygon - parsePolygon(lineItems, result); - break; - - case 'mtllib': - // Reference to a material library file (.mtl) - parseMtlLib(lineItems, result); - break; - - case 'usemtl': - // Sets the current material to be applied to polygons defined from this point forward - parseUseMtl(lineItems); - break; - } - } - - return result; -}; - -module.exports = ParseObj; - - -/***/ }), -/* 477 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetColor = __webpack_require__(100); - -/** - * Takes a Wavefront Material file and extracts the diffuse reflectivity of the named - * materials, converts them to integer color values and returns them. - * - * This is used internally by the `addOBJ` and `addModel` methods, but is exposed for - * public consumption as well. - * - * Note this only works with diffuse values, specified in the `Kd r g b` format, where - * `g` and `b` are optional, but `r` is required. It does not support spectral rfl files, - * or any other material statement (such as `Ka` or `Ks`) - * - * @method Phaser.Geom.Mesh.ParseObjMaterial - * @since 3.50.0 - * - * @param {string} mtl - The OBJ MTL file as a raw string, i.e. loaded via `this.load.text`. - * - * @return {object} The parsed material colors, where each property of the object matches the material name. - */ -var ParseObjMaterial = function (mtl) -{ - var output = {}; - - var lines = mtl.split('\n'); - - var currentMaterial = ''; - - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if (line.indexOf('#') === 0 || line === '') - { - continue; - } - - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) - { - case 'newmtl': - { - currentMaterial = lineItems[1]; - break; - } - - // The diffuse reflectivity of the current material - // Support r, [g], [b] format, where g and b are optional - case 'kd': - { - var r = Math.floor(lineItems[1] * 255); - var g = (lineItems.length >= 2) ? Math.floor(lineItems[2] * 255) : r; - var b = (lineItems.length >= 3) ? Math.floor(lineItems[3] * 255) : r; - - output[currentMaterial] = GetColor(r, g, b); - - break; - } - } - } - - return output; -}; - -module.exports = ParseObjMaterial; - - -/***/ }), -/* 478 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Calculate the magnitude of the point, which equivalent to the length of the line from the origin to this point. - * - * @function Phaser.Geom.Point.GetMagnitude - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - The point to calculate the magnitude for - * - * @return {number} The resulting magnitude - */ -var GetMagnitude = function (point) -{ - return Math.sqrt((point.x * point.x) + (point.y * point.y)); -}; - -module.exports = GetMagnitude; - - -/***/ }), -/* 479 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Calculates the square of magnitude of given point.(Can be used for fast magnitude calculation of point) - * - * @function Phaser.Geom.Point.GetMagnitudeSq - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - Returns square of the magnitude/length of given point. - * - * @return {number} Returns square of the magnitude of given point. - */ -var GetMagnitudeSq = function (point) -{ - return (point.x * point.x) + (point.y * point.y); -}; - -module.exports = GetMagnitudeSq; - - -/***/ }), -/* 480 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); - -Rectangle.Area = __webpack_require__(1261); -Rectangle.Ceil = __webpack_require__(1262); -Rectangle.CeilAll = __webpack_require__(1263); -Rectangle.CenterOn = __webpack_require__(186); -Rectangle.Clone = __webpack_require__(1264); -Rectangle.Contains = __webpack_require__(56); -Rectangle.ContainsPoint = __webpack_require__(1265); -Rectangle.ContainsRect = __webpack_require__(481); -Rectangle.CopyFrom = __webpack_require__(1266); -Rectangle.Decompose = __webpack_require__(468); -Rectangle.Equals = __webpack_require__(1267); -Rectangle.FitInside = __webpack_require__(1268); -Rectangle.FitOutside = __webpack_require__(1269); -Rectangle.Floor = __webpack_require__(1270); -Rectangle.FloorAll = __webpack_require__(1271); -Rectangle.FromPoints = __webpack_require__(194); -Rectangle.FromXY = __webpack_require__(1272); -Rectangle.GetAspectRatio = __webpack_require__(232); -Rectangle.GetCenter = __webpack_require__(1273); -Rectangle.GetPoint = __webpack_require__(166); -Rectangle.GetPoints = __webpack_require__(300); -Rectangle.GetSize = __webpack_require__(1274); -Rectangle.Inflate = __webpack_require__(1275); -Rectangle.Intersection = __webpack_require__(1276); -Rectangle.MarchingAnts = __webpack_require__(310); -Rectangle.MergePoints = __webpack_require__(1277); -Rectangle.MergeRect = __webpack_require__(1278); -Rectangle.MergeXY = __webpack_require__(1279); -Rectangle.Offset = __webpack_require__(1280); -Rectangle.OffsetPoint = __webpack_require__(1281); -Rectangle.Overlaps = __webpack_require__(1282); -Rectangle.Perimeter = __webpack_require__(128); -Rectangle.PerimeterPoint = __webpack_require__(1283); -Rectangle.Random = __webpack_require__(169); -Rectangle.RandomOutside = __webpack_require__(1284); -Rectangle.SameDimensions = __webpack_require__(1285); -Rectangle.Scale = __webpack_require__(1286); -Rectangle.Union = __webpack_require__(419); - -module.exports = Rectangle; - - -/***/ }), -/* 481 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Tests if one rectangle fully contains another. - * - * @function Phaser.Geom.Rectangle.ContainsRect - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rectA - The first rectangle. - * @param {Phaser.Geom.Rectangle} rectB - The second rectangle. - * - * @return {boolean} True only if rectA fully contains rectB. - */ -var ContainsRect = function (rectA, rectB) -{ - // Volume check (if rectB volume > rectA then rectA cannot contain it) - if ((rectB.width * rectB.height) > (rectA.width * rectA.height)) - { - return false; - } - - return ( - (rectB.x > rectA.x && rectB.x < rectA.right) && - (rectB.right > rectA.x && rectB.right < rectA.right) && - (rectB.y > rectA.y && rectB.y < rectA.bottom) && - (rectB.bottom > rectA.y && rectB.bottom < rectA.bottom) - ); -}; - -module.exports = ContainsRect; - - -/***/ }), -/* 482 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); - -// The three medians (the lines drawn from the vertices to the bisectors of the opposite sides) -// meet in the centroid or center of mass (center of gravity). -// The centroid divides each median in a ratio of 2:1 - -/** - * Calculates the position of a Triangle's centroid, which is also its center of mass (center of gravity). - * - * The centroid is the point in a Triangle at which its three medians (the lines drawn from the vertices to the bisectors of the opposite sides) meet. It divides each one in a 2:1 ratio. - * - * @function Phaser.Geom.Triangle.Centroid - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. - * @param {(Phaser.Geom.Point|object)} [out] - An object to store the coordinates in. - * - * @return {(Phaser.Geom.Point|object)} The `out` object with modified `x` and `y` properties, or a new Point if none was provided. - */ -var Centroid = function (triangle, out) -{ - if (out === undefined) { out = new Point(); } - - out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; - out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; - - return out; -}; - -module.exports = Centroid; - - -/***/ }), -/* 483 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Moves each point (vertex) of a Triangle by a given offset, thus moving the entire Triangle by that offset. - * - * @function Phaser.Geom.Triangle.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to move. - * @param {number} x - The horizontal offset (distance) by which to move each point. Can be positive or negative. - * @param {number} y - The vertical offset (distance) by which to move each point. Can be positive or negative. - * - * @return {Phaser.Geom.Triangle} The modified Triangle. - */ -var Offset = function (triangle, x, y) -{ - triangle.x1 += x; - triangle.y1 += y; - - triangle.x2 += x; - triangle.y2 += y; - - triangle.x3 += x; - triangle.y3 += y; - - return triangle; -}; - -module.exports = Offset; - - -/***/ }), -/* 484 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Point = __webpack_require__(4); - -// The three angle bisectors of a triangle meet in one point called the incenter. -// It is the center of the incircle, the circle inscribed in the triangle. - -function getLength (x1, y1, x2, y2) -{ - var x = x1 - x2; - var y = y1 - y2; - var magnitude = (x * x) + (y * y); - - return Math.sqrt(magnitude); -} - -/** - * Calculates the position of the incenter of a Triangle object. This is the point where its three angle bisectors meet and it's also the center of the incircle, which is the circle inscribed in the triangle. - * - * @function Phaser.Geom.Triangle.InCenter - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to find the incenter of. - * @param {Phaser.Geom.Point} [out] - An optional Point in which to store the coordinates. - * - * @return {Phaser.Geom.Point} Point (x, y) of the center pixel of the triangle. - */ -var InCenter = function (triangle, out) -{ - if (out === undefined) { out = new Point(); } - - var x1 = triangle.x1; - var y1 = triangle.y1; - - var x2 = triangle.x2; - var y2 = triangle.y2; - - var x3 = triangle.x3; - var y3 = triangle.y3; - - var d1 = getLength(x3, y3, x2, y2); - var d2 = getLength(x1, y1, x3, y3); - var d3 = getLength(x2, y2, x1, y1); - - var p = d1 + d2 + d3; - - out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p; - out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p; - - return out; -}; - -module.exports = InCenter; - - -/***/ }), -/* 485 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Creates a new Pixel Perfect Handler function. - * - * Access via `InputPlugin.makePixelPerfect` rather than calling it directly. - * - * @function Phaser.Input.CreatePixelPerfectHandler - * @since 3.10.0 - * - * @param {Phaser.Textures.TextureManager} textureManager - A reference to the Texture Manager. - * @param {number} alphaTolerance - The alpha level that the pixel should be above to be included as a successful interaction. - * - * @return {function} The new Pixel Perfect Handler function. - */ -var CreatePixelPerfectHandler = function (textureManager, alphaTolerance) -{ - return function (hitArea, x, y, gameObject) - { - var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); - - return (alpha && alpha >= alphaTolerance); - }; -}; - -module.exports = CreatePixelPerfectHandler; - - -/***/ }), -/* 486 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Creates a new Interactive Object. - * - * This is called automatically by the Input Manager when you enable a Game Object for input. - * - * The resulting Interactive Object is mapped to the Game Object's `input` property. - * - * @function Phaser.Input.CreateInteractiveObject - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to which this Interactive Object is bound. - * @param {any} hitArea - The hit area for this Interactive Object. Typically a geometry shape, like a Rectangle or Circle. - * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - The 'contains' check callback that the hit area shape will use for all hit tests. - * - * @return {Phaser.Types.Input.InteractiveObject} The new Interactive Object. - */ -var CreateInteractiveObject = function (gameObject, hitArea, hitAreaCallback) -{ - return { - - gameObject: gameObject, - - enabled: true, - alwaysEnabled: false, - draggable: false, - dropZone: false, - cursor: false, - - target: null, - - camera: null, - - hitArea: hitArea, - hitAreaCallback: hitAreaCallback, - hitAreaDebug: null, - - // Has the dev specified their own shape, or is this bound to the texture size? - customHitArea: false, - - localX: 0, - localY: 0, - - // 0 = Not being dragged - // 1 = Being checked for dragging - // 2 = Being dragged - dragState: 0, - - dragStartX: 0, - dragStartY: 0, - dragStartXGlobal: 0, - dragStartYGlobal: 0, - - dragX: 0, - dragY: 0 - - }; -}; - -module.exports = CreateInteractiveObject; - - -/***/ }), -/* 487 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * Contains information about a specific Gamepad Axis. - * Axis objects are created automatically by the Gamepad as they are needed. - * - * @class Axis - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Axis belongs to. - * @param {number} index - The index of this Axis. - */ -var Axis = new Class({ - - initialize: - - function Axis (pad, index) - { - /** - * A reference to the Gamepad that this Axis belongs to. - * - * @name Phaser.Input.Gamepad.Axis#pad - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.0.0 - */ - this.pad = pad; - - /** - * An event emitter to use to emit the axis events. - * - * @name Phaser.Input.Gamepad.Axis#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = pad.events; - - /** - * The index of this Axis. - * - * @name Phaser.Input.Gamepad.Axis#index - * @type {number} - * @since 3.0.0 - */ - this.index = index; - - /** - * The raw axis value, between -1 and 1 with 0 being dead center. - * Use the method `getValue` to get a normalized value with the threshold applied. - * - * @name Phaser.Input.Gamepad.Axis#value - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.value = 0; - - /** - * Movement tolerance threshold below which axis values are ignored in `getValue`. - * - * @name Phaser.Input.Gamepad.Axis#threshold - * @type {number} - * @default 0.1 - * @since 3.0.0 - */ - this.threshold = 0.1; - }, - - /** - * Internal update handler for this Axis. - * Called automatically by the Gamepad as part of its update. - * - * @method Phaser.Input.Gamepad.Axis#update - * @private - * @since 3.0.0 - * - * @param {number} value - The value of the axis movement. - */ - update: function (value) - { - this.value = value; - }, - - /** - * Applies the `threshold` value to the axis and returns it. - * - * @method Phaser.Input.Gamepad.Axis#getValue - * @since 3.0.0 - * - * @return {number} The axis value, adjusted for the movement threshold. - */ - getValue: function () - { - return (Math.abs(this.value) < this.threshold) ? 0 : this.value; - }, - - /** - * Destroys this Axis instance and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Axis#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.pad = null; - this.events = null; - } - -}); - -module.exports = Axis; - - -/***/ }), -/* 488 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(234); - -/** - * @classdesc - * Contains information about a specific button on a Gamepad. - * Button objects are created automatically by the Gamepad as they are needed. - * - * @class Button - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Button belongs to. - * @param {number} index - The index of this Button. - */ -var Button = new Class({ - - initialize: - - function Button (pad, index) - { - /** - * A reference to the Gamepad that this Button belongs to. - * - * @name Phaser.Input.Gamepad.Button#pad - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.0.0 - */ - this.pad = pad; - - /** - * An event emitter to use to emit the button events. - * - * @name Phaser.Input.Gamepad.Button#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events = pad.manager; - - /** - * The index of this Button. - * - * @name Phaser.Input.Gamepad.Button#index - * @type {number} - * @since 3.0.0 - */ - this.index = index; - - /** - * Between 0 and 1. - * - * @name Phaser.Input.Gamepad.Button#value - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.value = 0; - - /** - * Can be set for analogue buttons to enable a 'pressure' threshold, - * before a button is considered as being 'pressed'. - * - * @name Phaser.Input.Gamepad.Button#threshold - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.threshold = 1; - - /** - * Is the Button being pressed down or not? - * - * @name Phaser.Input.Gamepad.Button#pressed - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.pressed = false; - }, - - /** - * Internal update handler for this Button. - * Called automatically by the Gamepad as part of its update. - * - * @method Phaser.Input.Gamepad.Button#update - * @fires Phaser.Input.Gamepad.Events#BUTTON_DOWN - * @fires Phaser.Input.Gamepad.Events#BUTTON_UP - * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN - * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP - * @private - * @since 3.0.0 - * - * @param {number} value - The value of the button. Between 0 and 1. - */ - update: function (value) - { - this.value = value; - - var pad = this.pad; - var index = this.index; - - if (value >= this.threshold) - { - if (!this.pressed) - { - this.pressed = true; - this.events.emit(Events.BUTTON_DOWN, pad, this, value); - this.pad.emit(Events.GAMEPAD_BUTTON_DOWN, index, value, this); - } - } - else if (this.pressed) - { - this.pressed = false; - this.events.emit(Events.BUTTON_UP, pad, this, value); - this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this); - } - }, - - /** - * Destroys this Button instance and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Button#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.pad = null; - this.events = null; - } - -}); - -module.exports = Button; - - -/***/ }), -/* 489 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Axis = __webpack_require__(487); -var Button = __webpack_require__(488); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A single Gamepad. - * - * These are created, updated and managed by the Gamepad Plugin. - * - * @class Gamepad - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Gamepad - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad.GamepadPlugin} manager - A reference to the Gamepad Plugin. - * @param {Phaser.Types.Input.Gamepad.Pad} pad - The Gamepad object, as extracted from GamepadEvent. - */ -var Gamepad = new Class({ - - Extends: EventEmitter, - - initialize: - - function Gamepad (manager, pad) - { - EventEmitter.call(this); - - /** - * A reference to the Gamepad Plugin. - * - * @name Phaser.Input.Gamepad.Gamepad#manager - * @type {Phaser.Input.Gamepad.GamepadPlugin} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * A reference to the native Gamepad object that is connected to the browser. - * - * @name Phaser.Input.Gamepad.Gamepad#pad - * @type {any} - * @since 3.10.0 - */ - this.pad = pad; - - /** - * A string containing some information about the controller. - * - * This is not strictly specified, but in Firefox it will contain three pieces of information - * separated by dashes (-): two 4-digit hexadecimal strings containing the USB vendor and - * product id of the controller, and the name of the controller as provided by the driver. - * In Chrome it will contain the name of the controller as provided by the driver, - * followed by vendor and product 4-digit hexadecimal strings. - * - * @name Phaser.Input.Gamepad.Gamepad#id - * @type {string} - * @since 3.0.0 - */ - this.id = pad.id; - - /** - * An integer that is unique for each Gamepad currently connected to the system. - * This can be used to distinguish multiple controllers. - * Note that disconnecting a device and then connecting a new device may reuse the previous index. - * - * @name Phaser.Input.Gamepad.Gamepad#index - * @type {number} - * @since 3.0.0 - */ - this.index = pad.index; - - var buttons = []; - - for (var i = 0; i < pad.buttons.length; i++) - { - buttons.push(new Button(this, i)); - } - - /** - * An array of Gamepad Button objects, corresponding to the different buttons available on the Gamepad. - * - * @name Phaser.Input.Gamepad.Gamepad#buttons - * @type {Phaser.Input.Gamepad.Button[]} - * @since 3.0.0 - */ - this.buttons = buttons; - - var axes = []; - - for (i = 0; i < pad.axes.length; i++) - { - axes.push(new Axis(this, i)); - } - - /** - * An array of Gamepad Axis objects, corresponding to the different axes available on the Gamepad, if any. - * - * @name Phaser.Input.Gamepad.Gamepad#axes - * @type {Phaser.Input.Gamepad.Axis[]} - * @since 3.0.0 - */ - this.axes = axes; - - /** - * The Gamepad's Haptic Actuator (Vibration / Rumble support). - * This is highly experimental and only set if both present on the device, - * and exposed by both the hardware and browser. - * - * @name Phaser.Input.Gamepad.Gamepad#vibration - * @type {GamepadHapticActuator} - * @since 3.10.0 - */ - this.vibration = pad.vibrationActuator; - - // https://w3c.github.io/gamepad/#remapping - - var _noButton = { value: 0, pressed: false }; - - /** - * A reference to the Left Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCLeft = (buttons[14]) ? buttons[14] : _noButton; - - /** - * A reference to the Right Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCRight = (buttons[15]) ? buttons[15] : _noButton; - - /** - * A reference to the Top Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCTop = (buttons[12]) ? buttons[12] : _noButton; - - /** - * A reference to the Bottom Button in the Left Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_LCBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._LCBottom = (buttons[13]) ? buttons[13] : _noButton; - - /** - * A reference to the Left Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCLeft = (buttons[2]) ? buttons[2] : _noButton; - - /** - * A reference to the Right Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCRight = (buttons[1]) ? buttons[1] : _noButton; - - /** - * A reference to the Top Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCTop = (buttons[3]) ? buttons[3] : _noButton; - - /** - * A reference to the Bottom Button in the Right Cluster. - * - * @name Phaser.Input.Gamepad.Gamepad#_RCBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._RCBottom = (buttons[0]) ? buttons[0] : _noButton; - - /** - * A reference to the Top Left Front Button (L1 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBLeftTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBLeftTop = (buttons[4]) ? buttons[4] : _noButton; - - /** - * A reference to the Bottom Left Front Button (L2 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBLeftBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBLeftBottom = (buttons[6]) ? buttons[6] : _noButton; - - /** - * A reference to the Top Right Front Button (R1 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBRightTop - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBRightTop = (buttons[5]) ? buttons[5] : _noButton; - - /** - * A reference to the Bottom Right Front Button (R2 Shoulder Button) - * - * @name Phaser.Input.Gamepad.Gamepad#_FBRightBottom - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._FBRightBottom = (buttons[7]) ? buttons[7] : _noButton; - - var _noAxis = { value: 0 }; - - /** - * A reference to the Horizontal Axis for the Left Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_HAxisLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._HAxisLeft = (axes[0]) ? axes[0] : _noAxis; - - /** - * A reference to the Vertical Axis for the Left Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_VAxisLeft - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._VAxisLeft = (axes[1]) ? axes[1] : _noAxis; - - /** - * A reference to the Horizontal Axis for the Right Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_HAxisRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._HAxisRight = (axes[2]) ? axes[2] : _noAxis; - - /** - * A reference to the Vertical Axis for the Right Stick. - * - * @name Phaser.Input.Gamepad.Gamepad#_VAxisRight - * @type {Phaser.Input.Gamepad.Button} - * @private - * @since 3.10.0 - */ - this._VAxisRight = (axes[3]) ? axes[3] : _noAxis; - - /** - * A Vector2 containing the most recent values from the Gamepad's left axis stick. - * This is updated automatically as part of the Gamepad.update cycle. - * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. - * The values are based on the Axis thresholds. - * If the Gamepad does not have a left axis stick, the values will always be zero. - * - * @name Phaser.Input.Gamepad.Gamepad#leftStick - * @type {Phaser.Math.Vector2} - * @since 3.10.0 - */ - this.leftStick = new Vector2(); - - /** - * A Vector2 containing the most recent values from the Gamepad's right axis stick. - * This is updated automatically as part of the Gamepad.update cycle. - * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. - * The values are based on the Axis thresholds. - * If the Gamepad does not have a right axis stick, the values will always be zero. - * - * @name Phaser.Input.Gamepad.Gamepad#rightStick - * @type {Phaser.Math.Vector2} - * @since 3.10.0 - */ - this.rightStick = new Vector2(); - - /** - * When was this Gamepad created? Used to avoid duplicate event spamming in the update loop. - * - * @name Phaser.Input.Gamepad.Gamepad#_created - * @type {number} - * @private - * @since 3.50.0 - */ - this._created = performance.now(); - }, - - /** - * Gets the total number of axis this Gamepad claims to support. - * - * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal - * @since 3.10.0 - * - * @return {number} The total number of axes this Gamepad claims to support. - */ - getAxisTotal: function () - { - return this.axes.length; - }, - - /** - * Gets the value of an axis based on the given index. - * The index must be valid within the range of axes supported by this Gamepad. - * The return value will be a float between 0 and 1. - * - * @method Phaser.Input.Gamepad.Gamepad#getAxisValue - * @since 3.10.0 - * - * @param {number} index - The index of the axes to get the value for. - * - * @return {number} The value of the axis, between 0 and 1. - */ - getAxisValue: function (index) - { - return this.axes[index].getValue(); - }, - - /** - * Sets the threshold value of all axis on this Gamepad. - * The value is a float between 0 and 1 and is the amount below which the axis is considered as not having been moved. - * - * @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold - * @since 3.10.0 - * - * @param {number} value - A value between 0 and 1. - */ - setAxisThreshold: function (value) - { - for (var i = 0; i < this.axes.length; i++) - { - this.axes[i].threshold = value; - } - }, - - /** - * Gets the total number of buttons this Gamepad claims to have. - * - * @method Phaser.Input.Gamepad.Gamepad#getButtonTotal - * @since 3.10.0 - * - * @return {number} The total number of buttons this Gamepad claims to have. - */ - getButtonTotal: function () - { - return this.buttons.length; - }, - - /** - * Gets the value of a button based on the given index. - * The index must be valid within the range of buttons supported by this Gamepad. - * - * The return value will be either 0 or 1 for an analogue button, or a float between 0 and 1 - * for a pressure-sensitive digital button, such as the shoulder buttons on a Dual Shock. - * - * @method Phaser.Input.Gamepad.Gamepad#getButtonValue - * @since 3.10.0 - * - * @param {number} index - The index of the button to get the value for. - * - * @return {number} The value of the button, between 0 and 1. - */ - getButtonValue: function (index) - { - return this.buttons[index].value; - }, - - /** - * Returns if the button is pressed down or not. - * The index must be valid within the range of buttons supported by this Gamepad. - * - * @method Phaser.Input.Gamepad.Gamepad#isButtonDown - * @since 3.10.0 - * - * @param {number} index - The index of the button to get the value for. - * - * @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`. - */ - isButtonDown: function (index) - { - return this.buttons[index].pressed; - }, - - /** - * Internal update handler for this Gamepad. - * Called automatically by the Gamepad Manager as part of its update. - * - * @method Phaser.Input.Gamepad.Gamepad#update - * @private - * @since 3.0.0 - */ - update: function (pad) - { - if (pad.timestamp < this._created) - { - return; - } - - var i; - - // Sync the button values - - var localButtons = this.buttons; - var gamepadButtons = pad.buttons; - - var len = localButtons.length; - - for (i = 0; i < len; i++) - { - localButtons[i].update(gamepadButtons[i].value); - } - - // Sync the axis values - - var localAxes = this.axes; - var gamepadAxes = pad.axes; - - len = localAxes.length; - - for (i = 0; i < len; i++) - { - localAxes[i].update(gamepadAxes[i]); - } - - if (len >= 2) - { - this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue()); - - if (len >= 4) - { - this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue()); - } - } - }, - - /** - * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. - * - * @method Phaser.Input.Gamepad.Gamepad#destroy - * @since 3.10.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.manager = null; - this.pad = null; - - var i; - - for (i = 0; i < this.buttons.length; i++) - { - this.buttons[i].destroy(); - } - - for (i = 0; i < this.axes.length; i++) - { - this.axes[i].destroy(); - } - - this.buttons = []; - this.axes = []; - }, - - /** - * Is this Gamepad currently connected or not? - * - * @name Phaser.Input.Gamepad.Gamepad#connected - * @type {boolean} - * @default true - * @since 3.0.0 - */ - connected: { - - get: function () - { - return this.pad.connected; - } - - }, - - /** - * A timestamp containing the most recent time this Gamepad was updated. - * - * @name Phaser.Input.Gamepad.Gamepad#timestamp - * @type {number} - * @since 3.0.0 - */ - timestamp: { - - get: function () - { - return this.pad.timestamp; - } - - }, - - /** - * Is the Gamepad's Left button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad left button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#left - * @type {boolean} - * @since 3.10.0 - */ - left: { - - get: function () - { - return this._LCLeft.pressed; - } - - }, - - /** - * Is the Gamepad's Right button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad right button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#right - * @type {boolean} - * @since 3.10.0 - */ - right: { - - get: function () - { - return this._LCRight.pressed; - } - - }, - - /** - * Is the Gamepad's Up button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad up button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#up - * @type {boolean} - * @since 3.10.0 - */ - up: { - - get: function () - { - return this._LCTop.pressed; - } - - }, - - /** - * Is the Gamepad's Down button being pressed? - * If the Gamepad doesn't have this button it will always return false. - * This is the d-pad down button under standard Gamepad mapping. - * - * @name Phaser.Input.Gamepad.Gamepad#down - * @type {boolean} - * @since 3.10.0 - */ - down: { - - get: function () - { - return this._LCBottom.pressed; - } - - }, - - /** - * Is the Gamepad's bottom button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the X button. - * On an XBox controller it's the A button. - * - * @name Phaser.Input.Gamepad.Gamepad#A - * @type {boolean} - * @since 3.10.0 - */ - A: { - - get: function () - { - return this._RCBottom.pressed; - } - - }, - - /** - * Is the Gamepad's top button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Triangle button. - * On an XBox controller it's the Y button. - * - * @name Phaser.Input.Gamepad.Gamepad#Y - * @type {boolean} - * @since 3.10.0 - */ - Y: { - - get: function () - { - return this._RCTop.pressed; - } - - }, - - /** - * Is the Gamepad's left button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Square button. - * On an XBox controller it's the X button. - * - * @name Phaser.Input.Gamepad.Gamepad#X - * @type {boolean} - * @since 3.10.0 - */ - X: { - - get: function () - { - return this._RCLeft.pressed; - } - - }, - - /** - * Is the Gamepad's right button in the right button cluster being pressed? - * If the Gamepad doesn't have this button it will always return false. - * On a Dual Shock controller it's the Circle button. - * On an XBox controller it's the B button. - * - * @name Phaser.Input.Gamepad.Gamepad#B - * @type {boolean} - * @since 3.10.0 - */ - B: { - - get: function () - { - return this._RCRight.pressed; - } - - }, - - /** - * Returns the value of the Gamepad's top left shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the L1 button. - * On an XBox controller it's the LB button. - * - * @name Phaser.Input.Gamepad.Gamepad#L1 - * @type {number} - * @since 3.10.0 - */ - L1: { - - get: function () - { - return this._FBLeftTop.value; - } - - }, - - /** - * Returns the value of the Gamepad's bottom left shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the L2 button. - * On an XBox controller it's the LT button. - * - * @name Phaser.Input.Gamepad.Gamepad#L2 - * @type {number} - * @since 3.10.0 - */ - L2: { - - get: function () - { - return this._FBLeftBottom.value; - } - - }, - - /** - * Returns the value of the Gamepad's top right shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the R1 button. - * On an XBox controller it's the RB button. - * - * @name Phaser.Input.Gamepad.Gamepad#R1 - * @type {number} - * @since 3.10.0 - */ - R1: { - - get: function () - { - return this._FBRightTop.value; - } - - }, - - /** - * Returns the value of the Gamepad's bottom right shoulder button. - * If the Gamepad doesn't have this button it will always return zero. - * The value is a float between 0 and 1, corresponding to how depressed the button is. - * On a Dual Shock controller it's the R2 button. - * On an XBox controller it's the RT button. - * - * @name Phaser.Input.Gamepad.Gamepad#R2 - * @type {number} - * @since 3.10.0 - */ - R2: { - - get: function () - { - return this._FBRightBottom.value; - } - - } - -}); - -module.exports = Gamepad; - - -/***/ }), -/* 490 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(151); - -/** - * @classdesc - * A generic Key object which can be passed to the Process functions (and so on) - * keycode must be an integer - * - * @class Key - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyboardPlugin} plugin - The Keyboard Plugin instance that owns this Key object. - * @param {number} keyCode - The keycode of this key. - */ -var Key = new Class({ - - Extends: EventEmitter, - - initialize: - - function Key (plugin, keyCode) - { - EventEmitter.call(this); - - /** - * The Keyboard Plugin instance that owns this Key object. - * - * @name Phaser.Input.Keyboard.Key#plugin - * @type {Phaser.Input.Keyboard.KeyboardPlugin} - * @since 3.17.0 - */ - this.plugin = plugin; - - /** - * The keycode of this key. - * - * @name Phaser.Input.Keyboard.Key#keyCode - * @type {number} - * @since 3.0.0 - */ - this.keyCode = keyCode; - - /** - * The original DOM event. - * - * @name Phaser.Input.Keyboard.Key#originalEvent - * @type {KeyboardEvent} - * @since 3.0.0 - */ - this.originalEvent = undefined; - - /** - * Can this Key be processed? - * - * @name Phaser.Input.Keyboard.Key#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down. - * - * @name Phaser.Input.Keyboard.Key#isDown - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isDown = false; - - /** - * The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up. - * - * @name Phaser.Input.Keyboard.Key#isUp - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.isUp = true; - - /** - * The down state of the ALT key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#altKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.altKey = false; - - /** - * The down state of the CTRL key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#ctrlKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.ctrlKey = false; - - /** - * The down state of the SHIFT key, if pressed at the same time as this key. - * - * @name Phaser.Input.Keyboard.Key#shiftKey - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.shiftKey = false; - - /** - * The down state of the Meta key, if pressed at the same time as this key. - * On a Mac the Meta Key is the Command key. On Windows keyboards, it's the Windows key. - * - * @name Phaser.Input.Keyboard.Key#metaKey - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.metaKey = false; - - /** - * The location of the modifier key. 0 for standard (or unknown), 1 for left, 2 for right, 3 for numpad. - * - * @name Phaser.Input.Keyboard.Key#location - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.location = 0; - - /** - * The timestamp when the key was last pressed down. - * - * @name Phaser.Input.Keyboard.Key#timeDown - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeDown = 0; - - /** - * The number of milliseconds this key was held down for in the previous down - up sequence. - * This value isn't updated every game step, only when the Key changes state. - * To get the current duration use the `getDuration` method. - * - * @name Phaser.Input.Keyboard.Key#duration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.duration = 0; - - /** - * The timestamp when the key was last released. - * - * @name Phaser.Input.Keyboard.Key#timeUp - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeUp = 0; - - /** - * When a key is held down should it continuously fire the `down` event each time it repeats? - * - * By default it will emit the `down` event just once, but if you wish to receive the event - * for each repeat as well, enable this property. - * - * @name Phaser.Input.Keyboard.Key#emitOnRepeat - * @type {boolean} - * @default false - * @since 3.16.0 - */ - this.emitOnRepeat = false; - - /** - * If a key is held down this holds down the number of times the key has 'repeated'. - * - * @name Phaser.Input.Keyboard.Key#repeats - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeats = 0; - - /** - * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) - * - * @name Phaser.Input.Keyboard.Key#_justDown - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._justDown = false; - - /** - * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) - * - * @name Phaser.Input.Keyboard.Key#_justUp - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._justUp = false; - - /** - * Internal tick counter. - * - * @name Phaser.Input.Keyboard.Key#_tick - * @type {number} - * @private - * @since 3.11.0 - */ - this._tick = -1; - }, - - /** - * Controls if this Key will continuously emit a `down` event while being held down (true), - * or emit the event just once, on first press, and then skip future events (false). - * - * @method Phaser.Input.Keyboard.Key#setEmitOnRepeat - * @since 3.16.0 - * - * @param {boolean} value - Emit `down` events on repeated key down actions, or just once? - * - * @return {this} This Key instance. - */ - setEmitOnRepeat: function (value) - { - this.emitOnRepeat = value; - - return this; - }, - - /** - * Processes the Key Down action for this Key. - * Called automatically by the Keyboard Plugin. - * - * @method Phaser.Input.Keyboard.Key#onDown - * @fires Phaser.Input.Keyboard.Events#DOWN - * @since 3.16.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard event. - */ - onDown: function (event) - { - this.originalEvent = event; - - if (!this.enabled) - { - return; - } - - this.altKey = event.altKey; - this.ctrlKey = event.ctrlKey; - this.shiftKey = event.shiftKey; - this.metaKey = event.metaKey; - this.location = event.location; - - this.repeats++; - - if (!this.isDown) - { - this.isDown = true; - this.isUp = false; - this.timeDown = event.timeStamp; - this.duration = 0; - this._justDown = true; - this._justUp = false; - - this.emit(Events.DOWN, this, event); - } - else if (this.emitOnRepeat) - { - this.emit(Events.DOWN, this, event); - } - }, - - /** - * Processes the Key Up action for this Key. - * Called automatically by the Keyboard Plugin. - * - * @method Phaser.Input.Keyboard.Key#onUp - * @fires Phaser.Input.Keyboard.Events#UP - * @since 3.16.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard event. - */ - onUp: function (event) - { - this.originalEvent = event; - - if (!this.enabled) - { - return; - } - - this.isDown = false; - this.isUp = true; - this.timeUp = event.timeStamp; - this.duration = this.timeUp - this.timeDown; - this.repeats = 0; - - this._justDown = false; - this._justUp = true; - this._tick = -1; - - this.emit(Events.UP, this, event); - }, - - /** - * Resets this Key object back to its default un-pressed state. - * - * @method Phaser.Input.Keyboard.Key#reset - * @since 3.6.0 - * - * @return {this} This Key instance. - */ - reset: function () - { - this.preventDefault = true; - this.enabled = true; - this.isDown = false; - this.isUp = true; - this.altKey = false; - this.ctrlKey = false; - this.shiftKey = false; - this.metaKey = false; - this.timeDown = 0; - this.duration = 0; - this.timeUp = 0; - this.repeats = 0; - this._justDown = false; - this._justUp = false; - this._tick = -1; - - return this; - }, - - /** - * Returns the duration, in ms, that the Key has been held down for. - * - * If the key is not currently down it will return zero. - * - * The get the duration the Key was held down for in the previous up-down cycle, - * use the `Key.duration` property value instead. - * - * @method Phaser.Input.Keyboard.Key#getDuration - * @since 3.17.0 - * - * @return {number} The duration, in ms, that the Key has been held down for if currently down. - */ - getDuration: function () - { - if (this.isDown) - { - return (this.plugin.game.loop.time - this.timeDown); - } - else - { - return 0; - } - }, - - /** - * Removes any bound event handlers and removes local references. - * - * @method Phaser.Input.Keyboard.Key#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.removeAllListeners(); - - this.originalEvent = null; - - this.plugin = null; - } - -}); - -module.exports = Key; - - -/***/ }), -/* 491 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(151); -var GetFastValue = __webpack_require__(2); -var ProcessKeyCombo = __webpack_require__(492); -var ResetKeyCombo = __webpack_require__(494); - -/** - * @classdesc - * A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them - * it will emit a `keycombomatch` event from the Keyboard Manager. - * - * The keys to be listened for can be defined as: - * - * A string (i.e. 'ATARI') - * An array of either integers (key codes) or strings, or a mixture of both - * An array of objects (such as Key objects) with a public 'keyCode' property - * - * For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter) - * you could pass the following array of key codes: - * - * ```javascript - * this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true }); - * - * this.input.keyboard.on('keycombomatch', function (event) { - * console.log('Konami Code entered!'); - * }); - * ``` - * - * Or, to listen for the user entering the word PHASER: - * - * ```javascript - * this.input.keyboard.createCombo('PHASER'); - * ``` - * - * @class KeyCombo - * @memberof Phaser.Input.Keyboard - * @constructor - * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyboardPlugin} keyboardPlugin - A reference to the Keyboard Plugin. - * @param {(string|number[]|object[])} keys - The keys that comprise this combo. - * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. - */ -var KeyCombo = new Class({ - - initialize: - - function KeyCombo (keyboardPlugin, keys, config) - { - if (config === undefined) { config = {}; } - - // Can't have a zero or single length combo (string or array based) - if (keys.length < 2) - { - return false; - } - - /** - * A reference to the Keyboard Manager - * - * @name Phaser.Input.Keyboard.KeyCombo#manager - * @type {Phaser.Input.Keyboard.KeyboardPlugin} - * @since 3.0.0 - */ - this.manager = keyboardPlugin; - - /** - * A flag that controls if this Key Combo is actively processing keys or not. - * - * @name Phaser.Input.Keyboard.KeyCombo#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = true; - - /** - * An array of the keycodes that comprise this combo. - * - * @name Phaser.Input.Keyboard.KeyCombo#keyCodes - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.keyCodes = []; - - // if 'keys' is a string we need to get the keycode of each character in it - - for (var i = 0; i < keys.length; i++) - { - var char = keys[i]; - - if (typeof char === 'string') - { - this.keyCodes.push(char.toUpperCase().charCodeAt(0)); - } - else if (typeof char === 'number') - { - this.keyCodes.push(char); - } - else if (char.hasOwnProperty('keyCode')) - { - this.keyCodes.push(char.keyCode); - } - } - - /** - * The current keyCode the combo is waiting for. - * - * @name Phaser.Input.Keyboard.KeyCombo#current - * @type {number} - * @since 3.0.0 - */ - this.current = this.keyCodes[0]; - - /** - * The current index of the key being waited for in the 'keys' string. - * - * @name Phaser.Input.Keyboard.KeyCombo#index - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.index = 0; - - /** - * The length of this combo (in keycodes) - * - * @name Phaser.Input.Keyboard.KeyCombo#size - * @type {number} - * @since 3.0.0 - */ - this.size = this.keyCodes.length; - - /** - * The time the previous key in the combo was matched. - * - * @name Phaser.Input.Keyboard.KeyCombo#timeLastMatched - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeLastMatched = 0; - - /** - * Has this Key Combo been matched yet? - * - * @name Phaser.Input.Keyboard.KeyCombo#matched - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.matched = false; - - /** - * The time the entire combo was matched. - * - * @name Phaser.Input.Keyboard.KeyCombo#timeMatched - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.timeMatched = 0; - - /** - * If they press the wrong key do we reset the combo? - * - * @name Phaser.Input.Keyboard.KeyCombo#resetOnWrongKey - * @type {boolean} - * @default 0 - * @since 3.0.0 - */ - this.resetOnWrongKey = GetFastValue(config, 'resetOnWrongKey', true); - - /** - * The max delay in ms between each key press. Above this the combo is reset. 0 means disabled. - * - * @name Phaser.Input.Keyboard.KeyCombo#maxKeyDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxKeyDelay = GetFastValue(config, 'maxKeyDelay', 0); - - /** - * If previously matched and they press the first key of the combo again, will it reset? - * - * @name Phaser.Input.Keyboard.KeyCombo#resetOnMatch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.resetOnMatch = GetFastValue(config, 'resetOnMatch', false); - - /** - * If the combo matches, will it delete itself? - * - * @name Phaser.Input.Keyboard.KeyCombo#deleteOnMatch - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.deleteOnMatch = GetFastValue(config, 'deleteOnMatch', false); - - var _this = this; - - var onKeyDownHandler = function (event) - { - if (_this.matched || !_this.enabled) - { - return; - } - - var matched = ProcessKeyCombo(event, _this); - - if (matched) - { - _this.manager.emit(Events.COMBO_MATCH, _this, event); - - if (_this.resetOnMatch) - { - ResetKeyCombo(_this); - } - else if (_this.deleteOnMatch) - { - _this.destroy(); - } - } - }; - - /** - * The internal Key Down handler. - * - * @name Phaser.Input.Keyboard.KeyCombo#onKeyDown - * @private - * @type {KeyboardKeydownCallback} - * @fires Phaser.Input.Keyboard.Events#COMBO_MATCH - * @since 3.0.0 - */ - this.onKeyDown = onKeyDownHandler; - - this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown); - }, - - /** - * How far complete is this combo? A value between 0 and 1. - * - * @name Phaser.Input.Keyboard.KeyCombo#progress - * @type {number} - * @readonly - * @since 3.0.0 - */ - progress: { - - get: function () - { - return this.index / this.size; - } - - }, - - /** - * Destroys this Key Combo and all of its references. - * - * @method Phaser.Input.Keyboard.KeyCombo#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enabled = false; - this.keyCodes = []; - - this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown); - - this.manager = null; - } - -}); - -module.exports = KeyCombo; - - -/***/ }), -/* 492 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AdvanceKeyCombo = __webpack_require__(493); - -/** - * Used internally by the KeyCombo class. - * - * @function Phaser.Input.Keyboard.ProcessKeyCombo - * @private - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native Keyboard Event. - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to be processed. - * - * @return {boolean} `true` if the combo was matched, otherwise `false`. - */ -var ProcessKeyCombo = function (event, combo) -{ - if (combo.matched) - { - return true; - } - - var comboMatched = false; - var keyMatched = false; - - if (event.keyCode === combo.current) - { - // Key was correct - - if (combo.index > 0 && combo.maxKeyDelay > 0) - { - // We have to check to see if the delay between - // the new key and the old one was too long (if enabled) - - var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; - - // Check if they pressed it in time or not - if (event.timeStamp <= timeLimit) - { - keyMatched = true; - comboMatched = AdvanceKeyCombo(event, combo); - } - } - else - { - keyMatched = true; - - // We don't check the time for the first key pressed, so just advance it - comboMatched = AdvanceKeyCombo(event, combo); - } - } - - if (!keyMatched && combo.resetOnWrongKey) - { - // Wrong key was pressed - combo.index = 0; - combo.current = combo.keyCodes[0]; - } - - if (comboMatched) - { - combo.timeLastMatched = event.timeStamp; - combo.matched = true; - combo.timeMatched = event.timeStamp; - } - - return comboMatched; -}; - -module.exports = ProcessKeyCombo; - - -/***/ }), -/* 493 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Used internally by the KeyCombo class. - * Return `true` if it reached the end of the combo, `false` if not. - * - * @function Phaser.Input.Keyboard.AdvanceKeyCombo - * @private - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native Keyboard Event. - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. - * - * @return {boolean} `true` if it reached the end of the combo, `false` if not. - */ -var AdvanceKeyCombo = function (event, combo) -{ - combo.timeLastMatched = event.timeStamp; - combo.index++; - - if (combo.index === combo.size) - { - return true; - } - else - { - combo.current = combo.keyCodes[combo.index]; - return false; - } -}; - -module.exports = AdvanceKeyCombo; - - -/***/ }), -/* 494 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Used internally by the KeyCombo class. - * - * @function Phaser.Input.Keyboard.ResetKeyCombo - * @private - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo to reset. - * - * @return {Phaser.Input.Keyboard.KeyCombo} The KeyCombo. - */ -var ResetKeyCombo = function (combo) -{ - combo.current = combo.keyCodes[0]; - combo.index = 0; - combo.timeLastMatched = 0; - combo.matched = false; - combo.timeMatched = 0; - - return combo; -}; - -module.exports = ResetKeyCombo; - - -/***/ }), -/* 495 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var MergeXHRSettings = __webpack_require__(235); - -/** - * 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; - - -/***/ }), -/* 496 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var HTML5AudioFile = __webpack_require__(497); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Audio File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. - * - * @class AudioFile - * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {any} [urlConfig] - The absolute or relative URL to load this file from in a config object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - * @param {AudioContext} [audioContext] - The AudioContext this file will use to process itself. - */ -var AudioFile = new Class({ - - Extends: File, - - initialize: - - // URL is an object created by AudioFile.findAudioURL - function AudioFile (loader, key, urlConfig, xhrSettings, audioContext) - { - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - audioContext = GetFastValue(config, 'context', audioContext); - } - - var fileConfig = { - type: 'audio', - cache: loader.cacheManager.audio, - extension: urlConfig.type, - responseType: 'arraybuffer', - key: key, - url: urlConfig.url, - xhrSettings: xhrSettings, - config: { context: audioContext } - }; - - 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.AudioFile#onProcess - * @since 3.0.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; - - var _this = this; - - // interesting read https://github.com/WebAudio/web-audio-api/issues/1305 - this.config.context.decodeAudioData(this.xhrLoader.response, - function (audioBuffer) - { - _this.data = audioBuffer; - - _this.onProcessComplete(); - }, - function (e) - { - // eslint-disable-next-line no-console - console.error('Error decoding audio: ' + _this.key + ' - ', e ? e.message : null); - - _this.onProcessError(); - } - ); - - this.config.context = null; - } - -}); - -AudioFile.create = function (loader, key, urls, config, xhrSettings) -{ - var game = loader.systems.game; - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - // url may be inside key, which may be an object - if (IsPlainObject(key)) - { - urls = GetFastValue(key, 'url', []); - config = GetFastValue(key, 'config', {}); - } - - var urlConfig = AudioFile.getAudioURL(game, urls); - - if (!urlConfig) - { - return null; - } - - // https://developers.google.com/web/updates/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs - // var stream = GetFastValue(config, 'stream', false); - - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) - { - return new AudioFile(loader, key, urlConfig, xhrSettings, game.sound.context); - } - else - { - return new HTML5AudioFile(loader, key, urlConfig, config); - } -}; - -AudioFile.getAudioURL = function (game, urls) -{ - if (!Array.isArray(urls)) - { - urls = [ urls ]; - } - - for (var i = 0; i < urls.length; i++) - { - var url = GetFastValue(urls[i], 'url', urls[i]); - - if (url.indexOf('blob:') === 0 || url.indexOf('data:') === 0) - { - return { - url: url, - type: '' - }; - } - - var audioType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); - - audioType = GetFastValue(urls[i], 'type', (audioType) ? audioType[1] : '').toLowerCase(); - - if (game.device.audio[audioType]) - { - return { - url: url, - type: audioType - }; - } - } - - return null; -}; - -/** - * Adds an Audio or HTML5Audio file, or array of audio 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.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); - * } - * ``` - * - * 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 Audio Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Audio 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 Audio Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.audio({ - * key: 'title', - * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ] - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AudioFileConfig` for more details. - * - * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. - * - * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats. - * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on - * browser support. - * - * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded. - * - * Note: The ability to load this type of file will only be available if the Audio 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#audio - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.AudioFileConfig|Phaser.Types.Loader.FileTypes.AudioFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {(string|string[])} [urls] - The absolute or relative URL to load the audio files from. - * @param {any} [config] - An object containing an `instances` property for HTML5Audio. Defaults to 1. - * @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('audio', function (key, urls, config, xhrSettings) -{ - var game = this.systems.game; - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; - - if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - // Sounds are disabled, so skip loading audio - return this; - } - - var audioFile; - - 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 - audioFile = AudioFile.create(this, key[i]); - - if (audioFile) - { - this.addFile(audioFile); - } - } - } - else - { - audioFile = AudioFile.create(this, key, urls, config, xhrSettings); - - if (audioFile) - { - this.addFile(audioFile); - } - } - - return this; -}); - -module.exports = AudioFile; - - -/***/ }), -/* 497 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Events = __webpack_require__(90); -var File = __webpack_require__(23); -var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(152); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Audio File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. - * - * @class HTML5AudioFile - * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string} [urlConfig] - The absolute or relative URL to load this file from. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var HTML5AudioFile = new Class({ - - Extends: File, - - initialize: - - function HTML5AudioFile (loader, key, urlConfig, audioConfig) - { - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - audioConfig = GetFastValue(config, 'config', audioConfig); - } - - var fileConfig = { - type: 'audio', - cache: loader.cacheManager.audio, - extension: urlConfig.type, - key: key, - url: urlConfig.url, - config: audioConfig - }; - - File.call(this, loader, fileConfig); - - // New properties specific to this class - this.locked = 'ontouchstart' in window; - this.loaded = false; - this.filesLoaded = 0; - this.filesTotal = 0; - }, - - /** - * Called when the file finishes loading. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad - * @since 3.0.0 - */ - onLoad: function () - { - if (this.loaded) - { - return; - } - - this.loaded = true; - - this.loader.nextFile(this, true); - }, - - /** - * Called if the file errors while loading. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onError - * @since 3.0.0 - */ - onError: function () - { - for (var i = 0; i < this.data.length; i++) - { - var audio = this.data[i]; - - audio.oncanplaythrough = null; - audio.onerror = null; - } - - this.loader.nextFile(this, false); - }, - - /** - * Called during the file load progress. Is sent a DOM ProgressEvent. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress - * @fires Phaser.Loader.Events#FILE_PROGRESS - * @since 3.0.0 - */ - onProgress: function (event) - { - var audio = event.target; - - audio.oncanplaythrough = null; - audio.onerror = null; - - this.filesLoaded++; - - this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1); - - this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); - - if (this.filesLoaded === this.filesTotal) - { - this.onLoad(); - } - }, - - /** - * 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.FileTypes.HTML5AudioFile#load - * @since 3.0.0 - */ - load: function () - { - this.data = []; - - var instances = (this.config && this.config.instances) || 1; - - this.filesTotal = instances; - this.filesLoaded = 0; - this.percentComplete = 0; - - for (var i = 0; i < instances; i++) - { - var audio = new Audio(); - - if (!audio.dataset) - { - audio.dataset = {}; - } - - audio.dataset.name = this.key + ('0' + i).slice(-2); - audio.dataset.used = 'false'; - - if (this.locked) - { - audio.dataset.locked = 'true'; - } - else - { - audio.dataset.locked = 'false'; - - audio.preload = 'auto'; - audio.oncanplaythrough = this.onProgress.bind(this); - audio.onerror = this.onError.bind(this); - } - - this.data.push(audio); - } - - for (i = 0; i < this.data.length; i++) - { - audio = this.data[i]; - audio.src = GetURL(this, this.loader.baseURL); - - if (!this.locked) - { - audio.load(); - } - } - - if (this.locked) - { - // This is super-dangerous but works. Race condition potential high. - // Is there another way? - setTimeout(this.onLoad.bind(this)); - } - } - -}); - -module.exports = HTML5AudioFile; - - -/***/ }), -/* 498 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(20); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Script File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#script method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#script. - * - * @class ScriptFile - * @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.ScriptFileConfig)} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var ScriptFile = new Class({ - - Extends: File, - - initialize: - - function ScriptFile (loader, key, url, xhrSettings) - { - var extension = 'js'; - - 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: 'script', - cache: false, - 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.ScriptFile#onProcess - * @since 3.7.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; - - this.data = document.createElement('script'); - this.data.language = 'javascript'; - this.data.type = 'text/javascript'; - this.data.defer = false; - this.data.text = this.xhrLoader.responseText; - - document.head.appendChild(this.data); - - this.onProcessComplete(); - } - -}); - -/** - * Adds a Script file, or array of Script 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.script('aliens', 'lib/aliens.js'); - * } - * ``` - * - * 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 and not already in-use by another file in the Loader. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.script({ - * key: 'aliens', - * url: 'lib/aliens.js' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.ScriptFileConfig` for more details. - * - * Once the file has finished loading it will automatically be converted into a script element - * via `document.createElement('script')`. It will have its language set to JavaScript, `defer` set to - * false and then the resulting element will be appended to `document.head`. Any code then in the - * script will be executed. - * - * 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.js". It will always add `.js` 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 Script 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#script - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.ScriptFileConfig|Phaser.Types.Loader.FileTypes.ScriptFileConfig[])} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". - * @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('script', 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 ScriptFile(this, key[i])); - } - } - else - { - this.addFile(new ScriptFile(this, key, url, xhrSettings)); - } - - return this; -}); - -module.exports = ScriptFile; - - -/***/ }), -/* 499 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeImage = __webpack_require__(500); -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var PhysicsGroup = __webpack_require__(502); -var StaticPhysicsGroup = __webpack_require__(503); - -/** - * @classdesc - * The Arcade Physics Factory allows you to easily create Arcade Physics enabled Game Objects. - * Objects that are created by this Factory are automatically added to the physics world. - * - * @class Factory - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics World instance. - */ -var Factory = new Class({ - - initialize: - - function Factory (world) - { - /** - * A reference to the Arcade Physics World. - * - * @name Phaser.Physics.Arcade.Factory#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * A reference to the Scene this Arcade Physics instance belongs to. - * - * @name Phaser.Physics.Arcade.Factory#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = world.scene; - - /** - * A reference to the Scene.Systems this Arcade Physics instance belongs to. - * - * @name Phaser.Physics.Arcade.Factory#sys - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.sys = world.scene.sys; - }, - - /** - * Creates a new Arcade Physics Collider object. - * - * @method Phaser.Physics.Arcade.Factory#collider - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for collision. - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - collider: function (object1, object2, collideCallback, processCallback, callbackContext) - { - return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext); - }, - - /** - * Creates a new Arcade Physics Collider Overlap object. - * - * @method Phaser.Physics.Arcade.Factory#overlap - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for overlap. - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for overlap. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - overlap: function (object1, object2, collideCallback, processCallback, callbackContext) - { - return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext); - }, - - /** - * Adds an Arcade Physics Body to the given Game Object. - * - * @method Phaser.Physics.Arcade.Factory#existing - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - A Game Object. - * @param {boolean} [isStatic=false] - Create a Static body (true) or Dynamic body (false). - * - * @return {Phaser.Types.Physics.Arcade.GameObjectWithBody} The Game Object. - */ - existing: function (gameObject, isStatic) - { - var type = (isStatic) ? CONST.STATIC_BODY : CONST.DYNAMIC_BODY; - - this.world.enableBody(gameObject, type); - - return gameObject; - }, - - /** - * Creates a new Arcade Image object with a Static body. - * - * @method Phaser.Physics.Arcade.Factory#staticImage - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.ImageWithStaticBody} The Image object that was created. - */ - staticImage: function (x, y, key, frame) - { - var image = new ArcadeImage(this.scene, x, y, key, frame); - - this.sys.displayList.add(image); - - this.world.enableBody(image, CONST.STATIC_BODY); - - return image; - }, - - /** - * Creates a new Arcade Image object with a Dynamic body. - * - * @method Phaser.Physics.Arcade.Factory#image - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.ImageWithDynamicBody} The Image object that was created. - */ - image: function (x, y, key, frame) - { - var image = new ArcadeImage(this.scene, x, y, key, frame); - - this.sys.displayList.add(image); - - this.world.enableBody(image, CONST.DYNAMIC_BODY); - - return image; - }, - - /** - * Creates a new Arcade Sprite object with a Static body. - * - * @method Phaser.Physics.Arcade.Factory#staticSprite - * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created. - */ - staticSprite: function (x, y, key, frame) - { - var sprite = new ArcadeSprite(this.scene, x, y, key, frame); - - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); - - this.world.enableBody(sprite, CONST.STATIC_BODY); - - return sprite; - }, - - /** - * Creates a new Arcade Sprite object with a Dynamic body. - * - * @method Phaser.Physics.Arcade.Factory#sprite - * @since 3.0.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 Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * - * @return {Phaser.Types.Physics.Arcade.SpriteWithDynamicBody} The Sprite object that was created. - */ - sprite: function (x, y, key, frame) - { - var sprite = new ArcadeSprite(this.scene, x, y, key, frame); - - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); - - this.world.enableBody(sprite, CONST.DYNAMIC_BODY); - - return sprite; - }, - - /** - * Creates a Static Physics Group object. - * All Game Objects created by this Group will automatically be static Arcade Physics objects. - * - * @method Phaser.Physics.Arcade.Factory#staticGroup - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - * - * @return {Phaser.Physics.Arcade.StaticGroup} The Static Group object that was created. - */ - staticGroup: function (children, config) - { - return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config)); - }, - - /** - * Creates a Physics Group object. - * All Game Objects created by this Group will automatically be dynamic Arcade Physics objects. - * - * @method Phaser.Physics.Arcade.Factory#group - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - * - * @return {Phaser.Physics.Arcade.Group} The Group object that was created. - */ - group: function (children, config) - { - return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config)); - }, - - /** - * Destroys this Factory. - * - * @method Phaser.Physics.Arcade.Factory#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.world = null; - this.scene = null; - this.sys = null; - } - -}); - -module.exports = Factory; - - -/***/ }), -/* 500 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(238); -var Image = __webpack_require__(124); - -/** - * @classdesc - * An Arcade Physics Image is an Image with an Arcade Physics body and related components. - * The body can be dynamic or static. - * - * The main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image. - * - * @class Image - * @extends Phaser.GameObjects.Image - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @extends Phaser.Physics.Arcade.Components.Acceleration - * @extends Phaser.Physics.Arcade.Components.Angular - * @extends Phaser.Physics.Arcade.Components.Bounce - * @extends Phaser.Physics.Arcade.Components.Debug - * @extends Phaser.Physics.Arcade.Components.Drag - * @extends Phaser.Physics.Arcade.Components.Enable - * @extends Phaser.Physics.Arcade.Components.Friction - * @extends Phaser.Physics.Arcade.Components.Gravity - * @extends Phaser.Physics.Arcade.Components.Immovable - * @extends Phaser.Physics.Arcade.Components.Mass - * @extends Phaser.Physics.Arcade.Components.Pushable - * @extends Phaser.Physics.Arcade.Components.Size - * @extends Phaser.Physics.Arcade.Components.Velocity - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Tint - * @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 - 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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. - */ -var ArcadeImage = new Class({ - - Extends: Image, - - Mixins: [ - Components.Acceleration, - Components.Angular, - Components.Bounce, - Components.Debug, - Components.Drag, - Components.Enable, - Components.Friction, - Components.Gravity, - Components.Immovable, - Components.Mass, - Components.Pushable, - Components.Size, - Components.Velocity - ], - - initialize: - - function ArcadeImage (scene, x, y, texture, frame) - { - Image.call(this, scene, x, y, texture, frame); - - /** - * This Game Object's Physics Body. - * - * @name Phaser.Physics.Arcade.Image#body - * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} - * @default null - * @since 3.0.0 - */ - this.body = null; - } - -}); - -module.exports = ArcadeImage; - - -/***/ }), -/* 501 */ -/***/ (function(module, exports, __webpack_require__) { - -var OverlapRect = __webpack_require__(239); -var Circle = __webpack_require__(61); -var CircleToCircle = __webpack_require__(226); -var CircleToRectangle = __webpack_require__(149); - -/** - * This method will search the given circular area and return an array of all physics bodies that - * overlap with it. It can return either Dynamic, Static bodies or a mixture of both. - * - * A body only has to intersect with the search area to be considered, it doesn't have to be fully - * contained within it. - * - * If Arcade Physics is set to use the RTree (which it is by default) then the search is rather fast, - * otherwise the search is O(N) for Dynamic Bodies. - * - * @function Phaser.Physics.Arcade.Components.OverlapCirc - * @since 3.21.0 - * - * @param {number} x - The x coordinate of the center of the area to search within. - * @param {number} y - The y coordinate of the center of the area to search within. - * @param {number} radius - The radius of the area to search within. - * @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies? - * @param {boolean} [includeStatic=false] - Should the search include Static Bodies? - * - * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. - */ -var OverlapCirc = function (world, x, y, radius, includeDynamic, includeStatic) -{ - var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); - - if (bodiesInRect.length === 0) - { - return bodiesInRect; - } - - var area = new Circle(x, y, radius); - var circFromBody = new Circle(); - var bodiesInArea = []; - - for (var i = 0; i < bodiesInRect.length; i++) - { - var body = bodiesInRect[i]; - - if (body.isCircle) - { - circFromBody.setTo(body.center.x, body.center.y, body.halfWidth); - - if (CircleToCircle(area, circFromBody)) - { - bodiesInArea.push(body); - } - } - else if (CircleToRectangle(area, body)) - { - bodiesInArea.push(body); - } - } - - return bodiesInArea; -}; - -module.exports = OverlapCirc; - - -/***/ }), -/* 502 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(108); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * An Arcade Physics Group object. - * - * The primary use of a Physics Group is a way to collect together physics enable objects - * that share the same intrinsic structure into a single pool. They can they be easily - * compared against other Groups, or Game Objects. - * - * All Game Objects created by, or added to this Group will automatically be given **dynamic** - * Arcade Physics bodies (if they have no body already) and the bodies will receive the - * Groups {@link Phaser.Physics.Arcade.Group#defaults default values}. - * - * You should not pass objects into this Group that should not receive a body. For example, - * do not add basic Geometry or Tilemap Layers into a Group, as they will not behave in the - * way you may expect. Groups should all ideally have objects of the same type in them. - * - * If you wish to create a Group filled with Static Bodies, please see {@link Phaser.Physics.Arcade.StaticGroup}. - * - * @class Group - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The physics simulation. - * @param {Phaser.Scene} scene - The scene this group belongs to. - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - */ -var PhysicsGroup = new Class({ - - Extends: Group, - - initialize: - - function PhysicsGroup (world, scene, children, config) - { - if (!children && !config) - { - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - else if (IsPlainObject(children)) - { - // children is a plain object, so swizzle them: - config = children; - children = null; - - config.internalCreateCallback = this.createCallbackHandler; - config.internalRemoveCallback = this.removeCallbackHandler; - } - else if (Array.isArray(children) && IsPlainObject(children[0])) - { - // children is an array of plain objects (i.e., configs) - config = children[0]; - - var _this = this; - - children.forEach(function (singleConfig) - { - singleConfig.internalCreateCallback = _this.createCallbackHandler; - singleConfig.internalRemoveCallback = _this.removeCallbackHandler; - }); - - children = null; - } - else - { - // config is not defined and children is not a plain object nor an array of plain objects - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - - /** - * The physics simulation. - * - * @name Phaser.Physics.Arcade.Group#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The class to create new Group members from. - * - * This should be either `Phaser.Physics.Arcade.Image`, `Phaser.Physics.Arcade.Sprite`, or a class extending one of those. - * - * @name Phaser.Physics.Arcade.Group#classType - * @type {Function} - * @default ArcadeSprite - * @since 3.0.0 - */ - config.classType = GetFastValue(config, 'classType', ArcadeSprite); - - /** - * The physics type of the Group's members. - * - * @name Phaser.Physics.Arcade.Group#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.DYNAMIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.DYNAMIC_BODY; - - /** - * Default physics properties applied to Game Objects added to the Group or created by the Group. Derived from the `config` argument. - * - * You can remove the default values by setting this property to `{}`. - * - * @name Phaser.Physics.Arcade.Group#defaults - * @type {Phaser.Types.Physics.Arcade.PhysicsGroupDefaults} - * @since 3.0.0 - */ - this.defaults = { - setCollideWorldBounds: GetFastValue(config, 'collideWorldBounds', false), - setBoundsRectangle: GetFastValue(config, 'customBoundsRectangle', null), - setAccelerationX: GetFastValue(config, 'accelerationX', 0), - setAccelerationY: GetFastValue(config, 'accelerationY', 0), - setAllowDrag: GetFastValue(config, 'allowDrag', true), - setAllowGravity: GetFastValue(config, 'allowGravity', true), - setAllowRotation: GetFastValue(config, 'allowRotation', true), - setBounceX: GetFastValue(config, 'bounceX', 0), - setBounceY: GetFastValue(config, 'bounceY', 0), - setDragX: GetFastValue(config, 'dragX', 0), - setDragY: GetFastValue(config, 'dragY', 0), - setEnable: GetFastValue(config, 'enable', true), - setGravityX: GetFastValue(config, 'gravityX', 0), - setGravityY: GetFastValue(config, 'gravityY', 0), - setFrictionX: GetFastValue(config, 'frictionX', 0), - setFrictionY: GetFastValue(config, 'frictionY', 0), - setMaxVelocityX: GetFastValue(config, 'maxVelocityX', 10000), - setMaxVelocityY: GetFastValue(config, 'maxVelocityY', 10000), - setVelocityX: GetFastValue(config, 'velocityX', 0), - setVelocityY: GetFastValue(config, 'velocityY', 0), - setAngularVelocity: GetFastValue(config, 'angularVelocity', 0), - setAngularAcceleration: GetFastValue(config, 'angularAcceleration', 0), - setAngularDrag: GetFastValue(config, 'angularDrag', 0), - setMass: GetFastValue(config, 'mass', 1), - setImmovable: GetFastValue(config, 'immovable', false) - }; - - Group.call(this, scene, children, config); - - /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.Physics.Arcade.Group#type - * @type {string} - * @default 'PhysicsGroup' - * @since 3.21.0 - */ - this.type = 'PhysicsGroup'; - }, - - /** - * Enables a Game Object's Body and assigns `defaults`. Called when a Group member is added or created. - * - * @method Phaser.Physics.Arcade.Group#createCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object being added. - */ - createCallbackHandler: function (child) - { - if (!child.body) - { - this.world.enableBody(child, CONST.DYNAMIC_BODY); - } - - var body = child.body; - - for (var key in this.defaults) - { - body[key](this.defaults[key]); - } - }, - - /** - * Disables a Game Object's Body. Called when a Group member is removed. - * - * @method Phaser.Physics.Arcade.Group#removeCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object being removed. - */ - removeCallbackHandler: function (child) - { - if (child.body) - { - this.world.disableBody(child); - } - }, - - /** - * Sets the velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity. - * @param {number} y - The vertical velocity. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x, y), the second (x + step, y + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocity: function (x, y, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.set(x + (i * step), y + (i * step)); - } - - return this; - }, - - /** - * Sets the horizontal velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocityX - * @since 3.0.0 - * - * @param {number} value - The velocity value. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x), the second (x + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocityX: function (value, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.x = value + (i * step); - } - - return this; - }, - - /** - * Sets the vertical velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocityY - * @since 3.0.0 - * - * @param {number} value - The velocity value. - * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (y), the second (y + step), and so on. - * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. - */ - setVelocityY: function (value, step) - { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); - - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.y = value + (i * step); - } - - return this; - } - -}); - -module.exports = PhysicsGroup; - - -/***/ }), -/* 503 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ArcadeSprite = __webpack_require__(154); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(108); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * An Arcade Physics Static Group object. - * - * All Game Objects created by or added to this Group will automatically be given static Arcade Physics bodies, if they have no body. - * - * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Group}. - * - * @class StaticGroup - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The physics simulation. - * @param {Phaser.Scene} scene - The scene this group belongs to. - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. - */ -var StaticPhysicsGroup = new Class({ - - Extends: Group, - - initialize: - - function StaticPhysicsGroup (world, scene, children, config) - { - if (!children && !config) - { - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler, - createMultipleCallback: this.createMultipleCallbackHandler, - classType: ArcadeSprite - }; - } - else if (IsPlainObject(children)) - { - // children is a plain object, so swizzle them: - config = children; - children = null; - - config.internalCreateCallback = this.createCallbackHandler; - config.internalRemoveCallback = this.removeCallbackHandler; - config.createMultipleCallback = this.createMultipleCallbackHandler; - config.classType = GetFastValue(config, 'classType', ArcadeSprite); - } - else if (Array.isArray(children) && IsPlainObject(children[0])) - { - // children is an array of plain objects - config = children; - children = null; - - config.forEach(function (singleConfig) - { - singleConfig.internalCreateCallback = this.createCallbackHandler; - singleConfig.internalRemoveCallback = this.removeCallbackHandler; - singleConfig.createMultipleCallback = this.createMultipleCallbackHandler; - singleConfig.classType = GetFastValue(singleConfig, 'classType', ArcadeSprite); - }); - } - else - { - // config is not defined and children is not a plain object nor an array of plain objects - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - - /** - * The physics simulation. - * - * @name Phaser.Physics.Arcade.StaticGroup#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The scene this group belongs to. - * - * @name Phaser.Physics.Arcade.StaticGroup#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.STATIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.STATIC_BODY; - - Group.call(this, scene, children, config); - - /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.Physics.Arcade.StaticGroup#type - * @type {string} - * @default 'StaticPhysicsGroup' - * @since 3.21.0 - */ - this.type = 'StaticPhysicsGroup'; - }, - - /** - * Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation. - * - * @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The new group member. - * - * @see Phaser.Physics.Arcade.World#enableBody - */ - createCallbackHandler: function (child) - { - if (!child.body) - { - this.world.enableBody(child, CONST.STATIC_BODY); - } - }, - - /** - * Disables the group member's physics body, removing it from the simulation. - * - * @method Phaser.Physics.Arcade.StaticGroup#removeCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The group member being removed. - * - * @see Phaser.Physics.Arcade.World#disableBody - */ - removeCallbackHandler: function (child) - { - if (child.body) - { - this.world.disableBody(child); - } - }, - - /** - * Refreshes the group. - * - * @method Phaser.Physics.Arcade.StaticGroup#createMultipleCallbackHandler - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject[]} entries - The newly created group members. - * - * @see Phaser.Physics.Arcade.StaticGroup#refresh - */ - createMultipleCallbackHandler: function () - { - this.refresh(); - }, - - /** - * Resets each Body to the position of its parent Game Object. - * Body sizes aren't changed (use {@link Phaser.Physics.Arcade.Components.Enable#refreshBody} for that). - * - * @method Phaser.Physics.Arcade.StaticGroup#refresh - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.StaticGroup} This group. - * - * @see Phaser.Physics.Arcade.StaticBody#reset - */ - refresh: function () - { - var children = this.children.entries; - - for (var i = 0; i < children.length; i++) - { - children[i].body.reset(); - } - - return this; - } - -}); - -module.exports = StaticPhysicsGroup; - - -/***/ }), -/* 504 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AngleBetweenPoints = __webpack_require__(344); -var Body = __webpack_require__(505); -var Clamp = __webpack_require__(17); -var Class = __webpack_require__(0); -var Collider = __webpack_require__(506); -var CONST = __webpack_require__(59); -var DistanceBetween = __webpack_require__(48); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(240); -var FuzzyEqual = __webpack_require__(121); -var FuzzyGreaterThan = __webpack_require__(348); -var FuzzyLessThan = __webpack_require__(349); -var GetOverlapX = __webpack_require__(241); -var GetOverlapY = __webpack_require__(242); -var GetTilesWithinWorldXY = __webpack_require__(507); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); -var ProcessQueue = __webpack_require__(206); -var ProcessTileCallbacks = __webpack_require__(508); -var Rectangle = __webpack_require__(10); -var RTree = __webpack_require__(509); -var SeparateTile = __webpack_require__(510); -var SeparateX = __webpack_require__(515); -var SeparateY = __webpack_require__(516); -var Set = __webpack_require__(147); -var StaticBody = __webpack_require__(517); -var TileIntersectsBody = __webpack_require__(243); -var TransformMatrix = __webpack_require__(25); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(64); - -/** - * @classdesc - * The Arcade Physics World. - * - * The World is responsible for creating, managing, colliding and updating all of the bodies within it. - * - * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. - * - * @class World - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to which this World instance belongs. - * @param {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} config - An Arcade Physics Configuration object. - */ -var World = new Class({ - - Extends: EventEmitter, - - initialize: - - function World (scene, config) - { - EventEmitter.call(this); - - /** - * The Scene this simulation belongs to. - * - * @name Phaser.Physics.Arcade.World#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * Dynamic Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#bodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.bodies = new Set(); - - /** - * Static Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#staticBodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.staticBodies = new Set(); - - /** - * Static Bodies marked for deletion. - * - * @name Phaser.Physics.Arcade.World#pendingDestroy - * @type {Phaser.Structs.Set.<(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)>} - * @since 3.1.0 - */ - this.pendingDestroy = new Set(); - - /** - * This simulation's collision processors. - * - * @name Phaser.Physics.Arcade.World#colliders - * @type {Phaser.Structs.ProcessQueue.} - * @since 3.0.0 - */ - this.colliders = new ProcessQueue(); - - /** - * Acceleration of Bodies due to gravity, in pixels per second. - * - * @name Phaser.Physics.Arcade.World#gravity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.gravity = new Vector2(GetValue(config, 'gravity.x', 0), GetValue(config, 'gravity.y', 0)); - - /** - * A boundary constraining Bodies. - * - * @name Phaser.Physics.Arcade.World#bounds - * @type {Phaser.Geom.Rectangle} - * @since 3.0.0 - */ - this.bounds = new Rectangle( - GetValue(config, 'x', 0), - GetValue(config, 'y', 0), - GetValue(config, 'width', scene.sys.scale.width), - GetValue(config, 'height', scene.sys.scale.height) - ); - - /** - * The boundary edges that Bodies can collide with. - * - * @name Phaser.Physics.Arcade.World#checkCollision - * @type {Phaser.Types.Physics.Arcade.CheckCollisionObject} - * @since 3.0.0 - */ - this.checkCollision = { - up: GetValue(config, 'checkCollision.up', true), - down: GetValue(config, 'checkCollision.down', true), - left: GetValue(config, 'checkCollision.left', true), - right: GetValue(config, 'checkCollision.right', true) - }; - - /** - * The number of physics steps to be taken per second. - * - * This property is read-only. Use the `setFPS` method to modify it at run-time. - * - * @name Phaser.Physics.Arcade.World#fps - * @readonly - * @type {number} - * @default 60 - * @since 3.10.0 - */ - this.fps = GetValue(config, 'fps', 60); - - /** - * Should Physics use a fixed update time-step (true) or sync to the render fps (false)?. - * False value of this property disables fps and timeScale properties. - * - * @name Phaser.Physics.Arcade.World#fixedStep - * @type {boolean} - * @default true - * @since 3.23.0 - */ - this.fixedStep = GetValue(config, 'fixedStep', true); - - /** - * The amount of elapsed ms since the last frame. - * - * @name Phaser.Physics.Arcade.World#_elapsed - * @private - * @type {number} - * @since 3.10.0 - */ - this._elapsed = 0; - - /** - * Internal frame time value. - * - * @name Phaser.Physics.Arcade.World#_frameTime - * @private - * @type {number} - * @since 3.10.0 - */ - this._frameTime = 1 / this.fps; - - /** - * Internal frame time ms value. - * - * @name Phaser.Physics.Arcade.World#_frameTimeMS - * @private - * @type {number} - * @since 3.10.0 - */ - this._frameTimeMS = 1000 * this._frameTime; - - /** - * The number of steps that took place in the last frame. - * - * @name Phaser.Physics.Arcade.World#stepsLastFrame - * @readonly - * @type {number} - * @since 3.10.0 - */ - this.stepsLastFrame = 0; - - /** - * Scaling factor applied to the frame rate. - * - * - 1.0 = normal speed - * - 2.0 = half speed - * - 0.5 = double speed - * - * @name Phaser.Physics.Arcade.World#timeScale - * @type {number} - * @default 1 - * @since 3.10.0 - */ - this.timeScale = GetValue(config, 'timeScale', 1); - - /** - * The maximum absolute difference of a Body's per-step velocity and its overlap with another Body that will result in separation on *each axis*. - * Larger values favor separation. - * Smaller values favor no separation. - * - * @name Phaser.Physics.Arcade.World#OVERLAP_BIAS - * @type {number} - * @default 4 - * @since 3.0.0 - */ - this.OVERLAP_BIAS = GetValue(config, 'overlapBias', 4); - - /** - * The maximum absolute value of a Body's overlap with a tile that will result in separation on *each axis*. - * Larger values favor separation. - * Smaller values favor no separation. - * The optimum value may be similar to the tile size. - * - * @name Phaser.Physics.Arcade.World#TILE_BIAS - * @type {number} - * @default 16 - * @since 3.0.0 - */ - this.TILE_BIAS = GetValue(config, 'tileBias', 16); - - /** - * Always separate overlapping Bodies horizontally before vertically. - * False (the default) means Bodies are first separated on the axis of greater gravity, or the vertical axis if neither is greater. - * - * @name Phaser.Physics.Arcade.World#forceX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.forceX = GetValue(config, 'forceX', false); - - /** - * Whether the simulation advances with the game loop. - * - * @name Phaser.Physics.Arcade.World#isPaused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isPaused = GetValue(config, 'isPaused', false); - - /** - * Temporary total of colliding Bodies. - * - * @name Phaser.Physics.Arcade.World#_total - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._total = 0; - - /** - * Enables the debug display. - * - * @name Phaser.Physics.Arcade.World#drawDebug - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.drawDebug = GetValue(config, 'debug', false); - - /** - * The graphics object drawing the debug display. - * - * @name Phaser.Physics.Arcade.World#debugGraphic - * @type {Phaser.GameObjects.Graphics} - * @since 3.0.0 - */ - this.debugGraphic; - - /** - * Default debug display settings for new Bodies. - * - * @name Phaser.Physics.Arcade.World#defaults - * @type {Phaser.Types.Physics.Arcade.ArcadeWorldDefaults} - * @since 3.0.0 - */ - this.defaults = { - debugShowBody: GetValue(config, 'debugShowBody', true), - debugShowStaticBody: GetValue(config, 'debugShowStaticBody', true), - debugShowVelocity: GetValue(config, 'debugShowVelocity', true), - bodyDebugColor: GetValue(config, 'debugBodyColor', 0xff00ff), - staticBodyDebugColor: GetValue(config, 'debugStaticBodyColor', 0x0000ff), - velocityDebugColor: GetValue(config, 'debugVelocityColor', 0x00ff00) - }; - - /** - * The maximum number of items per node on the RTree. - * - * This is ignored if `useTree` is `false`. If you have a large number of bodies in - * your world then you may find search performance improves by increasing this value, - * to allow more items per node and less node division. - * - * @name Phaser.Physics.Arcade.World#maxEntries - * @type {number} - * @default 16 - * @since 3.0.0 - */ - this.maxEntries = GetValue(config, 'maxEntries', 16); - - /** - * Should this Arcade Physics World use an RTree for Dynamic bodies? - * - * An RTree is a fast way of spatially sorting of all the bodies in the world. - * However, at certain limits, the cost of clearing and inserting the bodies into the - * tree every frame becomes more expensive than the search speed gains it provides. - * - * If you have a large number of dynamic bodies in your world then it may be best to - * disable the use of the RTree by setting this property to `false` in the physics config. - * - * The number it can cope with depends on browser and device, but a conservative estimate - * of around 5,000 bodies should be considered the max before disabling it. - * - * This only applies to dynamic bodies. Static bodies are always kept in an RTree, - * because they don't have to be cleared every frame, so you benefit from the - * massive search speeds all the time. - * - * @name Phaser.Physics.Arcade.World#useTree - * @type {boolean} - * @default true - * @since 3.10.0 - */ - this.useTree = GetValue(config, 'useTree', true); - - /** - * The spatial index of Dynamic Bodies. - * - * @name Phaser.Physics.Arcade.World#tree - * @type {Phaser.Structs.RTree} - * @since 3.0.0 - */ - this.tree = new RTree(this.maxEntries); - - /** - * The spatial index of Static Bodies. - * - * @name Phaser.Physics.Arcade.World#staticTree - * @type {Phaser.Structs.RTree} - * @since 3.0.0 - */ - this.staticTree = new RTree(this.maxEntries); - - /** - * Recycled input for tree searches. - * - * @name Phaser.Physics.Arcade.World#treeMinMax - * @type {Phaser.Types.Physics.Arcade.ArcadeWorldTreeMinMax} - * @since 3.0.0 - */ - this.treeMinMax = { minX: 0, minY: 0, maxX: 0, maxY: 0 }; - - /** - * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. - * - * @name Phaser.Physics.Arcade.World#_tempMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix = new TransformMatrix(); - - /** - * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. - * - * @name Phaser.Physics.Arcade.World#_tempMatrix2 - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - if (this.drawDebug) - { - this.createDebugGraphic(); - } - }, - - /** - * Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group. - * - * The difference between this and the `enableBody` method is that you can pass arrays or Groups - * to this method. - * - * You can specify if the bodies are to be Dynamic or Static. A dynamic body can move via velocity and - * acceleration. A static body remains fixed in place and as such is able to use an optimized search - * tree, making it ideal for static elements such as level objects. You can still collide and overlap - * with static bodies. - * - * Normally, rather than calling this method directly, you'd use the helper methods available in the - * Arcade Physics Factory, such as: - * - * ```javascript - * this.physics.add.image(x, y, textureKey); - * this.physics.add.sprite(x, y, textureKey); - * ``` - * - * Calling factory methods encapsulates the creation of a Game Object and the creation of its - * body at the same time. If you are creating custom classes then you can pass them to this - * method to have their bodies created. - * - * @method Phaser.Physics.Arcade.World#enable - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to create the bodies. - * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. - */ - enable: function (object, bodyType) - { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!Array.isArray(object)) - { - object = [ object ]; - } - - for (var i = 0; i < object.length; i++) - { - var entry = object[i]; - - if (entry.isParent) - { - var children = entry.getChildren(); - - for (var c = 0; c < children.length; c++) - { - var child = children[c]; - - if (child.isParent) - { - // Handle Groups nested inside of Groups - this.enable(child, bodyType); - } - else - { - this.enableBody(child, bodyType); - } - } - } - else - { - this.enableBody(entry, bodyType); - } - } - }, - - /** - * Creates an Arcade Physics Body on a single Game Object. - * - * If the Game Object already has a body, this method will simply add it back into the simulation. - * - * You can specify if the body is Dynamic or Static. A dynamic body can move via velocity and - * acceleration. A static body remains fixed in place and as such is able to use an optimized search - * tree, making it ideal for static elements such as level objects. You can still collide and overlap - * with static bodies. - * - * Normally, rather than calling this method directly, you'd use the helper methods available in the - * Arcade Physics Factory, such as: - * - * ```javascript - * this.physics.add.image(x, y, textureKey); - * this.physics.add.sprite(x, y, textureKey); - * ``` - * - * Calling factory methods encapsulates the creation of a Game Object and the creation of its - * body at the same time. If you are creating custom classes then you can pass them to this - * method to have their bodies created. - * - * @method Phaser.Physics.Arcade.World#enableBody - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} object - The Game Object on which to create the body. - * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. - * - * @return {Phaser.GameObjects.GameObject} The Game Object on which the body was created. - */ - enableBody: function (object, bodyType) - { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!object.body) - { - if (bodyType === CONST.DYNAMIC_BODY) - { - object.body = new Body(this, object); - } - else if (bodyType === CONST.STATIC_BODY) - { - object.body = new StaticBody(this, object); - } - } - - this.add(object.body); - - return object; - }, - - /** - * Adds an existing Arcade Physics Body or StaticBody to the simulation. - * - * The body is enabled and added to the local search trees. - * - * @method Phaser.Physics.Arcade.World#add - * @since 3.10.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be added to the simulation. - * - * @return {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} The Body that was added to the simulation. - */ - add: function (body) - { - if (body.physicsType === CONST.DYNAMIC_BODY) - { - this.bodies.set(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - this.staticBodies.set(body); - - this.staticTree.insert(body); - } - - body.enable = true; - - return body; - }, - - /** - * Disables the Arcade Physics Body of a Game Object, an array of Game Objects, or the children of a Group. - * - * The difference between this and the `disableBody` method is that you can pass arrays or Groups - * to this method. - * - * The body itself is not deleted, it just has its `enable` property set to false, which - * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. - * - * @method Phaser.Physics.Arcade.World#disable - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to disable the bodies. - */ - disable: function (object) - { - if (!Array.isArray(object)) - { - object = [ object ]; - } - - for (var i = 0; i < object.length; i++) - { - var entry = object[i]; - - if (entry.isParent) - { - var children = entry.getChildren(); - - for (var c = 0; c < children.length; c++) - { - var child = children[c]; - - if (child.isParent) - { - // Handle Groups nested inside of Groups - this.disable(child); - } - else - { - this.disableBody(child.body); - } - } - } - else - { - this.disableBody(entry.body); - } - } - }, - - /** - * Disables an existing Arcade Physics Body or StaticBody and removes it from the simulation. - * - * The body is disabled and removed from the local search trees. - * - * The body itself is not deleted, it just has its `enable` property set to false, which - * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. - * - * @method Phaser.Physics.Arcade.World#disableBody - * @since 3.0.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be disabled. - */ - disableBody: function (body) - { - this.remove(body); - - body.enable = false; - }, - - /** - * Removes an existing Arcade Physics Body or StaticBody from the simulation. - * - * The body is disabled and removed from the local search trees. - * - * The body itself is not deleted, it just has its `enabled` property set to false, which - * means you can re-enable it again at any point by passing it to enable `enable` or `add`. - * - * @method Phaser.Physics.Arcade.World#remove - * @since 3.0.0 - * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation. - */ - remove: function (body) - { - if (body.physicsType === CONST.DYNAMIC_BODY) - { - this.tree.remove(body); - this.bodies.delete(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - this.staticBodies.delete(body); - this.staticTree.remove(body); - } - }, - - /** - * Creates a Graphics Game Object that the world will use to render the debug display to. - * - * This is called automatically when the World is instantiated if the `debug` config property - * was set to `true`. However, you can call it at any point should you need to display the - * debug Graphic from a fixed point. - * - * You can control which objects are drawn to the Graphics object, and the colors they use, - * by setting the debug properties in the physics config. - * - * You should not typically use this in a production game. Use it to aid during debugging. - * - * @method Phaser.Physics.Arcade.World#createDebugGraphic - * @since 3.0.0 - * - * @return {Phaser.GameObjects.Graphics} The Graphics object that was created for use by the World. - */ - createDebugGraphic: function () - { - var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); - - graphic.setDepth(Number.MAX_VALUE); - - this.debugGraphic = graphic; - - this.drawDebug = true; - - return graphic; - }, - - /** - * Sets the position, size and properties of the World boundary. - * - * The World boundary is an invisible rectangle that defines the edges of the World. - * If a Body is set to collide with the world bounds then it will automatically stop - * when it reaches any of the edges. You can optionally set which edges of the boundary - * should be checked against. - * - * @method Phaser.Physics.Arcade.World#setBounds - * @since 3.0.0 - * - * @param {number} x - The top-left x coordinate of the boundary. - * @param {number} y - The top-left y coordinate of the boundary. - * @param {number} width - The width of the boundary. - * @param {number} height - The height of the boundary. - * @param {boolean} [checkLeft] - Should bodies check against the left edge of the boundary? - * @param {boolean} [checkRight] - Should bodies check against the right edge of the boundary? - * @param {boolean} [checkUp] - Should bodies check against the top edge of the boundary? - * @param {boolean} [checkDown] - Should bodies check against the bottom edge of the boundary? - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - setBounds: function (x, y, width, height, checkLeft, checkRight, checkUp, checkDown) - { - this.bounds.setTo(x, y, width, height); - - if (checkLeft !== undefined) - { - this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); - } - - return this; - }, - - /** - * Enables or disables collisions on each edge of the World boundary. - * - * @method Phaser.Physics.Arcade.World#setBoundsCollision - * @since 3.0.0 - * - * @param {boolean} [left=true] - Should bodies check against the left edge of the boundary? - * @param {boolean} [right=true] - Should bodies check against the right edge of the boundary? - * @param {boolean} [up=true] - Should bodies check against the top edge of the boundary? - * @param {boolean} [down=true] - Should bodies check against the bottom edge of the boundary? - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - setBoundsCollision: function (left, right, up, down) - { - if (left === undefined) { left = true; } - if (right === undefined) { right = true; } - if (up === undefined) { up = true; } - if (down === undefined) { down = true; } - - this.checkCollision.left = left; - this.checkCollision.right = right; - this.checkCollision.up = up; - this.checkCollision.down = down; - - return this; - }, - - /** - * Pauses the simulation. - * - * A paused simulation does not update any existing bodies, or run any Colliders. - * - * However, you can still enable and disable bodies within it, or manually run collide or overlap - * checks. - * - * @method Phaser.Physics.Arcade.World#pause - * @fires Phaser.Physics.Arcade.Events#PAUSE - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - pause: function () - { - this.isPaused = true; - - this.emit(Events.PAUSE); - - return this; - }, - - /** - * Resumes the simulation, if paused. - * - * @method Phaser.Physics.Arcade.World#resume - * @fires Phaser.Physics.Arcade.Events#RESUME - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - resume: function () - { - this.isPaused = false; - - this.emit(Events.RESUME); - - return this; - }, - - /** - * Creates a new Collider object and adds it to the simulation. - * - * A Collider is a way to automatically perform collision checks between two objects, - * calling the collide and process callbacks if they occur. - * - * Colliders are run as part of the World update, after all of the Bodies have updated. - * - * By creating a Collider you don't need then call `World.collide` in your `update` loop, - * as it will be handled for you automatically. - * - * @method Phaser.Physics.Arcade.World#addCollider - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#collide - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - addCollider: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); - - this.colliders.add(collider); - - return collider; - }, - - /** - * Creates a new Overlap Collider object and adds it to the simulation. - * - * A Collider is a way to automatically perform overlap checks between two objects, - * calling the collide and process callbacks if they occur. - * - * Colliders are run as part of the World update, after all of the Bodies have updated. - * - * By creating a Collider you don't need then call `World.overlap` in your `update` loop, - * as it will be handled for you automatically. - * - * @method Phaser.Physics.Arcade.World#addOverlap - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap. - * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects overlap. Must return a boolean. - * @param {*} [callbackContext] - The scope in which to call the callbacks. - * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. - */ - addOverlap: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); - - this.colliders.add(collider); - - return collider; - }, - - /** - * Removes a Collider from the simulation so it is no longer processed. - * - * This method does not destroy the Collider. If you wish to add it back at a later stage you can call - * `World.colliders.add(Collider)`. - * - * If you no longer need the Collider you can call the `Collider.destroy` method instead, which will - * automatically clear all of its references and then remove it from the World. If you call destroy on - * a Collider you _don't_ need to pass it to this method too. - * - * @method Phaser.Physics.Arcade.World#removeCollider - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Collider} collider - The Collider to remove from the simulation. - * - * @return {Phaser.Physics.Arcade.World} This World object. - */ - removeCollider: function (collider) - { - this.colliders.remove(collider); - - return this; - }, - - /** - * Sets the frame rate to run the simulation at. - * - * The frame rate value is used to simulate a fixed update time step. This fixed - * time step allows for a straightforward implementation of a deterministic game state. - * - * This frame rate is independent of the frequency at which the game is rendering. The - * higher you set the fps, the more physics simulation steps will occur per game step. - * Conversely, the lower you set it, the less will take place. - * - * You can optionally advance the simulation directly yourself by calling the `step` method. - * - * @method Phaser.Physics.Arcade.World#setFPS - * @since 3.10.0 - * - * @param {number} framerate - The frame rate to advance the simulation at. - * - * @return {this} This World object. - */ - setFPS: function (framerate) - { - this.fps = framerate; - this._frameTime = 1 / this.fps; - this._frameTimeMS = 1000 * this._frameTime; - - return this; - }, - - /** - * Advances the simulation based on the elapsed time and fps rate. - * - * This is called automatically by your Scene and does not need to be invoked directly. - * - * @method Phaser.Physics.Arcade.World#update - * @fires Phaser.Physics.Arcade.Events#WORLD_STEP - * @since 3.0.0 - * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. - */ - update: function (time, delta) - { - if (this.isPaused || this.bodies.size === 0) - { - return; - } - - var i; - var fixedDelta = this._frameTime; - var msPerFrame = this._frameTimeMS * this.timeScale; - - this._elapsed += delta; - - // Update all active bodies - var body; - var bodies = this.bodies.entries; - - // Will a step happen this frame? - var willStep = (this._elapsed >= msPerFrame); - - if (!this.fixedStep) - { - fixedDelta = delta * 0.001; - willStep = true; - this._elapsed = 0; - } - - for (i = 0; i < bodies.length; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.preUpdate(willStep, fixedDelta); - } - } - - // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs - if (willStep) - { - this._elapsed -= msPerFrame; - this.stepsLastFrame = 1; - - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } - - // Process any colliders - var colliders = this.colliders.update(); - - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; - - if (collider.active) - { - collider.update(); - } - } - - this.emit(Events.WORLD_STEP, fixedDelta); - } - - // Process any additional steps this frame - while (this._elapsed >= msPerFrame) - { - this._elapsed -= msPerFrame; - - this.step(fixedDelta); - } - }, - - /** - * Advances the simulation by a time increment. - * - * @method Phaser.Physics.Arcade.World#step - * @fires Phaser.Physics.Arcade.Events#WORLD_STEP - * @since 3.10.0 - * - * @param {number} delta - The delta time amount, in seconds, by which to advance the simulation. - */ - step: function (delta) - { - // Update all active bodies - var i; - var body; - var bodies = this.bodies.entries; - var len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.update(delta); - } - } - - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } - - // Process any colliders - var colliders = this.colliders.update(); - - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; - - if (collider.active) - { - collider.update(); - } - } - - this.emit(Events.WORLD_STEP, delta); - - this.stepsLastFrame++; - }, - - /** - * Updates bodies, draws the debug display, and handles pending queue operations. - * - * @method Phaser.Physics.Arcade.World#postUpdate - * @since 3.0.0 - */ - postUpdate: function () - { - var i; - var body; - var bodies = this.bodies.entries; - var len = bodies.length; - - var dynamic = this.bodies; - var staticBodies = this.staticBodies; - - // We don't need to postUpdate if there wasn't a step this frame - if (this.stepsLastFrame) - { - this.stepsLastFrame = 0; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.enable) - { - body.postUpdate(); - } - } - } - - if (this.drawDebug) - { - var graphics = this.debugGraphic; - - graphics.clear(); - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - - bodies = staticBodies.entries; - len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - } - - var pending = this.pendingDestroy; - - if (pending.size > 0) - { - var dynamicTree = this.tree; - var staticTree = this.staticTree; - - bodies = pending.entries; - len = bodies.length; - - for (i = 0; i < len; i++) - { - body = bodies[i]; - - if (body.physicsType === CONST.DYNAMIC_BODY) - { - dynamicTree.remove(body); - dynamic.delete(body); - } - else if (body.physicsType === CONST.STATIC_BODY) - { - staticTree.remove(body); - staticBodies.delete(body); - } - - body.world = undefined; - body.gameObject = undefined; - } - - pending.clear(); - } - }, - - /** - * Calculates a Body's velocity and updates its position. - * - * @method Phaser.Physics.Arcade.World#updateMotion - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to be updated. - * @param {number} delta - The delta value to be used in the motion calculations, in seconds. - */ - updateMotion: function (body, delta) - { - if (body.allowRotation) - { - this.computeAngularVelocity(body, delta); - } - - this.computeVelocity(body, delta); - }, - - /** - * Calculates a Body's angular velocity. - * - * @method Phaser.Physics.Arcade.World#computeAngularVelocity - * @since 3.10.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. - * @param {number} delta - The delta value to be used in the calculation, in seconds. - */ - computeAngularVelocity: function (body, delta) - { - var velocity = body.angularVelocity; - var acceleration = body.angularAcceleration; - var drag = body.angularDrag; - var max = body.maxAngular; - - if (acceleration) - { - velocity += acceleration * delta; - } - else if (body.allowDrag && drag) - { - drag *= delta; - - if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) - { - velocity -= drag; - } - else if (FuzzyLessThan(velocity + drag, 0, 0.1)) - { - velocity += drag; - } - else - { - velocity = 0; - } - } - - velocity = Clamp(velocity, -max, max); - - var velocityDelta = velocity - body.angularVelocity; - - body.angularVelocity += velocityDelta; - body.rotation += (body.angularVelocity * delta); - }, - - /** - * Calculates a Body's per-axis velocity. - * - * @method Phaser.Physics.Arcade.World#computeVelocity - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. - * @param {number} delta - The delta value to be used in the calculation, in seconds. - */ - computeVelocity: function (body, delta) - { - var velocityX = body.velocity.x; - var accelerationX = body.acceleration.x; - var dragX = body.drag.x; - var maxX = body.maxVelocity.x; - - var velocityY = body.velocity.y; - var accelerationY = body.acceleration.y; - var dragY = body.drag.y; - var maxY = body.maxVelocity.y; - - var speed = body.speed; - var maxSpeed = body.maxSpeed; - var allowDrag = body.allowDrag; - var useDamping = body.useDamping; - - if (body.allowGravity) - { - velocityX += (this.gravity.x + body.gravity.x) * delta; - velocityY += (this.gravity.y + body.gravity.y) * delta; - } - - if (accelerationX) - { - velocityX += accelerationX * delta; - } - else if (allowDrag && dragX) - { - if (useDamping) - { - // Damping based deceleration - dragX = Math.pow(dragX, delta); - - velocityX *= dragX; - - speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); - - if (FuzzyEqual(speed, 0, 0.001)) - { - velocityX = 0; - } - } - else - { - // Linear deceleration - dragX *= delta; - - if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) - { - velocityX -= dragX; - } - else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) - { - velocityX += dragX; - } - else - { - velocityX = 0; - } - } - } - - if (accelerationY) - { - velocityY += accelerationY * delta; - } - else if (allowDrag && dragY) - { - if (useDamping) - { - // Damping based deceleration - dragY = Math.pow(dragY, delta); - - velocityY *= dragY; - - speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); - - if (FuzzyEqual(speed, 0, 0.001)) - { - velocityY = 0; - } - } - else - { - // Linear deceleration - dragY *= delta; - - if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) - { - velocityY -= dragY; - } - else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) - { - velocityY += dragY; - } - else - { - velocityY = 0; - } - } - } - - velocityX = Clamp(velocityX, -maxX, maxX); - velocityY = Clamp(velocityY, -maxY, maxY); - - body.velocity.set(velocityX, velocityY); - - if (maxSpeed > -1 && speed > maxSpeed) - { - body.velocity.normalize().scale(maxSpeed); - speed = maxSpeed; - } - - body.speed = speed; - }, - - /** - * Separates two Bodies. - * - * @method Phaser.Physics.Arcade.World#separate - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. - * @param {ArcadePhysicsCallback} [processCallback] - The process callback. - * @param {*} [callbackContext] - The context in which to invoke the callback. - * @param {boolean} [overlapOnly] - If this a collide or overlap check? - * @param {boolean} [intersects] - Assert that the bodies intersect and should not be tested before separation. - * - * @return {boolean} True if separation occurred, otherwise false. - */ - separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects) - { - if ( - !intersects && - !body1.enable || - !body2.enable || - body1.checkCollision.none || - body2.checkCollision.none || - !this.intersects(body1, body2)) - { - return false; - } - - // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort. - if (processCallback && processCallback.call(callbackContext, body1.gameObject, body2.gameObject) === false) - { - return false; - } - - // Circle vs. Circle quick bail out - if (body1.isCircle && body2.isCircle) - { - return this.separateCircle(body1, body2, overlapOnly); - } - - // We define the behavior of bodies in a collision circle and rectangle - // If a collision occurs in the corner points of the rectangle, the body behave like circles - - // Either body1 or body2 is a circle - if (body1.isCircle !== body2.isCircle) - { - var bodyRect = (body1.isCircle) ? body2 : body1; - var bodyCircle = (body1.isCircle) ? body1 : body2; - - var rect = { - x: bodyRect.x, - y: bodyRect.y, - right: bodyRect.right, - bottom: bodyRect.bottom - }; - - var circle = bodyCircle.center; - - if (circle.y < rect.y || circle.y > rect.bottom) - { - if (circle.x < rect.x || circle.x > rect.right) - { - return this.separateCircle(body1, body2, overlapOnly); - } - } - } - - var resultX = false; - var resultY = false; - - // Do we separate on x first or y first or both? - if (overlapOnly) - { - // No separation but we need to calculate overlapX, overlapY, etc. - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - else if (this.forceX || Math.abs(this.gravity.y + body1.gravity.y) < Math.abs(this.gravity.x + body1.gravity.x)) - { - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - - // Are they still intersecting? Let's do the other axis then - if (this.intersects(body1, body2)) - { - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - } - else - { - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); - - // Are they still intersecting? Let's do the other axis then - if (this.intersects(body1, body2)) - { - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); - } - } - - var result = (resultX || resultY); - - if (result) - { - if (overlapOnly) - { - if (body1.onOverlap || body2.onOverlap) - { - this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); - } - } - else if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } - } - - return result; - }, - - /** - * Separates two Bodies, when both are circular. - * - * @method Phaser.Physics.Arcade.World#separateCircle - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. - * @param {boolean} [overlapOnly] - If this a collide or overlap check? - * @param {number} [bias] - A small value added to the calculations. - * - * @return {boolean} True if separation occurred, otherwise false. - */ - separateCircle: function (body1, body2, overlapOnly, bias) - { - // Set the bounding box overlap values into the bodies themselves (hence we don't use the return values here) - GetOverlapX(body1, body2, false, bias); - GetOverlapY(body1, body2, false, bias); - - var overlap = 0; - - if (body1.isCircle !== body2.isCircle) - { - var rect = { - x: (body2.isCircle) ? body1.position.x : body2.position.x, - y: (body2.isCircle) ? body1.position.y : body2.position.y, - right: (body2.isCircle) ? body1.right : body2.right, - bottom: (body2.isCircle) ? body1.bottom : body2.bottom - }; - - var circle = { - x: (body1.isCircle) ? body1.center.x : body2.center.x, - y: (body1.isCircle) ? body1.center.y : body2.center.y, - radius: (body1.isCircle) ? body1.halfWidth : body2.halfWidth - }; - - if (circle.y < rect.y) - { - if (circle.x < rect.x) - { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.y) - circle.radius; - } - else if (circle.x > rect.right) - { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.y) - circle.radius; - } - } - else if (circle.y > rect.bottom) - { - if (circle.x < rect.x) - { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.bottom) - circle.radius; - } - else if (circle.x > rect.right) - { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.bottom) - circle.radius; - } - } - - overlap *= -1; - } - else - { - overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y); - } - - body1.overlapR = overlap; - body2.overlapR = overlap; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1.immovable && body2.immovable) || body1.customSeparateX || body2.customSeparateX) - { - if (overlap !== 0 && (body1.onOverlap || body2.onOverlap)) - { - this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); - } - - // return true if there was some overlap, otherwise false - return (overlap !== 0); - } - - var dx = body1.center.x - body2.center.x; - var dy = body1.center.y - body2.center.y; - var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - var nx = ((body2.center.x - body1.center.x) / d) || 0; - var ny = ((body2.center.y - body1.center.y) / d) || 0; - var p = 2 * (body1.velocity.x * nx + body1.velocity.y * ny - body2.velocity.x * nx - body2.velocity.y * ny) / (body1.mass + body2.mass); - - if (body1.immovable || body2.immovable) - { - p *= 2; - } - - if (!body1.immovable) - { - body1.velocity.x = (body1.velocity.x - p / body1.mass * nx); - body1.velocity.y = (body1.velocity.y - p / body1.mass * ny); - } - - if (!body2.immovable) - { - body2.velocity.x = (body2.velocity.x + p / body2.mass * nx); - body2.velocity.y = (body2.velocity.y + p / body2.mass * ny); - } - - if (!body1.immovable && !body2.immovable) - { - overlap /= 2; - } - - // Note: This is inadequate for circle-rectangle separation - - var angle = AngleBetweenPoints(body1.center, body2.center); - var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle); - var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle); - - if (!body1.immovable) - { - body1.x -= overlapX; - body1.y -= overlapY; - - body1.updateCenter(); - } - - if (!body2.immovable) - { - body2.x += overlapX; - body2.y += overlapY; - - body2.updateCenter(); - } - - body1.velocity.x *= body1.bounce.x; - body1.velocity.y *= body1.bounce.y; - body2.velocity.x *= body2.bounce.x; - body2.velocity.y *= body2.bounce.y; - - if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } - - return true; - }, - - /** - * Checks to see if two Bodies intersect at all. - * - * @method Phaser.Physics.Arcade.World#intersects - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first body to check. - * @param {Phaser.Physics.Arcade.Body} body2 - The second body to check. - * - * @return {boolean} True if the two bodies intersect, otherwise false. - */ - intersects: function (body1, body2) - { - if (body1 === body2) - { - return false; - } - - if (!body1.isCircle && !body2.isCircle) - { - // Rect vs. Rect - return !( - body1.right <= body2.position.x || - body1.bottom <= body2.position.y || - body1.position.x >= body2.right || - body1.position.y >= body2.bottom - ); - } - else if (body1.isCircle) - { - if (body2.isCircle) - { - // Circle vs. Circle - return DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y) <= (body1.halfWidth + body2.halfWidth); - } - else - { - // Circle vs. Rect - return this.circleBodyIntersects(body1, body2); - } - } - else - { - // Rect vs. Circle - return this.circleBodyIntersects(body2, body1); - } - }, - - /** - * Tests if a circular Body intersects with another Body. - * - * @method Phaser.Physics.Arcade.World#circleBodyIntersects - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} circle - The circular body to test. - * @param {Phaser.Physics.Arcade.Body} body - The rectangular body to test. - * - * @return {boolean} True if the two bodies intersect, otherwise false. - */ - circleBodyIntersects: function (circle, body) - { - var x = Clamp(circle.center.x, body.left, body.right); - var y = Clamp(circle.center.y, body.top, body.bottom); - - var dx = (circle.center.x - x) * (circle.center.x - x); - var dy = (circle.center.y - y) * (circle.center.y - y); - - return (dx + dy) <= (circle.halfWidth * circle.halfWidth); - }, - - /** - * Tests if Game Objects overlap. - * - * See details in {@link Phaser.Physics.Arcade.World#collide}. - * - * @method Phaser.Physics.Arcade.World#overlap - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `overlapCallback` will only be called if this callback returns `true`. - * @param {*} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if at least one Game Object overlaps another. - * - * @see Phaser.Physics.Arcade.World#collide - */ - overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) - { - if (overlapCallback === undefined) { overlapCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = overlapCallback; } - - return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true); - }, - - /** - * Performs a collision check and separation between the two physics enabled objects given, which can be single - * Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups. - * - * If you don't require separation then use {@link Phaser.Physics.Arcade.World#overlap} instead. - * - * If two Groups or arrays are passed, each member of one will be tested against each member of the other. - * - * If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members. - * - * If **only** one Array is passed, the array is iterated and every element in it is tested against the others. - * - * Two callbacks can be provided; they receive the colliding game objects as arguments. - * If an overlap is detected, the `processCallback` is called first. It can cancel the collision by returning false. - * Next the objects are separated and `collideCallback` is invoked. - * - * Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable - * for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other. - * The separation that stops two objects penetrating may create a new penetration against a different object. If you - * require a high level of stability please consider using an alternative physics system, such as Matter.js. - * - * @method Phaser.Physics.Arcade.World#collide - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} `true` if any overlapping Game Objects were separated, otherwise `false`. - */ - collide: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); - }, - - /** - * Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideObjects - * @private - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideObjects: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) - { - var i; - var j; - - if (object1.isParent && object1.physicsType === undefined) - { - object1 = object1.children.entries; - } - - if (object2 && object2.isParent && object2.physicsType === undefined) - { - object2 = object2.children.entries; - } - - var object1isArray = Array.isArray(object1); - var object2isArray = Array.isArray(object2); - - this._total = 0; - - if (!object1isArray && !object2isArray) - { - // Neither of them are arrays - do this first as it's the most common use-case - this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (!object1isArray && object2isArray) - { - // Object 2 is an Array - for (i = 0; i < object2.length; i++) - { - this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - else if (object1isArray && !object2isArray) - { - // Object 1 is an Array - if (!object2) - { - // Special case for array vs. self - for (i = 0; i < object1.length; i++) - { - var child = object1[i]; - - for (j = i + 1; j < object1.length; j++) - { - if (i === j) - { - continue; - } - - this.collideHandler(child, object1[j], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - else - { - for (i = 0; i < object1.length; i++) - { - this.collideHandler(object1[i], object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - else - { - // They're both arrays - for (i = 0; i < object1.length; i++) - { - for (j = 0; j < object2.length; j++) - { - this.collideHandler(object1[i], object2[j], collideCallback, processCallback, callbackContext, overlapOnly); - } - } - } - - return (this._total > 0); - }, - - /** - * Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead. - * - * @method Phaser.Physics.Arcade.World#collideHandler - * @private - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object or array of objects to check, or `undefined`. - * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} callbackContext - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) - { - // Collide Group with Self - // Only collide valid objects - if (object2 === undefined && object1.isParent) - { - return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - - // If neither of the objects are set then bail out - if (!object1 || !object2) - { - return false; - } - - // A Body - if (object1.body) - { - if (object2.body) - { - return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isTilemap) - { - return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - - // GROUPS - else if (object1.isParent) - { - if (object2.body) - { - return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isTilemap) - { - return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - - // TILEMAP LAYERS - else if (object1.isTilemap) - { - if (object2.body) - { - return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - else if (object2.isParent) - { - return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); - } - } - }, - - /** - * Internal handler for Sprite vs. Sprite collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsSprite - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite1 - The first object to check for collision. - * @param {Phaser.GameObjects.GameObject} sprite2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) - { - if (!sprite1.body || !sprite2.body) - { - return false; - } - - if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } - - this._total++; - } - - return true; - }, - - /** - * Internal handler for Sprite vs. Group collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsGroup - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.GameObjects.Group} group - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. - */ - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) - { - var bodyA = sprite.body; - - if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) - { - return; - } - - // Does sprite collide with anything? - - var i; - var len; - var bodyB; - - if (this.useTree || group.physicsType === CONST.STATIC_BODY) - { - var minMax = this.treeMinMax; - - minMax.minX = bodyA.left; - minMax.minY = bodyA.top; - minMax.maxX = bodyA.right; - minMax.maxY = bodyA.bottom; - - var results = (group.physicsType === CONST.DYNAMIC_BODY) ? this.tree.search(minMax) : this.staticTree.search(minMax); - - len = results.length; - - for (i = 0; i < len; i++) - { - bodyB = results[i]; - - if (bodyA === bodyB || !bodyB.enable || bodyB.checkCollision.none || !group.contains(bodyB.gameObject)) - { - // Skip if comparing against itself, or if bodyB isn't collidable, or if bodyB isn't actually part of the Group - continue; - } - - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } - - this._total++; - } - } - } - else - { - var children = group.getChildren(); - var skipIndex = group.children.entries.indexOf(sprite); - - len = children.length; - - for (i = 0; i < len; i++) - { - bodyB = children[i].body; - - if (!bodyB || i === skipIndex || !bodyB.enable) - { - continue; - } - - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } - - this._total++; - } - } - } - }, - - /** - * Internal handler for Group vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Group} group - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} callbackContext - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) - { - var children = group.getChildren(); - - if (children.length === 0) - { - return false; - } - - var didCollide = false; - - for (var i = 0; i < children.length; i++) - { - if (children[i].body) - { - if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) - { - didCollide = true; - } - } - } - - return didCollide; - }, - - /** - * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. - * - * You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform - * tile filtering and culling for you, as well as handle the interesting face collision automatically. - * - * This method is offered for those who would like to check for collision with specific Tiles in a layer, without - * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions - * on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, - * you should filter them before passing them to this method. - * - * Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have - * say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the - * tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on - * dynamic maps, this method can prove very useful. - * - * @method Phaser.Physics.Arcade.World#collideTiles - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) - { - if (!sprite.body.enable || tiles.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); - } - }, - - /** - * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. - * - * You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform - * tile filtering and culling for you, as well as handle the interesting face collision automatically. - * - * This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without - * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap - * tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, - * you should filter them before passing them to this method. - * - * @method Phaser.Physics.Arcade.World#overlapTiles - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - overlapTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) - { - if (!sprite.body.enable || tiles.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); - } - }, - - /** - * Internal handler for Sprite vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsTilemapLayer - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) - { - var body = sprite.body; - - if (!body.enable || body.checkCollision.none) - { - return false; - } - - var x = body.position.x; - var y = body.position.y; - var w = body.width; - var h = body.height; - - var layerData = tilemapLayer.layer; - - if (layerData.tileWidth > layerData.baseTileWidth) - { - // The x origin of a tile is the left side, so x and width need to be adjusted. - var xDiff = (layerData.tileWidth - layerData.baseTileWidth) * tilemapLayer.scaleX; - x -= xDiff; - w += xDiff; - } - - if (layerData.tileHeight > layerData.baseTileHeight) - { - // The y origin of a tile is the bottom side, so just the height needs to be adjusted. - var yDiff = (layerData.tileHeight - layerData.baseTileHeight) * tilemapLayer.scaleY; - h += yDiff; - } - - var mapData = GetTilesWithinWorldXY(x, y, w, h, null, tilemapLayer.scene.cameras.main, tilemapLayer.layer); - - if (mapData.length === 0) - { - return false; - } - else - { - return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); - } - }, - - /** - * Internal handler for Sprite vs. Tilemap collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler - * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @private - * @since 3.17.0 - * - * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. - * @param {boolean} [isLayer] - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) - { - var body = sprite.body; - - var tile; - var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 }; - var tilemapLayer; - var collision = false; - - for (var i = 0; i < tiles.length; i++) - { - tile = tiles[i]; - - tilemapLayer = tile.tilemapLayer; - - var point = tilemapLayer.tileToWorldXY(tile.x, tile.y); - - tileWorldRect.left = point.x; - tileWorldRect.top = point.y; - - // If the maps base tile size differs from the layer tile size, only the top of the rect - // needs to be adjusted since its origin is (0, 1). - if (tile.baseHeight !== tile.height) - { - tileWorldRect.top -= (tile.height - tile.baseHeight) * tilemapLayer.scaleY; - } - - tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; - tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; - - if (TileIntersectsBody(tileWorldRect, body) - && (!processCallback || processCallback.call(callbackContext, sprite, tile)) - && ProcessTileCallbacks(tile, sprite) - && (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS, isLayer))) - { - this._total++; - - collision = true; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, tile); - } - - if (overlapOnly && body.onOverlap) - { - this.emit(Events.TILE_OVERLAP, sprite, tile, body); - } - else if (body.onCollide) - { - this.emit(Events.TILE_COLLIDE, sprite, tile, body); - } - } - } - - return collision; - }, - - /** - * Internal helper for Group vs. Group collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. - * - * @method Phaser.Physics.Arcade.World#collideGroupVsGroup - * @private - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Group} group1 - The first object to check for collision. - * @param {Phaser.GameObjects.Group} group2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. - * @param {any} [callbackContext] - The context in which to run the callbacks. - * @param {boolean} overlapOnly - Whether this is a collision or overlap check. - * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. - */ - collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) - { - if (group1.length === 0 || group2.length === 0) - { - return; - } - - var children = group1.getChildren(); - - for (var i = 0; i < children.length; i++) - { - this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); - } - }, - - /** - * Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}. - * - * If the object is outside any boundary edge (left, top, right, bottom), it will be moved to the same offset from the opposite edge (the interior). - * - * @method Phaser.Physics.Arcade.World#wrap - * @since 3.3.0 - * - * @param {any} object - A Game Object, a Group, an object with `x` and `y` coordinates, or an array of such objects. - * @param {number} [padding=0] - An amount added to each boundary edge during the operation. - */ - wrap: function (object, padding) - { - if (object.body) - { - this.wrapObject(object, padding); - } - else if (object.getChildren) - { - this.wrapArray(object.getChildren(), padding); - } - else if (Array.isArray(object)) - { - this.wrapArray(object, padding); - } - else - { - this.wrapObject(object, padding); - } - }, - - /** - * Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. - * - * @method Phaser.Physics.Arcade.World#wrapArray - * @since 3.3.0 - * - * @param {Array.<*>} objects - An array of objects to be wrapped. - * @param {number} [padding=0] - An amount added to the boundary. - */ - wrapArray: function (objects, padding) - { - for (var i = 0; i < objects.length; i++) - { - this.wrapObject(objects[i], padding); - } - }, - - /** - * Wrap an object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. - * - * @method Phaser.Physics.Arcade.World#wrapObject - * @since 3.3.0 - * - * @param {*} object - A Game Object, a Physics Body, or any object with `x` and `y` coordinates - * @param {number} [padding=0] - An amount added to the boundary. - */ - wrapObject: function (object, padding) - { - if (padding === undefined) { padding = 0; } - - object.x = Wrap(object.x, this.bounds.left - padding, this.bounds.right + padding); - object.y = Wrap(object.y, this.bounds.top - padding, this.bounds.bottom + padding); - }, - - /** - * Shuts down the simulation, clearing physics data and removing listeners. - * - * @method Phaser.Physics.Arcade.World#shutdown - * @since 3.0.0 - */ - shutdown: function () - { - this.tree.clear(); - this.staticTree.clear(); - this.bodies.clear(); - this.staticBodies.clear(); - this.colliders.destroy(); - - this.removeAllListeners(); - }, - - /** - * Shuts down the simulation and disconnects it from the current scene. - * - * @method Phaser.Physics.Arcade.World#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - - this.scene = null; - } - -}); - -module.exports = World; - - -/***/ }), -/* 505 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @author Benjamin D. Richards - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var Events = __webpack_require__(240); -var RadToDeg = __webpack_require__(192); -var Rectangle = __webpack_require__(10); -var RectangleContains = __webpack_require__(56); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A Dynamic Arcade Body. - * - * Its static counterpart is {@link Phaser.Physics.Arcade.StaticBody}. - * - * @class Body - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Body belongs to. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. - */ -var Body = new Class({ - - initialize: - - function Body (world, gameObject) - { - var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; - var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; - - /** - * The Arcade Physics simulation this Body belongs to. - * - * @name Phaser.Physics.Arcade.Body#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The Game Object this Body belongs to. - * - * @name Phaser.Physics.Arcade.Body#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.gameObject = gameObject; - - /** - * Transformations applied to this Body. - * - * @name Phaser.Physics.Arcade.Body#transform - * @type {object} - * @since 3.4.0 - */ - this.transform = { - x: gameObject.x, - y: gameObject.y, - rotation: gameObject.angle, - scaleX: gameObject.scaleX, - scaleY: gameObject.scaleY, - displayOriginX: gameObject.displayOriginX, - displayOriginY: gameObject.displayOriginY - }; - - /** - * Whether the Body is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugShowBody - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowBody = world.defaults.debugShowBody; - - /** - * Whether the Body's velocity is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugShowVelocity - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowVelocity = world.defaults.debugShowVelocity; - - /** - * The color of this Body on the debug display. - * - * @name Phaser.Physics.Arcade.Body#debugBodyColor - * @type {number} - * @since 3.0.0 - */ - this.debugBodyColor = world.defaults.bodyDebugColor; - - /** - * Whether this Body is updated by the physics simulation. - * - * @name Phaser.Physics.Arcade.Body#enable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enable = true; - - /** - * Whether this Body is circular (true) or rectangular (false). - * - * @name Phaser.Physics.Arcade.Body#isCircle - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setCircle - */ - this.isCircle = false; - - /** - * If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels. - * The true radius is equal to `halfWidth`. - * - * @name Phaser.Physics.Arcade.Body#radius - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setCircle - */ - this.radius = 0; - - /** - * The offset of this Body's position from its Game Object's position, in source pixels. - * - * @name Phaser.Physics.Arcade.Body#offset - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setOffset - */ - this.offset = new Vector2(); - - /** - * The position of this Body within the simulation. - * - * @name Phaser.Physics.Arcade.Body#position - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.position = new Vector2( - gameObject.x - gameObject.scaleX * gameObject.displayOriginX, - gameObject.y - gameObject.scaleY * gameObject.displayOriginY - ); - - /** - * The position of this Body during the previous step. - * - * @name Phaser.Physics.Arcade.Body#prev - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.prev = this.position.clone(); - - /** - * The position of this Body during the previous frame. - * - * @name Phaser.Physics.Arcade.Body#prevFrame - * @type {Phaser.Math.Vector2} - * @since 3.20.0 - */ - this.prevFrame = this.position.clone(); - - /** - * Whether this Body's `rotation` is affected by its angular acceleration and angular velocity. - * - * @name Phaser.Physics.Arcade.Body#allowRotation - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.allowRotation = true; - - /** - * This body's rotation, in degrees, based on its angular acceleration and angular velocity. - * The Body's rotation controls the `angle` of its Game Object. - * It doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle. - * - * @name Phaser.Physics.Arcade.Body#rotation - * @type {number} - * @since 3.0.0 - */ - this.rotation = gameObject.angle; - - /** - * The Body rotation, in degrees, during the previous step. - * - * @name Phaser.Physics.Arcade.Body#preRotation - * @type {number} - * @since 3.0.0 - */ - this.preRotation = gameObject.angle; - - /** - * The width of the Body, in pixels. - * If the Body is circular, this is also the diameter. - * If you wish to change the width use the `Body.setSize` method. - * - * @name Phaser.Physics.Arcade.Body#width - * @type {number} - * @readonly - * @default 64 - * @since 3.0.0 - */ - this.width = width; - - /** - * The height of the Body, in pixels. - * If the Body is circular, this is also the diameter. - * If you wish to change the height use the `Body.setSize` method. - * - * @name Phaser.Physics.Arcade.Body#height - * @type {number} - * @readonly - * @default 64 - * @since 3.0.0 - */ - this.height = height; - - /** - * The unscaled width of the Body, in source pixels, as set by setSize(). - * The default is the width of the Body's Game Object's texture frame. - * - * @name Phaser.Physics.Arcade.Body#sourceWidth - * @type {number} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setSize - */ - this.sourceWidth = width; - - /** - * The unscaled height of the Body, in source pixels, as set by setSize(). - * The default is the height of the Body's Game Object's texture frame. - * - * @name Phaser.Physics.Arcade.Body#sourceHeight - * @type {number} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#setSize - */ - this.sourceHeight = height; - - if (gameObject.frame) - { - this.sourceWidth = gameObject.frame.realWidth; - this.sourceHeight = gameObject.frame.realHeight; - } - - /** - * Half the Body's width, in pixels. - * - * @name Phaser.Physics.Arcade.Body#halfWidth - * @type {number} - * @since 3.0.0 - */ - this.halfWidth = Math.abs(width / 2); - - /** - * Half the Body's height, in pixels. - * - * @name Phaser.Physics.Arcade.Body#halfHeight - * @type {number} - * @since 3.0.0 - */ - this.halfHeight = Math.abs(height / 2); - - /** - * The center of the Body. - * The midpoint of its `position` (top-left corner) and its bottom-right corner. - * - * @name Phaser.Physics.Arcade.Body#center - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - /** - * The Body's velocity, in pixels per second. - * - * @name Phaser.Physics.Arcade.Body#velocity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.velocity = new Vector2(); - - /** - * The Body's change in position (due to velocity) at the last step, in pixels. - * - * The size of this value depends on the simulation's step rate. - * - * @name Phaser.Physics.Arcade.Body#newVelocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.newVelocity = new Vector2(); - - /** - * The Body's absolute maximum change in position, in pixels per step. - * - * @name Phaser.Physics.Arcade.Body#deltaMax - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.deltaMax = new Vector2(); - - /** - * The Body's change in velocity, in pixels per second squared. - * - * @name Phaser.Physics.Arcade.Body#acceleration - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.acceleration = new Vector2(); - - /** - * Whether this Body's velocity is affected by its `drag`. - * - * @name Phaser.Physics.Arcade.Body#allowDrag - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.allowDrag = true; - - /** - * When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared. - * - * When `useDamping` is true, this is a damping multiplier between 0 and 1. - * A value of 0 means the Body stops instantly. - * A value of 0.01 mean the Body loses 99% of its velocity per second. - * A value of 0.1 means the Body loses 90% of its velocity per second. - * A value of 1 means the Body loses no velocity. - * - * The x and y components are applied separately. - * - * Drag is applied only when `acceleration` is zero. - * - * @name Phaser.Physics.Arcade.Body#drag - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.drag = new Vector2(); - - /** - * Whether this Body's position is affected by gravity (local or world). - * - * @name Phaser.Physics.Arcade.Body#allowGravity - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#gravity - * @see Phaser.Physics.Arcade.World#gravity - */ - this.allowGravity = true; - - /** - * Acceleration due to gravity (specific to this Body), in pixels per second squared. - * Total gravity is the sum of this vector and the simulation's `gravity`. - * - * @name Phaser.Physics.Arcade.Body#gravity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#gravity - */ - this.gravity = new Vector2(); - - /** - * Rebound following a collision, relative to 1. - * - * @name Phaser.Physics.Arcade.Body#bounce - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.bounce = new Vector2(); - - /** - * Rebound following a collision with the world boundary, relative to 1. - * If null, `bounce` is used instead. - * - * @name Phaser.Physics.Arcade.Body#worldBounce - * @type {?Phaser.Math.Vector2} - * @default null - * @since 3.0.0 - */ - this.worldBounce = null; - - /** - * The rectangle used for world boundary collisions. - * - * By default it is set to the world boundary rectangle. Or, if this Body was - * created by a Physics Group, then whatever rectangle that Group defined. - * - * You can also change it by using the `Body.setBoundsRectangle` method. - * - * @name Phaser.Physics.Arcade.Body#customBoundsRectangle - * @type {Phaser.Geom.Rectangle} - * @since 3.20 - */ - this.customBoundsRectangle = world.bounds; - - // If true this Body will dispatch events - - /** - * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). - * - * @name Phaser.Physics.Arcade.Body#onWorldBounds - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#WORLD_BOUNDS - */ - this.onWorldBounds = false; - - /** - * Whether the simulation emits a `collide` event when this Body collides with another. - * - * @name Phaser.Physics.Arcade.Body#onCollide - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#COLLIDE - */ - this.onCollide = false; - - /** - * Whether the simulation emits an `overlap` event when this Body overlaps with another. - * - * @name Phaser.Physics.Arcade.Body#onOverlap - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#OVERLAP - */ - this.onOverlap = false; - - /** - * The Body's absolute maximum velocity, in pixels per second. - * The horizontal and vertical components are applied separately. - * - * @name Phaser.Physics.Arcade.Body#maxVelocity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.maxVelocity = new Vector2(10000, 10000); - - /** - * The maximum speed this Body is allowed to reach, in pixels per second. - * - * If not negative it limits the scalar value of speed. - * - * Any negative value means no maximum is being applied (the default). - * - * @name Phaser.Physics.Arcade.Body#maxSpeed - * @type {number} - * @default -1 - * @since 3.16.0 - */ - this.maxSpeed = -1; - - /** - * If this Body is `immovable` and in motion, `friction` is the proportion of this Body's motion received by the riding Body on each axis, relative to 1. - * The horizontal component (x) is applied only when two colliding Bodies are separated vertically. - * The vertical component (y) is applied only when two colliding Bodies are separated horizontally. - * The default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all. - * - * @name Phaser.Physics.Arcade.Body#friction - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.friction = new Vector2(1, 0); - - /** - * If this Body is using `drag` for deceleration this property controls how the drag is applied. - * If set to `true` drag will use a damping effect rather than a linear approach. If you are - * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in - * the game Asteroids) then you will get a far smoother and more visually correct deceleration - * by using damping, avoiding the axis-drift that is prone with linear deceleration. - * - * If you enable this property then you should use far smaller `drag` values than with linear, as - * they are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow - * deceleration. - * - * @name Phaser.Physics.Arcade.Body#useDamping - * @type {boolean} - * @default false - * @since 3.10.0 - */ - this.useDamping = false; - - /** - * The rate of change of this Body's `rotation`, in degrees per second. - * - * @name Phaser.Physics.Arcade.Body#angularVelocity - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularVelocity = 0; - - /** - * The Body's angular acceleration (change in angular velocity), in degrees per second squared. - * - * @name Phaser.Physics.Arcade.Body#angularAcceleration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularAcceleration = 0; - - /** - * Loss of angular velocity due to angular movement, in degrees per second. - * - * Angular drag is applied only when angular acceleration is zero. - * - * @name Phaser.Physics.Arcade.Body#angularDrag - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angularDrag = 0; - - /** - * The Body's maximum angular velocity, in degrees per second. - * - * @name Phaser.Physics.Arcade.Body#maxAngular - * @type {number} - * @default 1000 - * @since 3.0.0 - */ - this.maxAngular = 1000; - - /** - * The Body's inertia, relative to a default unit (1). - * With `bounce`, this affects the exchange of momentum (velocities) during collisions. - * - * @name Phaser.Physics.Arcade.Body#mass - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.mass = 1; - - /** - * The calculated angle of this Body's velocity vector, in radians, during the last step. - * - * @name Phaser.Physics.Arcade.Body#angle - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.angle = 0; - - /** - * The calculated magnitude of the Body's velocity, in pixels per second, during the last step. - * - * @name Phaser.Physics.Arcade.Body#speed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.speed = 0; - - /** - * The direction of the Body's velocity, as calculated during the last step. - * This is a numeric constant value (FACING_UP, FACING_DOWN, FACING_LEFT, FACING_RIGHT). - * If the Body is moving on both axes, this describes motion on the vertical axis only. - * - * @name Phaser.Physics.Arcade.Body#facing - * @type {number} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.FACING_UP - * @see Phaser.Physics.Arcade.FACING_DOWN - * @see Phaser.Physics.Arcade.FACING_LEFT - * @see Phaser.Physics.Arcade.FACING_RIGHT - */ - this.facing = CONST.FACING_NONE; - - /** - * Whether this Body can be moved by collisions with another Body. - * - * @name Phaser.Physics.Arcade.Body#immovable - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.immovable = false; - - /** - * Sets if this Body can be pushed by another Body. - * - * A body that cannot be pushed will reflect back all of the velocity it is given to the - * colliding body. If that body is also not pushable, then the separation will be split - * between them evenly. - * - * If you want your body to never move or seperate at all, see the `setImmovable` method. - * - * By default, Dynamic Bodies are always pushable. - * - * @name Phaser.Physics.Arcade.Body#pushable - * @type {boolean} - * @default true - * @since 3.50.0 - * @see Phaser.GameObjects.Components.Pushable#setPushable - */ - this.pushable = true; - - /** - * Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity. - * - * @name Phaser.Physics.Arcade.Body#moves - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.moves = true; - - /** - * A flag disabling the default horizontal separation of colliding bodies. - * Pass your own `collideCallback` to the collider. - * - * @name Phaser.Physics.Arcade.Body#customSeparateX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateX = false; - - /** - * A flag disabling the default vertical separation of colliding bodies. - * Pass your own `collideCallback` to the collider. - * - * @name Phaser.Physics.Arcade.Body#customSeparateY - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateY = false; - - /** - * The amount of horizontal overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.Body#overlapX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapX = 0; - - /** - * The amount of vertical overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.Body#overlapY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapY = 0; - - /** - * The amount of overlap (before separation), if this Body is circular and colliding with another circular body. - * - * @name Phaser.Physics.Arcade.Body#overlapR - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapR = 0; - - /** - * Whether this Body is overlapped with another and both are not moving, on at least one axis. - * - * @name Phaser.Physics.Arcade.Body#embedded - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.embedded = false; - - /** - * Whether this Body interacts with the world boundary. - * - * @name Phaser.Physics.Arcade.Body#collideWorldBounds - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.collideWorldBounds = false; - - /** - * Whether this Body is checked for collisions and for which directions. - * You can set `checkCollision.none = true` to disable collision checks. - * - * @name Phaser.Physics.Arcade.Body#checkCollision - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; - - /** - * Whether this Body is colliding with a Body or Static Body and in which direction. - * In a collision where both bodies have zero velocity, `embedded` will be set instead. - * - * @name Phaser.Physics.Arcade.Body#touching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#blocked - * @see Phaser.Physics.Arcade.Body#embedded - */ - this.touching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This Body's `touching` value during the previous step. - * - * @name Phaser.Physics.Arcade.Body#wasTouching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#touching - */ - this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * Whether this Body is colliding with a Static Body, a tile, or the world boundary. - * In a collision with a Static Body, if this Body has zero velocity then `embedded` will be set instead. - * - * @name Phaser.Physics.Arcade.Body#blocked - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#embedded - * @see Phaser.Physics.Arcade.Body#touching - */ - this.blocked = { none: true, up: false, down: false, left: false, right: false }; - - /** - * Whether to automatically synchronize this Body's dimensions to the dimensions of its Game Object's visual bounds. - * - * @name Phaser.Physics.Arcade.Body#syncBounds - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.GameObjects.Components.GetBounds#getBounds - */ - this.syncBounds = false; - - /** - * The Body's physics type (dynamic or static). - * - * @name Phaser.Physics.Arcade.Body#physicsType - * @type {number} - * @readonly - * @default Phaser.Physics.Arcade.DYNAMIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.DYNAMIC_BODY; - - /** - * Cached horizontal scale of the Body's Game Object. - * - * @name Phaser.Physics.Arcade.Body#_sx - * @type {number} - * @private - * @since 3.0.0 - */ - this._sx = gameObject.scaleX; - - /** - * Cached vertical scale of the Body's Game Object. - * - * @name Phaser.Physics.Arcade.Body#_sy - * @type {number} - * @private - * @since 3.0.0 - */ - this._sy = gameObject.scaleY; - - /** - * The calculated change in the Body's horizontal position during the last step. - * - * @name Phaser.Physics.Arcade.Body#_dx - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._dx = 0; - - /** - * The calculated change in the Body's vertical position during the last step. - * - * @name Phaser.Physics.Arcade.Body#_dy - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._dy = 0; - - /** - * The final calculated change in the Body's horizontal position as of `postUpdate`. - * - * @name Phaser.Physics.Arcade.Body#_tx - * @type {number} - * @private - * @default 0 - * @since 3.22.0 - */ - this._tx = 0; - - /** - * The final calculated change in the Body's vertical position as of `postUpdate`. - * - * @name Phaser.Physics.Arcade.Body#_ty - * @type {number} - * @private - * @default 0 - * @since 3.22.0 - */ - this._ty = 0; - - /** - * Stores the Game Object's bounds. - * - * @name Phaser.Physics.Arcade.Body#_bounds - * @type {Phaser.Geom.Rectangle} - * @private - * @since 3.0.0 - */ - this._bounds = new Rectangle(); - }, - - /** - * Updates the Body's `transform`, `width`, `height`, and `center` from its Game Object. - * The Body's `position` isn't changed. - * - * @method Phaser.Physics.Arcade.Body#updateBounds - * @since 3.0.0 - */ - updateBounds: function () - { - var sprite = this.gameObject; - - // Container? - - var transform = this.transform; - - if (sprite.parentContainer) - { - var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2); - - transform.x = matrix.tx; - transform.y = matrix.ty; - transform.rotation = RadToDeg(matrix.rotation); - transform.scaleX = matrix.scaleX; - transform.scaleY = matrix.scaleY; - transform.displayOriginX = sprite.displayOriginX; - transform.displayOriginY = sprite.displayOriginY; - } - else - { - transform.x = sprite.x; - transform.y = sprite.y; - transform.rotation = sprite.angle; - transform.scaleX = sprite.scaleX; - transform.scaleY = sprite.scaleY; - transform.displayOriginX = sprite.displayOriginX; - transform.displayOriginY = sprite.displayOriginY; - } - - var recalc = false; - - if (this.syncBounds) - { - var b = sprite.getBounds(this._bounds); - - this.width = b.width; - this.height = b.height; - recalc = true; - } - else - { - var asx = Math.abs(transform.scaleX); - var asy = Math.abs(transform.scaleY); - - if (this._sx !== asx || this._sy !== asy) - { - this.width = this.sourceWidth * asx; - this.height = this.sourceHeight * asy; - this._sx = asx; - this._sy = asy; - recalc = true; - } - } - - if (recalc) - { - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - this.updateCenter(); - } - }, - - /** - * Updates the Body's `center` from its `position`, `width`, and `height`. - * - * @method Phaser.Physics.Arcade.Body#updateCenter - * @since 3.0.0 - */ - updateCenter: function () - { - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - }, - - /** - * Updates the Body's `position`, `width`, `height`, and `center` from its Game Object and `offset`. - * - * You don't need to call this for Dynamic Bodies, as it happens automatically during the physics step. - * But you could use it if you have modified the Body offset or Game Object transform and need to immediately - * read the Body's new `position` or `center`. - * - * To resynchronize the Body with its Game Object, use `reset()` instead. - * - * @method Phaser.Physics.Arcade.Body#updateFromGameObject - * @since 3.24.0 - */ - updateFromGameObject: function () - { - this.updateBounds(); - - var transform = this.transform; - - this.position.x = transform.x + transform.scaleX * (this.offset.x - transform.displayOriginX); - this.position.y = transform.y + transform.scaleY * (this.offset.y - transform.displayOriginY); - - this.updateCenter(); - }, - - /** - * Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states. - * - * This method is only called if the physics world is going to run a step this frame. - * - * @method Phaser.Physics.Arcade.Body#resetFlags - * @since 3.18.0 - * - * @param {boolean} [clear=false] - Set the `wasTouching` values to their defaults. - */ - resetFlags: function (clear) - { - if (clear === undefined) - { - clear = false; - } - - // Store and reset collision flags - var wasTouching = this.wasTouching; - var touching = this.touching; - var blocked = this.blocked; - - if (clear) - { - wasTouching.none = true; - wasTouching.up = false; - wasTouching.down = false; - wasTouching.left = false; - wasTouching.right = false; - } - else - { - wasTouching.none = touching.none; - wasTouching.up = touching.up; - wasTouching.down = touching.down; - wasTouching.left = touching.left; - wasTouching.right = touching.right; - } - - touching.none = true; - touching.up = false; - touching.down = false; - touching.left = false; - touching.right = false; - - blocked.none = true; - blocked.up = false; - blocked.down = false; - blocked.left = false; - blocked.right = false; - - this.overlapR = 0; - this.overlapX = 0; - this.overlapY = 0; - - this.embedded = false; - }, - - /** - * Syncs the position body position with the parent Game Object. - * - * This method is called every game frame, regardless if the world steps or not. - * - * @method Phaser.Physics.Arcade.Body#preUpdate - * @since 3.17.0 - * - * @param {boolean} willStep - Will this Body run an update as well? - * @param {number} delta - The delta time, in seconds, elapsed since the last frame. - */ - preUpdate: function (willStep, delta) - { - if (willStep) - { - this.resetFlags(); - } - - this.updateFromGameObject(); - - this.rotation = this.transform.rotation; - this.preRotation = this.rotation; - - if (this.moves) - { - this.prev.x = this.position.x; - this.prev.y = this.position.y; - this.prevFrame.x = this.position.x; - this.prevFrame.y = this.position.y; - } - - if (willStep) - { - this.update(delta); - } - }, - - /** - * Performs a single physics step and updates the body velocity, angle, speed and other properties. - * - * This method can be called multiple times per game frame, depending on the physics step rate. - * - * The results are synced back to the Game Object in `postUpdate`. - * - * @method Phaser.Physics.Arcade.Body#update - * @fires Phaser.Physics.Arcade.Events#WORLD_BOUNDS - * @since 3.0.0 - * - * @param {number} delta - The delta time, in seconds, elapsed since the last frame. - */ - update: function (delta) - { - this.prev.x = this.position.x; - this.prev.y = this.position.y; - - if (this.moves) - { - this.world.updateMotion(this, delta); - - var vx = this.velocity.x; - var vy = this.velocity.y; - - this.newVelocity.set(vx * delta, vy * delta); - - this.position.add(this.newVelocity); - - this.updateCenter(); - - this.angle = Math.atan2(vy, vx); - this.speed = Math.sqrt(vx * vx + vy * vy); - - // Now the update will throw collision checks at the Body - // And finally we'll integrate the new position back to the Sprite in postUpdate - - if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) - { - this.world.emit(Events.WORLD_BOUNDS, this, this.blocked.up, this.blocked.down, this.blocked.left, this.blocked.right); - } - } - - this._dx = this.position.x - this.prev.x; - this._dy = this.position.y - this.prev.y; - }, - - /** - * Feeds the Body results back into the parent Game Object. - * - * This method is called every game frame, regardless if the world steps or not. - * - * @method Phaser.Physics.Arcade.Body#postUpdate - * @since 3.0.0 - */ - postUpdate: function () - { - var dx = this.position.x - this.prevFrame.x; - var dy = this.position.y - this.prevFrame.y; - - if (this.moves) - { - var mx = this.deltaMax.x; - var my = this.deltaMax.y; - - if (mx !== 0 && dx !== 0) - { - if (dx < 0 && dx < -mx) - { - dx = -mx; - } - else if (dx > 0 && dx > mx) - { - dx = mx; - } - } - - if (my !== 0 && dy !== 0) - { - if (dy < 0 && dy < -my) - { - dy = -my; - } - else if (dy > 0 && dy > my) - { - dy = my; - } - } - - this.gameObject.x += dx; - this.gameObject.y += dy; - } - - if (dx < 0) - { - this.facing = CONST.FACING_LEFT; - } - else if (dx > 0) - { - this.facing = CONST.FACING_RIGHT; - } - - if (dy < 0) - { - this.facing = CONST.FACING_UP; - } - else if (dy > 0) - { - this.facing = CONST.FACING_DOWN; - } - - if (this.allowRotation) - { - this.gameObject.angle += this.deltaZ(); - } - - this._tx = dx; - this._ty = dy; - }, - - /** - * Sets a custom collision boundary rectangle. Use if you want to have a custom - * boundary instead of the world boundaries. - * - * @method Phaser.Physics.Arcade.Body#setBoundsRectangle - * @since 3.20 - * - * @param {?Phaser.Geom.Rectangle} [bounds] - The new boundary rectangle. Pass `null` to use the World bounds. - * - * @return {this} This Body object. - */ - setBoundsRectangle: function (bounds) - { - this.customBoundsRectangle = (!bounds) ? this.world.bounds : bounds; - - return this; - }, - - /** - * Checks for collisions between this Body and the world boundary and separates them. - * - * @method Phaser.Physics.Arcade.Body#checkWorldBounds - * @since 3.0.0 - * - * @return {boolean} True if this Body is colliding with the world boundary. - */ - checkWorldBounds: function () - { - var pos = this.position; - var bounds = this.customBoundsRectangle; - var check = this.world.checkCollision; - - var bx = (this.worldBounce) ? -this.worldBounce.x : -this.bounce.x; - var by = (this.worldBounce) ? -this.worldBounce.y : -this.bounce.y; - - var wasSet = false; - - if (pos.x < bounds.x && check.left) - { - pos.x = bounds.x; - this.velocity.x *= bx; - this.blocked.left = true; - wasSet = true; - } - else if (this.right > bounds.right && check.right) - { - pos.x = bounds.right - this.width; - this.velocity.x *= bx; - this.blocked.right = true; - wasSet = true; - } - - if (pos.y < bounds.y && check.up) - { - pos.y = bounds.y; - this.velocity.y *= by; - this.blocked.up = true; - wasSet = true; - } - else if (this.bottom > bounds.bottom && check.down) - { - pos.y = bounds.bottom - this.height; - this.velocity.y *= by; - this.blocked.down = true; - wasSet = true; - } - - if (wasSet) - { - this.blocked.none = false; - this.updateCenter(); - } - - return wasSet; - }, - - /** - * Sets the offset of the Body's position from its Game Object's position. - * The Body's `position` isn't changed until the next `preUpdate`. - * - * @method Phaser.Physics.Arcade.Body#setOffset - * @since 3.0.0 - * - * @param {number} x - The horizontal offset, in source pixels. - * @param {number} [y=x] - The vertical offset, in source pixels. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setOffset: function (x, y) - { - if (y === undefined) { y = x; } - - this.offset.set(x, y); - - return this; - }, - - /** - * Sizes and positions this Body, as a rectangle. - * Modifies the Body `offset` if `center` is true (the default). - * Resets the width and height to match current frame, if no width and height provided and a frame is found. - * - * @method Phaser.Physics.Arcade.Body#setSize - * @since 3.0.0 - * - * @param {number} [width] - The width of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. - * @param {number} [height] - The height of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. - * @param {boolean} [center=true] - Modify the Body's `offset`, placing the Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setSize: function (width, height, center) - { - if (center === undefined) { center = true; } - - var gameObject = this.gameObject; - - if (!width && gameObject.frame) - { - width = gameObject.frame.realWidth; - } - - if (!height && gameObject.frame) - { - height = gameObject.frame.realHeight; - } - - this.sourceWidth = width; - this.sourceHeight = height; - - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.updateCenter(); - - if (center && gameObject.getCenter) - { - var ox = (gameObject.width - width) / 2; - var oy = (gameObject.height - height) / 2; - - this.offset.set(ox, oy); - } - - this.isCircle = false; - this.radius = 0; - - return this; - }, - - /** - * Sizes and positions this Body, as a circle. - * - * @method Phaser.Physics.Arcade.Body#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the Body, in source pixels. - * @param {number} [offsetX] - The horizontal offset of the Body from its Game Object, in source pixels. - * @param {number} [offsetY] - The vertical offset of the Body from its Game Object, in source pixels. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setCircle: function (radius, offsetX, offsetY) - { - if (offsetX === undefined) { offsetX = this.offset.x; } - if (offsetY === undefined) { offsetY = this.offset.y; } - - if (radius > 0) - { - this.isCircle = true; - this.radius = radius; - - this.sourceWidth = radius * 2; - this.sourceHeight = radius * 2; - - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.offset.set(offsetX, offsetY); - - this.updateCenter(); - } - else - { - this.isCircle = false; - } - - return this; - }, - - /** - * Sets this Body's parent Game Object to the given coordinates and resets this Body at the new coordinates. - * If the Body had any velocity or acceleration it is lost as a result of calling this. - * - * @method Phaser.Physics.Arcade.Body#reset - * @since 3.0.0 - * - * @param {number} x - The horizontal position to place the Game Object. - * @param {number} y - The vertical position to place the Game Object. - */ - reset: function (x, y) - { - this.stop(); - - var gameObject = this.gameObject; - - gameObject.setPosition(x, y); - - if (gameObject.getTopLeft) - { - gameObject.getTopLeft(this.position); - } - else - { - this.position.set(x, y); - } - - this.prev.copy(this.position); - this.prevFrame.copy(this.position); - - this.rotation = gameObject.angle; - this.preRotation = gameObject.angle; - - this.updateBounds(); - this.updateCenter(); - this.resetFlags(true); - }, - - /** - * Sets acceleration, velocity, and speed to zero. - * - * @method Phaser.Physics.Arcade.Body#stop - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - stop: function () - { - this.velocity.set(0); - this.acceleration.set(0); - this.speed = 0; - this.angularVelocity = 0; - this.angularAcceleration = 0; - - return this; - }, - - /** - * Copies the coordinates of this Body's edges into an object. - * - * @method Phaser.Physics.Arcade.Body#getBounds - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into. - * - * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}. - */ - getBounds: function (obj) - { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; - - return obj; - }, - - /** - * Tests if the coordinates are within this Body. - * - * @method Phaser.Physics.Arcade.Body#hitTest - * @since 3.0.0 - * - * @param {number} x - The horizontal coordinate. - * @param {number} y - The vertical coordinate. - * - * @return {boolean} True if (x, y) is within this Body. - */ - hitTest: function (x, y) - { - if (!this.isCircle) - { - return RectangleContains(this, x, y); - } - - // Check if x/y are within the bounds first - if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) - { - var dx = (this.center.x - x) * (this.center.x - x); - var dy = (this.center.y - y) * (this.center.y - y); - - return (dx + dy) <= (this.radius * this.radius); - } - - return false; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving down. - * - * @method Phaser.Physics.Arcade.Body#onFloor - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onFloor: function () - { - return this.blocked.down; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving up. - * - * @method Phaser.Physics.Arcade.Body#onCeiling - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onCeiling: function () - { - return this.blocked.up; - }, - - /** - * Whether this Body is touching a tile or the world boundary while moving left or right. - * - * @method Phaser.Physics.Arcade.Body#onWall - * @since 3.0.0 - * @see Phaser.Physics.Arcade.Body#blocked - * - * @return {boolean} True if touching. - */ - onWall: function () - { - return (this.blocked.left || this.blocked.right); - }, - - /** - * The absolute (non-negative) change in this Body's horizontal position from the previous step. - * - * @method Phaser.Physics.Arcade.Body#deltaAbsX - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaAbsX: function () - { - return (this._dx > 0) ? this._dx : -this._dx; - }, - - /** - * The absolute (non-negative) change in this Body's vertical position from the previous step. - * - * @method Phaser.Physics.Arcade.Body#deltaAbsY - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaAbsY: function () - { - return (this._dy > 0) ? this._dy : -this._dy; - }, - - /** - * The change in this Body's horizontal position from the previous step. - * This value is set during the Body's update phase. - * - * As a Body can update multiple times per step this may not hold the final - * delta value for the Body. In this case, please see the `deltaXFinal` method. - * - * @method Phaser.Physics.Arcade.Body#deltaX - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaX: function () - { - return this._dx; - }, - - /** - * The change in this Body's vertical position from the previous step. - * This value is set during the Body's update phase. - * - * As a Body can update multiple times per step this may not hold the final - * delta value for the Body. In this case, please see the `deltaYFinal` method. - * - * @method Phaser.Physics.Arcade.Body#deltaY - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaY: function () - { - return this._dy; - }, - - /** - * The change in this Body's horizontal position from the previous game update. - * - * This value is set during the `postUpdate` phase and takes into account the - * `deltaMax` and final position of the Body. - * - * Because this value is not calculated until `postUpdate`, you must listen for it - * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will - * not be calculated by that point. If you _do_ use these values in `update` they - * will represent the delta from the _previous_ game frame. - * - * @method Phaser.Physics.Arcade.Body#deltaXFinal - * @since 3.22.0 - * - * @return {number} The final delta x value. - */ - deltaXFinal: function () - { - return this._tx; - }, - - /** - * The change in this Body's vertical position from the previous game update. - * - * This value is set during the `postUpdate` phase and takes into account the - * `deltaMax` and final position of the Body. - * - * Because this value is not calculated until `postUpdate`, you must listen for it - * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will - * not be calculated by that point. If you _do_ use these values in `update` they - * will represent the delta from the _previous_ game frame. - * - * @method Phaser.Physics.Arcade.Body#deltaYFinal - * @since 3.22.0 - * - * @return {number} The final delta y value. - */ - deltaYFinal: function () - { - return this._ty; - }, - - /** - * The change in this Body's rotation from the previous step, in degrees. - * - * @method Phaser.Physics.Arcade.Body#deltaZ - * @since 3.0.0 - * - * @return {number} The delta value. - */ - deltaZ: function () - { - return this.rotation - this.preRotation; - }, - - /** - * Disables this Body and marks it for deletion by the simulation. - * - * @method Phaser.Physics.Arcade.Body#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enable = false; - - if (this.world) - { - this.world.pendingDestroy.set(this); - } - }, - - /** - * Draws this Body and its velocity, if enabled. - * - * @method Phaser.Physics.Arcade.Body#drawDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to draw on. - */ - drawDebug: function (graphic) - { - var pos = this.position; - - var x = pos.x + this.halfWidth; - var y = pos.y + this.halfHeight; - - if (this.debugShowBody) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor); - - if (this.isCircle) - { - graphic.strokeCircle(x, y, this.width / 2); - } - else - { - // Only draw the sides where checkCollision is true, similar to debugger in layer - if (this.checkCollision.up) - { - graphic.lineBetween(pos.x, pos.y, pos.x + this.width, pos.y); - } - - if (this.checkCollision.right) - { - graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); - } - - if (this.checkCollision.down) - { - graphic.lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height); - } - - if (this.checkCollision.left) - { - graphic.lineBetween(pos.x, pos.y, pos.x, pos.y + this.height); - } - } - } - - if (this.debugShowVelocity) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.world.defaults.velocityDebugColor, 1); - graphic.lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2); - } - }, - - /** - * Whether this Body will be drawn to the debug display. - * - * @method Phaser.Physics.Arcade.Body#willDrawDebug - * @since 3.0.0 - * - * @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled. - */ - willDrawDebug: function () - { - return (this.debugShowBody || this.debugShowVelocity); - }, - - /** - * Sets whether this Body collides with the world boundary. - * - * Optionally also sets the World Bounce and `onWorldBounds` values. - * - * @method Phaser.Physics.Arcade.Body#setCollideWorldBounds - * @since 3.0.0 - * - * @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`. - * @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value. - * @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value. - * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setCollideWorldBounds: function (value, bounceX, bounceY, onWorldBounds) - { - if (value === undefined) { value = true; } - - this.collideWorldBounds = value; - - var setBounceX = (bounceX !== undefined); - var setBounceY = (bounceY !== undefined); - - if (setBounceX || setBounceY) - { - if (!this.worldBounce) - { - this.worldBounce = new Vector2(); - } - - if (setBounceX) - { - this.worldBounce.x = bounceX; - } - - if (setBounceY) - { - this.worldBounce.y = bounceY; - } - } - - if (onWorldBounds !== undefined) - { - this.onWorldBounds = onWorldBounds; - } - - return this; - }, - - /** - * Sets the Body's velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity, in pixels per second. - * @param {number} [y=x] - The vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocity: function (x, y) - { - this.velocity.set(x, y); - - x = this.velocity.x; - y = this.velocity.y; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's horizontal velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocityX - * @since 3.0.0 - * - * @param {number} value - The velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocityX: function (value) - { - this.velocity.x = value; - - var x = value; - var y = this.velocity.y; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's vertical velocity. - * - * @method Phaser.Physics.Arcade.Body#setVelocityY - * @since 3.0.0 - * - * @param {number} value - The velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setVelocityY: function (value) - { - this.velocity.y = value; - - var x = this.velocity.x; - var y = value; - - this.speed = Math.sqrt(x * x + y * y); - - return this; - }, - - /** - * Sets the Body's maximum velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocity - * @since 3.10.0 - * - * @param {number} x - The horizontal velocity, in pixels per second. - * @param {number} [y=x] - The vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocity: function (x, y) - { - this.maxVelocity.set(x, y); - - return this; - }, - - /** - * Sets the Body's maximum horizontal velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocityX - * @since 3.50.0 - * - * @param {number} value - The maximum horizontal velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocityX: function (value) - { - this.maxVelocity.x = value; - - return this; - }, - - /** - * Sets the Body's maximum vertical velocity. - * - * @method Phaser.Physics.Arcade.Body#setMaxVelocityY - * @since 3.50.0 - * - * @param {number} value - The maximum vertical velocity, in pixels per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxVelocityY: function (value) - { - this.maxVelocity.y = value; - - return this; - }, - - /** - * Sets the maximum speed the Body can move. - * - * @method Phaser.Physics.Arcade.Body#setMaxSpeed - * @since 3.16.0 - * - * @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMaxSpeed: function (value) - { - this.maxSpeed = value; - - return this; - }, - - /** - * Sets the Body's bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounce - * @since 3.0.0 - * - * @param {number} x - The horizontal bounce, relative to 1. - * @param {number} y - The vertical bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounce: function (x, y) - { - this.bounce.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounceX - * @since 3.0.0 - * - * @param {number} value - The bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounceX: function (value) - { - this.bounce.x = value; - - return this; - }, - - /** - * Sets the Body's vertical bounce. - * - * @method Phaser.Physics.Arcade.Body#setBounceY - * @since 3.0.0 - * - * @param {number} value - The bounce, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setBounceY: function (value) - { - this.bounce.y = value; - - return this; - }, - - /** - * Sets the Body's acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAcceleration - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAcceleration: function (x, y) - { - this.acceleration.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAccelerationX - * @since 3.0.0 - * - * @param {number} value - The acceleration, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAccelerationX: function (value) - { - this.acceleration.x = value; - - return this; - }, - - /** - * Sets the Body's vertical acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAccelerationY - * @since 3.0.0 - * - * @param {number} value - The acceleration, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAccelerationY: function (value) - { - this.acceleration.y = value; - - return this; - }, - - /** - * Enables or disables drag. - * - * @method Phaser.Physics.Arcade.Body#setAllowDrag - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowDrag - * - * @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowDrag: function (value) - { - if (value === undefined) { value = true; } - - this.allowDrag = value; - - return this; - }, - - /** - * Enables or disables gravity's effect on this Body. - * - * @method Phaser.Physics.Arcade.Body#setAllowGravity - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowGravity - * - * @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowGravity: function (value) - { - if (value === undefined) { value = true; } - - this.allowGravity = value; - - return this; - }, - - /** - * Enables or disables rotation. - * - * @method Phaser.Physics.Arcade.Body#setAllowRotation - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowRotation - * - * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAllowRotation: function (value) - { - if (value === undefined) { value = true; } - - this.allowRotation = value; - - return this; - }, - - /** - * Sets the Body's drag. - * - * @method Phaser.Physics.Arcade.Body#setDrag - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDrag: function (x, y) - { - this.drag.set(x, y); - - return this; - }, - - /** - * If this Body is using `drag` for deceleration this property controls how the drag is applied. - * If set to `true` drag will use a damping effect rather than a linear approach. If you are - * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in - * the game Asteroids) then you will get a far smoother and more visually correct deceleration - * by using damping, avoiding the axis-drift that is prone with linear deceleration. - * - * If you enable this property then you should use far smaller `drag` values than with linear, as - * they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow - * deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately. - * - * @method Phaser.Physics.Arcade.Body#setDamping - * @since 3.50.0 - * - * @param {boolean} value - `true` to use damping, or `false` to use drag. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDamping: function (value) - { - this.useDamping = value; - - return this; - }, - - /** - * Sets the Body's horizontal drag. - * - * @method Phaser.Physics.Arcade.Body#setDragX - * @since 3.0.0 - * - * @param {number} value - The drag, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDragX: function (value) - { - this.drag.x = value; - - return this; - }, - - /** - * Sets the Body's vertical drag. - * - * @method Phaser.Physics.Arcade.Body#setDragY - * @since 3.0.0 - * - * @param {number} value - The drag, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setDragY: function (value) - { - this.drag.y = value; - - return this; - }, - - /** - * Sets the Body's gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravity - * @since 3.0.0 - * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravity: function (x, y) - { - this.gravity.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravityX - * @since 3.0.0 - * - * @param {number} value - The gravity, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravityX: function (value) - { - this.gravity.x = value; - - return this; - }, - - /** - * Sets the Body's vertical gravity. - * - * @method Phaser.Physics.Arcade.Body#setGravityY - * @since 3.0.0 - * - * @param {number} value - The gravity, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setGravityY: function (value) - { - this.gravity.y = value; - - return this; - }, - - /** - * Sets the Body's friction. - * - * @method Phaser.Physics.Arcade.Body#setFriction - * @since 3.0.0 - * - * @param {number} x - The horizontal component, relative to 1. - * @param {number} y - The vertical component, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFriction: function (x, y) - { - this.friction.set(x, y); - - return this; - }, - - /** - * Sets the Body's horizontal friction. - * - * @method Phaser.Physics.Arcade.Body#setFrictionX - * @since 3.0.0 - * - * @param {number} value - The friction value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFrictionX: function (value) - { - this.friction.x = value; - - return this; - }, - - /** - * Sets the Body's vertical friction. - * - * @method Phaser.Physics.Arcade.Body#setFrictionY - * @since 3.0.0 - * - * @param {number} value - The friction value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setFrictionY: function (value) - { - this.friction.y = value; - - return this; - }, - - /** - * Sets the Body's angular velocity. - * - * @method Phaser.Physics.Arcade.Body#setAngularVelocity - * @since 3.0.0 - * - * @param {number} value - The velocity, in degrees per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularVelocity: function (value) - { - this.angularVelocity = value; - - return this; - }, - - /** - * Sets the Body's angular acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAngularAcceleration - * @since 3.0.0 - * - * @param {number} value - The acceleration, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularAcceleration: function (value) - { - this.angularAcceleration = value; - - return this; - }, - - /** - * Sets the Body's angular drag. - * - * @method Phaser.Physics.Arcade.Body#setAngularDrag - * @since 3.0.0 - * - * @param {number} value - The drag, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setAngularDrag: function (value) - { - this.angularDrag = value; - - return this; - }, - - /** - * Sets the Body's mass. - * - * @method Phaser.Physics.Arcade.Body#setMass - * @since 3.0.0 - * - * @param {number} value - The mass value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setMass: function (value) - { - this.mass = value; - - return this; - }, - - /** - * Sets the Body's `immovable` property. - * - * @method Phaser.Physics.Arcade.Body#setImmovable - * @since 3.0.0 - * - * @param {boolean} [value=true] - The value to assign to `immovable`. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setImmovable: function (value) - { - if (value === undefined) { value = true; } - - this.immovable = value; - - return this; - }, - - /** - * Sets the Body's `enable` property. - * - * @method Phaser.Physics.Arcade.Body#setEnable - * @since 3.15.0 - * - * @param {boolean} [value=true] - The value to assign to `enable`. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. - */ - setEnable: function (value) - { - if (value === undefined) { value = true; } - - this.enable = value; - - return this; - }, - - /** - * This is an internal handler, called by the `ProcessX` function as part - * of the collision step. You should almost never call this directly. - * - * @method Phaser.Physics.Arcade.Body#processX - * @since 3.50.0 - * - * @param {number} x - The amount to add to the Body position. - * @param {number} [vx] - The amount to add to the Body velocity. - * @param {boolean} [left] - Set the blocked.left value? - * @param {boolean} [right] - Set the blocked.right value? - */ - processX: function (x, vx, left, right) - { - this.x += x; - - this.updateCenter(); - - if (vx !== null) - { - this.velocity.x = vx; - } - - var blocked = this.blocked; - - if (left) - { - blocked.left = true; - } - - if (right) - { - blocked.right = true; - } - }, - - /** - * This is an internal handler, called by the `ProcessY` function as part - * of the collision step. You should almost never call this directly. - * - * @method Phaser.Physics.Arcade.Body#processY - * @since 3.50.0 - * - * @param {number} y - The amount to add to the Body position. - * @param {number} [vy] - The amount to add to the Body velocity. - * @param {boolean} [up] - Set the blocked.up value? - * @param {boolean} [down] - Set the blocked.down value? - */ - processY: function (y, vy, up, down) - { - this.y += y; - - this.updateCenter(); - - if (vy !== null) - { - this.velocity.y = vy; - } - - var blocked = this.blocked; - - if (up) - { - blocked.up = true; - } - - if (down) - { - blocked.down = true; - } - }, - - /** - * The Bodys horizontal position (left edge). - * - * @name Phaser.Physics.Arcade.Body#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.position.x = value; - } - - }, - - /** - * The Bodys vertical position (top edge). - * - * @name Phaser.Physics.Arcade.Body#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.position.y = value; - } - - }, - - /** - * The left edge of the Body. Identical to x. - * - * @name Phaser.Physics.Arcade.Body#left - * @type {number} - * @readonly - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.position.x; - } - - }, - - /** - * The right edge of the Body. - * - * @name Phaser.Physics.Arcade.Body#right - * @type {number} - * @readonly - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.position.x + this.width; - } - - }, - - /** - * The top edge of the Body. Identical to y. - * - * @name Phaser.Physics.Arcade.Body#top - * @type {number} - * @readonly - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.position.y; - } - - }, - - /** - * The bottom edge of this Body. - * - * @name Phaser.Physics.Arcade.Body#bottom - * @type {number} - * @readonly - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.position.y + this.height; - } - - } - -}); - -module.exports = Body; - - -/***/ }), -/* 506 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects - * every step. If a collision, or overlap, occurs it will invoke the given callbacks. - * - * @class Collider - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade physics World that will manage the collisions. - * @param {boolean} overlapOnly - Whether to check for collisions or overlap. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. - * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. - * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. - * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. - * @param {any} callbackContext - The scope in which to call the callbacks. - */ -var Collider = new Class({ - - initialize: - - function Collider (world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) - { - /** - * The world in which the bodies will collide. - * - * @name Phaser.Physics.Arcade.Collider#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The name of the collider (unused by Phaser). - * - * @name Phaser.Physics.Arcade.Collider#name - * @type {string} - * @since 3.1.0 - */ - this.name = ''; - - /** - * Whether the collider is active. - * - * @name Phaser.Physics.Arcade.Collider#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; - - /** - * Whether to check for collisions or overlaps. - * - * @name Phaser.Physics.Arcade.Collider#overlapOnly - * @type {boolean} - * @since 3.0.0 - */ - this.overlapOnly = overlapOnly; - - /** - * The first object to check for collision. - * - * @name Phaser.Physics.Arcade.Collider#object1 - * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} - * @since 3.0.0 - */ - this.object1 = object1; - - /** - * The second object to check for collision. - * - * @name Phaser.Physics.Arcade.Collider#object2 - * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} - * @since 3.0.0 - */ - this.object2 = object2; - - /** - * The callback to invoke when the two objects collide. - * - * @name Phaser.Physics.Arcade.Collider#collideCallback - * @type {ArcadePhysicsCallback} - * @since 3.0.0 - */ - this.collideCallback = collideCallback; - - /** - * If a processCallback exists it must return true or collision checking will be skipped. - * - * @name Phaser.Physics.Arcade.Collider#processCallback - * @type {ArcadePhysicsCallback} - * @since 3.0.0 - */ - this.processCallback = processCallback; - - /** - * The context the collideCallback and processCallback will run in. - * - * @name Phaser.Physics.Arcade.Collider#callbackContext - * @type {object} - * @since 3.0.0 - */ - this.callbackContext = callbackContext; - }, - - /** - * A name for the Collider. - * - * Phaser does not use this value, it's for your own reference. - * - * @method Phaser.Physics.Arcade.Collider#setName - * @since 3.1.0 - * - * @param {string} name - The name to assign to the Collider. - * - * @return {Phaser.Physics.Arcade.Collider} This Collider instance. - */ - setName: function (name) - { - this.name = name; - - return this; - }, - - /** - * Called by World as part of its step processing, initial operation of collision checking. - * - * @method Phaser.Physics.Arcade.Collider#update - * @since 3.0.0 - */ - update: function () - { - this.world.collideObjects( - this.object1, - this.object2, - this.collideCallback, - this.processCallback, - this.callbackContext, - this.overlapOnly - ); - }, - - /** - * Removes Collider from World and disposes of its resources. - * - * @method Phaser.Physics.Arcade.Collider#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.world.removeCollider(this); - - this.active = false; - - this.world = null; - - this.object1 = null; - this.object2 = null; - - this.collideCallback = null; - this.processCallback = null; - this.callbackContext = null; - } - -}); - -module.exports = Collider; - - -/***/ }), -/* 507 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTilesWithin = __webpack_require__(26); -var Vector2 = __webpack_require__(3); - -var pointStart = new Vector2(); -var pointEnd = new Vector2(); - -/** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * @function Phaser.Tilemaps.Components.GetTilesWithinWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} filteringOptions - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when factoring in which tiles to return. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. - */ -var GetTilesWithinWorldXY = function (worldX, worldY, width, height, filteringOptions, camera, layer) -{ - var worldToTileXY = layer.tilemapLayer.tilemap._convert.WorldToTileXY; - - // Top left corner of the rect, rounded down to include partial tiles - worldToTileXY(worldX, worldY, true, pointStart, camera, layer); - - var xStart = pointStart.x; - var yStart = pointStart.y; - - // Bottom right corner of the rect, rounded up to include partial tiles - worldToTileXY(worldX + width, worldY + height, false, pointEnd, camera, layer); - - var xEnd = Math.ceil(pointEnd.x); - var yEnd = Math.ceil(pointEnd.y); - - return GetTilesWithin(xStart, yStart, xEnd - xStart, yEnd - yStart, filteringOptions, layer); -}; - -module.exports = GetTilesWithinWorldXY; - - -/***/ }), -/* 508 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * A function to process the collision callbacks between a single tile and an Arcade Physics enabled Game Object. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileCallbacks - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.Tile} tile - The Tile to process. - * @param {Phaser.GameObjects.Sprite} sprite - The Game Object to process with the Tile. - * - * @return {boolean} The result of the callback, `true` for further processing, or `false` to skip this pair. - */ -var ProcessTileCallbacks = function (tile, sprite) -{ - // Tile callbacks take priority over layer level callbacks - if (tile.collisionCallback) - { - return !tile.collisionCallback.call(tile.collisionCallbackContext, sprite, tile); - } - else if (tile.layer.callbacks[tile.index]) - { - return !tile.layer.callbacks[tile.index].callback.call( - tile.layer.callbacks[tile.index].callbackContext, sprite, tile - ); - } - - return true; -}; - -module.exports = ProcessTileCallbacks; - - -/***/ }), -/* 509 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Vladimir Agafonkin - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var quickselect = __webpack_require__(414); - -/** - * @classdesc - * RBush is a high-performance JavaScript library for 2D spatial indexing of points and rectangles. - * It's based on an optimized R-tree data structure with bulk insertion support. - * - * Spatial index is a special data structure for points and rectangles that allows you to perform queries like - * "all items within this bounding box" very efficiently (e.g. hundreds of times faster than looping over all items). - * - * This version of RBush uses a fixed min/max accessor structure of `[ '.left', '.top', '.right', '.bottom' ]`. - * This is to avoid the eval like function creation that the original library used, which caused CSP policy violations. - * - * rbush is forked from https://github.com/mourner/rbush by Vladimir Agafonkin - * - * @class RTree - * @memberof Phaser.Structs - * @constructor - * @since 3.0.0 - */ - -function rbush (maxEntries) -{ - var format = [ '.left', '.top', '.right', '.bottom' ]; - - if (!(this instanceof rbush)) return new rbush(maxEntries, format); - - // max entries in a node is 9 by default; min node fill is 40% for best performance - this._maxEntries = Math.max(4, maxEntries || 9); - this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); - - this.clear(); -} - -rbush.prototype = { - - all: function () - { - return this._all(this.data, []); - }, - - search: function (bbox) - { - var node = this.data, - result = [], - toBBox = this.toBBox; - - if (!intersects(bbox, node)) return result; - - var nodesToSearch = [], - i, len, child, childBBox; - - while (node) { - for (i = 0, len = node.children.length; i < len; i++) { - - child = node.children[i]; - childBBox = node.leaf ? toBBox(child) : child; - - if (intersects(bbox, childBBox)) { - if (node.leaf) result.push(child); - else if (contains(bbox, childBBox)) this._all(child, result); - else nodesToSearch.push(child); - } - } - node = nodesToSearch.pop(); - } - - return result; - }, - - collides: function (bbox) - { - var node = this.data, - toBBox = this.toBBox; - - if (!intersects(bbox, node)) return false; - - var nodesToSearch = [], - i, len, child, childBBox; - - while (node) { - for (i = 0, len = node.children.length; i < len; i++) { - - child = node.children[i]; - childBBox = node.leaf ? toBBox(child) : child; - - if (intersects(bbox, childBBox)) { - if (node.leaf || contains(bbox, childBBox)) return true; - nodesToSearch.push(child); - } - } - node = nodesToSearch.pop(); - } - - return false; - }, - - load: function (data) - { - if (!(data && data.length)) return this; - - if (data.length < this._minEntries) { - for (var i = 0, len = data.length; i < len; i++) { - this.insert(data[i]); - } - return this; - } - - // recursively build the tree with the given data from scratch using OMT algorithm - var node = this._build(data.slice(), 0, data.length - 1, 0); - - if (!this.data.children.length) { - // save as is if tree is empty - this.data = node; - - } else if (this.data.height === node.height) { - // split root if trees have the same height - this._splitRoot(this.data, node); - - } else { - if (this.data.height < node.height) { - // swap trees if inserted one is bigger - var tmpNode = this.data; - this.data = node; - node = tmpNode; - } - - // insert the small tree into the large tree at appropriate level - this._insert(node, this.data.height - node.height - 1, true); - } - - return this; - }, - - insert: function (item) - { - if (item) this._insert(item, this.data.height - 1); - return this; - }, - - clear: function () - { - this.data = createNode([]); - return this; - }, - - remove: function (item, equalsFn) - { - if (!item) return this; - - var node = this.data, - bbox = this.toBBox(item), - path = [], - indexes = [], - i, parent, index, goingUp; - - // depth-first iterative tree traversal - while (node || path.length) { - - if (!node) { // go up - node = path.pop(); - parent = path[path.length - 1]; - i = indexes.pop(); - goingUp = true; - } - - if (node.leaf) { // check current node - index = findItem(item, node.children, equalsFn); - - if (index !== -1) { - // item found, remove the item and condense tree upwards - node.children.splice(index, 1); - path.push(node); - this._condense(path); - return this; - } - } - - if (!goingUp && !node.leaf && contains(node, bbox)) { // go down - path.push(node); - indexes.push(i); - i = 0; - parent = node; - node = node.children[0]; - - } else if (parent) { // go right - i++; - node = parent.children[i]; - goingUp = false; - - } else node = null; // nothing found - } - - return this; - }, - - toBBox: function (item) { return item; }, - - compareMinX: compareNodeMinX, - compareMinY: compareNodeMinY, - - toJSON: function () { return this.data; }, - - fromJSON: function (data) - { - this.data = data; - return this; - }, - - _all: function (node, result) - { - var nodesToSearch = []; - while (node) { - if (node.leaf) result.push.apply(result, node.children); - else nodesToSearch.push.apply(nodesToSearch, node.children); - - node = nodesToSearch.pop(); - } - return result; - }, - - _build: function (items, left, right, height) - { - var N = right - left + 1, - M = this._maxEntries, - node; - - if (N <= M) { - // reached leaf level; return leaf - node = createNode(items.slice(left, right + 1)); - calcBBox(node, this.toBBox); - return node; - } - - if (!height) { - // target height of the bulk-loaded tree - height = Math.ceil(Math.log(N) / Math.log(M)); - - // target number of root entries to maximize storage utilization - M = Math.ceil(N / Math.pow(M, height - 1)); - } - - node = createNode([]); - node.leaf = false; - node.height = height; - - // split the items into M mostly square tiles - - var N2 = Math.ceil(N / M), - N1 = N2 * Math.ceil(Math.sqrt(M)), - i, j, right2, right3; - - multiSelect(items, left, right, N1, this.compareMinX); - - for (i = left; i <= right; i += N1) { - - right2 = Math.min(i + N1 - 1, right); - - multiSelect(items, i, right2, N2, this.compareMinY); - - for (j = i; j <= right2; j += N2) { - - right3 = Math.min(j + N2 - 1, right2); - - // pack each entry recursively - node.children.push(this._build(items, j, right3, height - 1)); - } - } - - calcBBox(node, this.toBBox); - - return node; - }, - - _chooseSubtree: function (bbox, node, level, path) - { - var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; - - while (true) { - path.push(node); - - if (node.leaf || path.length - 1 === level) break; - - minArea = minEnlargement = Infinity; - - for (i = 0, len = node.children.length; i < len; i++) { - child = node.children[i]; - area = bboxArea(child); - enlargement = enlargedArea(bbox, child) - area; - - // choose entry with the least area enlargement - if (enlargement < minEnlargement) { - minEnlargement = enlargement; - minArea = area < minArea ? area : minArea; - targetNode = child; - - } else if (enlargement === minEnlargement) { - // otherwise choose one with the smallest area - if (area < minArea) { - minArea = area; - targetNode = child; - } - } - } - - node = targetNode || node.children[0]; - } - - return node; - }, - - _insert: function (item, level, isNode) - { - var toBBox = this.toBBox, - bbox = isNode ? item : toBBox(item), - insertPath = []; - - // find the best node for accommodating the item, saving all nodes along the path too - var node = this._chooseSubtree(bbox, this.data, level, insertPath); - - // put the item into the node - node.children.push(item); - extend(node, bbox); - - // split on node overflow; propagate upwards if necessary - while (level >= 0) { - if (insertPath[level].children.length > this._maxEntries) { - this._split(insertPath, level); - level--; - } else break; - } - - // adjust bboxes along the insertion path - this._adjustParentBBoxes(bbox, insertPath, level); - }, - - // split overflowed node into two - _split: function (insertPath, level) - { - var node = insertPath[level], - M = node.children.length, - m = this._minEntries; - - this._chooseSplitAxis(node, m, M); - - var splitIndex = this._chooseSplitIndex(node, m, M); - - var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); - newNode.height = node.height; - newNode.leaf = node.leaf; - - calcBBox(node, this.toBBox); - calcBBox(newNode, this.toBBox); - - if (level) insertPath[level - 1].children.push(newNode); - else this._splitRoot(node, newNode); - }, - - _splitRoot: function (node, newNode) - { - // split root node - this.data = createNode([node, newNode]); - this.data.height = node.height + 1; - this.data.leaf = false; - calcBBox(this.data, this.toBBox); - }, - - _chooseSplitIndex: function (node, m, M) - { - var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; - - minOverlap = minArea = Infinity; - - for (i = m; i <= M - m; i++) { - bbox1 = distBBox(node, 0, i, this.toBBox); - bbox2 = distBBox(node, i, M, this.toBBox); - - overlap = intersectionArea(bbox1, bbox2); - area = bboxArea(bbox1) + bboxArea(bbox2); - - // choose distribution with minimum overlap - if (overlap < minOverlap) { - minOverlap = overlap; - index = i; - - minArea = area < minArea ? area : minArea; - - } else if (overlap === minOverlap) { - // otherwise choose distribution with minimum area - if (area < minArea) { - minArea = area; - index = i; - } - } - } - - return index; - }, - - // sorts node children by the best axis for split - _chooseSplitAxis: function (node, m, M) - { - var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, - compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, - xMargin = this._allDistMargin(node, m, M, compareMinX), - yMargin = this._allDistMargin(node, m, M, compareMinY); - - // if total distributions margin value is minimal for x, sort by minX, - // otherwise it's already sorted by minY - if (xMargin < yMargin) node.children.sort(compareMinX); - }, - - // total margin of all possible split distributions where each node is at least m full - _allDistMargin: function (node, m, M, compare) - { - node.children.sort(compare); - - var toBBox = this.toBBox, - leftBBox = distBBox(node, 0, m, toBBox), - rightBBox = distBBox(node, M - m, M, toBBox), - margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), - i, child; - - for (i = m; i < M - m; i++) { - child = node.children[i]; - extend(leftBBox, node.leaf ? toBBox(child) : child); - margin += bboxMargin(leftBBox); - } - - for (i = M - m - 1; i >= m; i--) { - child = node.children[i]; - extend(rightBBox, node.leaf ? toBBox(child) : child); - margin += bboxMargin(rightBBox); - } - - return margin; - }, - - _adjustParentBBoxes: function (bbox, path, level) - { - // adjust bboxes along the given tree path - for (var i = level; i >= 0; i--) { - extend(path[i], bbox); - } - }, - - _condense: function (path) - { - // go through the path, removing empty nodes and updating bboxes - for (var i = path.length - 1, siblings; i >= 0; i--) { - if (path[i].children.length === 0) { - if (i > 0) { - siblings = path[i - 1].children; - siblings.splice(siblings.indexOf(path[i]), 1); - - } else this.clear(); - - } else calcBBox(path[i], this.toBBox); - } - }, - - compareMinX: function (a, b) - { - return a.left - b.left; - }, - - compareMinY: function (a, b) - { - return a.top - b.top; - }, - - toBBox: function (a) - { - return { - minX: a.left, - minY: a.top, - maxX: a.right, - maxY: a.bottom - }; - } -}; - -function findItem (item, items, equalsFn) -{ - if (!equalsFn) return items.indexOf(item); - - for (var i = 0; i < items.length; i++) { - if (equalsFn(item, items[i])) return i; - } - return -1; -} - -// calculate node's bbox from bboxes of its children -function calcBBox (node, toBBox) -{ - distBBox(node, 0, node.children.length, toBBox, node); -} - -// min bounding rectangle of node children from k to p-1 -function distBBox (node, k, p, toBBox, destNode) -{ - if (!destNode) destNode = createNode(null); - destNode.minX = Infinity; - destNode.minY = Infinity; - destNode.maxX = -Infinity; - destNode.maxY = -Infinity; - - for (var i = k, child; i < p; i++) { - child = node.children[i]; - extend(destNode, node.leaf ? toBBox(child) : child); - } - - return destNode; -} - -function extend (a, b) -{ - a.minX = Math.min(a.minX, b.minX); - a.minY = Math.min(a.minY, b.minY); - a.maxX = Math.max(a.maxX, b.maxX); - a.maxY = Math.max(a.maxY, b.maxY); - return a; -} - -function compareNodeMinX (a, b) { return a.minX - b.minX; } -function compareNodeMinY (a, b) { return a.minY - b.minY; } - -function bboxArea (a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } -function bboxMargin (a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } - -function enlargedArea (a, b) -{ - return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * - (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); -} - -function intersectionArea (a, b) -{ - var minX = Math.max(a.minX, b.minX), - minY = Math.max(a.minY, b.minY), - maxX = Math.min(a.maxX, b.maxX), - maxY = Math.min(a.maxY, b.maxY); - - return Math.max(0, maxX - minX) * - Math.max(0, maxY - minY); -} - -function contains (a, b) -{ - return a.minX <= b.minX && - a.minY <= b.minY && - b.maxX <= a.maxX && - b.maxY <= a.maxY; -} - -function intersects (a, b) -{ - return b.minX <= a.maxX && - b.minY <= a.maxY && - b.maxX >= a.minX && - b.maxY >= a.minY; -} - -function createNode (children) -{ - return { - children: children, - height: 1, - leaf: true, - minX: Infinity, - minY: Infinity, - maxX: -Infinity, - maxY: -Infinity - }; -} - -// sort an array so that items come in groups of n unsorted items, with groups sorted between each other; -// combines selection algorithm with binary divide & conquer approach - -function multiSelect (arr, left, right, n, compare) -{ - var stack = [left, right], - mid; - - while (stack.length) - { - right = stack.pop(); - left = stack.pop(); - - if (right - left <= n) continue; - - mid = left + Math.ceil((right - left) / n / 2) * n; - quickselect(arr, mid, left, right, compare); - - stack.push(left, mid, mid, right); - } -} - -module.exports = rbush; - -/***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TileCheckX = __webpack_require__(511); -var TileCheckY = __webpack_require__(513); -var TileIntersectsBody = __webpack_require__(243); - -/** - * The core separation function to separate a physics body and a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.SeparateTile - * @since 3.0.0 - * - * @param {number} i - The index of the tile within the map data. - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to collide against. - * @param {Phaser.Geom.Rectangle} tileWorldRect - A rectangle-like object defining the dimensions of the tile. - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The tilemapLayer to collide against. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {boolean} `true` if the body was separated, otherwise `false`. - */ -var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) -{ - var tileLeft = tileWorldRect.left; - var tileTop = tileWorldRect.top; - var tileRight = tileWorldRect.right; - var tileBottom = tileWorldRect.bottom; - var faceHorizontal = tile.faceLeft || tile.faceRight; - var faceVertical = tile.faceTop || tile.faceBottom; - - if (!isLayer) - { - faceHorizontal = true; - faceVertical = true; - } - - // We don't need to go any further if this tile doesn't actually have any colliding faces. This - // could happen if the tile was meant to be collided with re: a callback, but otherwise isn't - // needed for separation. - if (!faceHorizontal && !faceVertical) - { - return false; - } - - var ox = 0; - var oy = 0; - var minX = 0; - var minY = 1; - - if (body.deltaAbsX() > body.deltaAbsY()) - { - // Moving faster horizontally, check X axis first - minX = -1; - } - else if (body.deltaAbsX() < body.deltaAbsY()) - { - // Moving faster vertically, check Y axis first - minY = -1; - } - - if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical) - { - // We only need do this if both axes have colliding faces AND we're moving in both - // directions - minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft)); - minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop)); - } - - if (minX < minY) - { - if (faceHorizontal) - { - ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); - - // That's horizontal done, check if we still intersects? If not then we can return now - if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) - { - return true; - } - } - - if (faceVertical) - { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - } - } - else - { - if (faceVertical) - { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - - // That's vertical done, check if we still intersects? If not then we can return now - if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) - { - return true; - } - } - - if (faceHorizontal) - { - ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); - } - } - - return (ox !== 0 || oy !== 0); -}; - -module.exports = SeparateTile; - - -/***/ }), -/* 511 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ProcessTileSeparationX = __webpack_require__(512); - -/** - * Check the body against the given tile on the X axis. - * Used internally by the SeparateTile function. - * - * @function Phaser.Physics.Arcade.Tilemap.TileCheckX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to check. - * @param {number} tileLeft - The left position of the tile within the tile world. - * @param {number} tileRight - The right position of the tile within the tile world. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {number} The amount of separation that occurred. - */ -var TileCheckX = function (body, tile, tileLeft, tileRight, tileBias, isLayer) -{ - var ox = 0; - - var faceLeft = tile.faceLeft; - var faceRight = tile.faceRight; - var collideLeft = tile.collideLeft; - var collideRight = tile.collideRight; - - if (!isLayer) - { - faceLeft = true; - faceRight = true; - collideLeft = true; - collideRight = true; - } - - if (body.deltaX() < 0 && collideRight && body.checkCollision.left) - { - // Body is moving LEFT - if (faceRight && body.x < tileRight) - { - ox = body.x - tileRight; - - if (ox < -tileBias) - { - ox = 0; - } - } - } - else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) - { - // Body is moving RIGHT - if (faceLeft && body.right > tileLeft) - { - ox = body.right - tileLeft; - - if (ox > tileBias) - { - ox = 0; - } - } - } - - if (ox !== 0) - { - if (body.customSeparateX) - { - body.overlapX = ox; - } - else - { - ProcessTileSeparationX(body, ox); - } - } - - return ox; -}; - -module.exports = TileCheckX; - - -/***/ }), -/* 512 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Internal function to process the separation of a physics body from a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {number} x - The x separation amount. - */ -var ProcessTileSeparationX = function (body, x) -{ - if (x < 0) - { - body.blocked.none = false; - body.blocked.left = true; - } - else if (x > 0) - { - body.blocked.none = false; - body.blocked.right = true; - } - - body.position.x -= x; - - if (body.bounce.x === 0) - { - body.velocity.x = 0; - } - else - { - body.velocity.x = -body.velocity.x * body.bounce.x; - } -}; - -module.exports = ProcessTileSeparationX; - - -/***/ }), -/* 513 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ProcessTileSeparationY = __webpack_require__(514); - -/** - * Check the body against the given tile on the Y axis. - * Used internally by the SeparateTile function. - * - * @function Phaser.Physics.Arcade.Tilemap.TileCheckY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {Phaser.Tilemaps.Tile} tile - The tile to check. - * @param {number} tileTop - The top position of the tile within the tile world. - * @param {number} tileBottom - The bottom position of the tile within the tile world. - * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. - * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? - * - * @return {number} The amount of separation that occurred. - */ -var TileCheckY = function (body, tile, tileTop, tileBottom, tileBias, isLayer) -{ - var oy = 0; - - var faceTop = tile.faceTop; - var faceBottom = tile.faceBottom; - var collideUp = tile.collideUp; - var collideDown = tile.collideDown; - - if (!isLayer) - { - faceTop = true; - faceBottom = true; - collideUp = true; - collideDown = true; - } - - if (body.deltaY() < 0 && collideDown && body.checkCollision.up) - { - // Body is moving UP - if (faceBottom && body.y < tileBottom) - { - oy = body.y - tileBottom; - - if (oy < -tileBias) - { - oy = 0; - } - } - } - else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) - { - // Body is moving DOWN - if (faceTop && body.bottom > tileTop) - { - oy = body.bottom - tileTop; - - if (oy > tileBias) - { - oy = 0; - } - } - } - - if (oy !== 0) - { - if (body.customSeparateY) - { - body.overlapY = oy; - } - else - { - ProcessTileSeparationY(body, oy); - } - } - - return oy; -}; - -module.exports = TileCheckY; - - -/***/ }), -/* 514 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Internal function to process the separation of a physics body from a tile. - * - * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. - * @param {number} y - The y separation amount. - */ -var ProcessTileSeparationY = function (body, y) -{ - if (y < 0) - { - body.blocked.none = false; - body.blocked.up = true; - } - else if (y > 0) - { - body.blocked.none = false; - body.blocked.down = true; - } - - body.position.y -= y; - - if (body.bounce.y === 0) - { - body.velocity.y = 0; - } - else - { - body.velocity.y = -body.velocity.y * body.bounce.y; - } -}; - -module.exports = ProcessTileSeparationY; - - -/***/ }), -/* 515 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetOverlapX = __webpack_require__(241); -var ProcessX = __webpack_require__(1383); - -/** - * Separates two overlapping bodies on the X-axis (horizontally). - * - * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. - * - * The bodies won't be separated if there is no horizontal overlap between them, if they are static, or if either one uses custom logic for its separation. - * - * @function Phaser.Physics.Arcade.SeparateX - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. - * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. - * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. - * - * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. - */ -var SeparateX = function (body1, body2, overlapOnly, bias) -{ - var overlap = GetOverlapX(body1, body2, overlapOnly, bias); - - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateX || body2.customSeparateX) - { - // return true if there was some overlap, otherwise false - return (overlap !== 0) || (body1.embedded && body2.embedded); - } - - var blockedState = ProcessX.Set(body1, body2, overlap); - - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) - { - return true; - } - - return ProcessX.Check(); - } - else if (body1Immovable) - { - ProcessX.RunImmovableBody1(blockedState); - } - else if (body2Immovable) - { - ProcessX.RunImmovableBody2(blockedState); - } - - // If we got this far then there WAS overlap, and separation is complete, so return true - return true; -}; - -module.exports = SeparateX; - - -/***/ }), -/* 516 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetOverlapY = __webpack_require__(242); -var ProcessY = __webpack_require__(1384); - -/** - * Separates two overlapping bodies on the Y-axis (vertically). - * - * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. - * - * The bodies won't be separated if there is no vertical overlap between them, if they are static, or if either one uses custom logic for its separation. - * - * @function Phaser.Physics.Arcade.SeparateY - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. - * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. - * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. - * - * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. - */ -var SeparateY = function (body1, body2, overlapOnly, bias) -{ - var overlap = GetOverlapY(body1, body2, overlapOnly, bias); - - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; - - // Can't separate two immovable bodies, or a body with its own custom separation logic - if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateY || body2.customSeparateY) - { - // return true if there was some overlap, otherwise false - return (overlap !== 0) || (body1.embedded && body2.embedded); - } - - var blockedState = ProcessY.Set(body1, body2, overlap); - - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) - { - return true; - } - - return ProcessY.Check(); - } - else if (body1Immovable) - { - ProcessY.RunImmovableBody1(blockedState); - } - else if (body2Immovable) - { - ProcessY.RunImmovableBody2(blockedState); - } - - // If we got this far then there WAS overlap, and separation is complete, so return true - return true; -}; - -module.exports = SeparateY; - - -/***/ }), -/* 517 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CircleContains = __webpack_require__(62); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(59); -var RectangleContains = __webpack_require__(56); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A Static Arcade Physics Body. - * - * A Static Body never moves, and isn't automatically synchronized with its parent Game Object. - * That means if you make any change to the parent's origin, position, or scale after creating or adding the body, you'll need to update the Static Body manually. - * - * A Static Body can collide with other Bodies, but is never moved by collisions. - * - * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Body}. - * - * @class StaticBody - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Static Body belongs to. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Static Body belongs to. - */ -var StaticBody = new Class({ - - initialize: - - function StaticBody (world, gameObject) - { - var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; - var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; - - /** - * The Arcade Physics simulation this Static Body belongs to. - * - * @name Phaser.Physics.Arcade.StaticBody#world - * @type {Phaser.Physics.Arcade.World} - * @since 3.0.0 - */ - this.world = world; - - /** - * The Game Object this Static Body belongs to. - * - * @name Phaser.Physics.Arcade.StaticBody#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.gameObject = gameObject; - - /** - * Whether the Static Body's boundary is drawn to the debug display. - * - * @name Phaser.Physics.Arcade.StaticBody#debugShowBody - * @type {boolean} - * @since 3.0.0 - */ - this.debugShowBody = world.defaults.debugShowStaticBody; - - /** - * The color of this Static Body on the debug display. - * - * @name Phaser.Physics.Arcade.StaticBody#debugBodyColor - * @type {number} - * @since 3.0.0 - */ - this.debugBodyColor = world.defaults.staticBodyDebugColor; - - /** - * Whether this Static Body is updated by the physics simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#enable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enable = true; - - /** - * Whether this Static Body's boundary is circular (`true`) or rectangular (`false`). - * - * @name Phaser.Physics.Arcade.StaticBody#isCircle - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isCircle = false; - - /** - * If this Static Body is circular, this is the radius of the boundary, as set by {@link Phaser.Physics.Arcade.StaticBody#setCircle}, in pixels. - * Equal to `halfWidth`. - * - * @name Phaser.Physics.Arcade.StaticBody#radius - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.radius = 0; - - /** - * The offset set by {@link Phaser.Physics.Arcade.StaticBody#setCircle} or {@link Phaser.Physics.Arcade.StaticBody#setSize}. - * - * This doesn't affect the Static Body's position, because a Static Body does not follow its Game Object. - * - * @name Phaser.Physics.Arcade.StaticBody#offset - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.offset = new Vector2(); - - /** - * The position of this Static Body within the simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#position - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.position = new Vector2(gameObject.x - (width * gameObject.originX), gameObject.y - (height * gameObject.originY)); - - /** - * The width of the Static Body's boundary, in pixels. - * If the Static Body is circular, this is also the Static Body's diameter. - * - * @name Phaser.Physics.Arcade.StaticBody#width - * @type {number} - * @since 3.0.0 - */ - this.width = width; - - /** - * The height of the Static Body's boundary, in pixels. - * If the Static Body is circular, this is also the Static Body's diameter. - * - * @name Phaser.Physics.Arcade.StaticBody#height - * @type {number} - * @since 3.0.0 - */ - this.height = height; - - /** - * Half the Static Body's width, in pixels. - * If the Static Body is circular, this is also the Static Body's radius. - * - * @name Phaser.Physics.Arcade.StaticBody#halfWidth - * @type {number} - * @since 3.0.0 - */ - this.halfWidth = Math.abs(this.width / 2); - - /** - * Half the Static Body's height, in pixels. - * If the Static Body is circular, this is also the Static Body's radius. - * - * @name Phaser.Physics.Arcade.StaticBody#halfHeight - * @type {number} - * @since 3.0.0 - */ - this.halfHeight = Math.abs(this.height / 2); - - /** - * The center of the Static Body's boundary. - * This is the midpoint of its `position` (top-left corner) and its bottom-right corner. - * - * @name Phaser.Physics.Arcade.StaticBody#center - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - */ - this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - /** - * A constant zero velocity used by the Arcade Physics simulation for calculations. - * - * @name Phaser.Physics.Arcade.StaticBody#velocity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.velocity = Vector2.ZERO; - - /** - * A constant `false` value expected by the Arcade Physics simulation. - * - * @name Phaser.Physics.Arcade.StaticBody#allowGravity - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.allowGravity = false; - - /** - * Gravitational force applied specifically to this Body. Values are in pixels per second squared. Always zero for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#gravity - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.gravity = Vector2.ZERO; - - /** - * Rebound, or restitution, following a collision, relative to 1. Always zero for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#bounce - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.0.0 - */ - this.bounce = Vector2.ZERO; - - // If true this Body will dispatch events - - /** - * Whether the simulation emits a `worldbounds` event when this StaticBody collides with the world boundary. - * Always false for a Static Body. (Static Bodies never collide with the world boundary and never trigger a `worldbounds` event.) - * - * @name Phaser.Physics.Arcade.StaticBody#onWorldBounds - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.onWorldBounds = false; - - /** - * Whether the simulation emits a `collide` event when this StaticBody collides with another. - * - * @name Phaser.Physics.Arcade.StaticBody#onCollide - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.onCollide = false; - - /** - * Whether the simulation emits an `overlap` event when this StaticBody overlaps with another. - * - * @name Phaser.Physics.Arcade.StaticBody#onOverlap - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.onOverlap = false; - - /** - * The StaticBody's inertia, relative to a default unit (1). With `bounce`, this affects the exchange of momentum (velocities) during collisions. - * - * @name Phaser.Physics.Arcade.StaticBody#mass - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.mass = 1; - - /** - * Whether this object can be moved by collisions with another body. - * - * @name Phaser.Physics.Arcade.StaticBody#immovable - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.immovable = true; - - /** - * Sets if this Body can be pushed by another Body. - * - * A body that cannot be pushed will reflect back all of the velocity it is given to the - * colliding body. If that body is also not pushable, then the separation will be split - * between them evenly. - * - * If you want your body to never move or seperate at all, see the `setImmovable` method. - * - * By default, Static Bodies are not pushable. - * - * @name Phaser.Physics.Arcade.StaticBody#pushable - * @type {boolean} - * @default false - * @since 3.50.0 - * @see Phaser.GameObjects.Components.Pushable#setPushable - */ - this.pushable = false; - - /** - * A flag disabling the default horizontal separation of colliding bodies. Pass your own `collideHandler` to the collider. - * - * @name Phaser.Physics.Arcade.StaticBody#customSeparateX - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateX = false; - - /** - * A flag disabling the default vertical separation of colliding bodies. Pass your own `collideHandler` to the collider. - * - * @name Phaser.Physics.Arcade.StaticBody#customSeparateY - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customSeparateY = false; - - /** - * The amount of horizontal overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapX = 0; - - /** - * The amount of vertical overlap (before separation), if this Body is colliding with another. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapY = 0; - - /** - * The amount of overlap (before separation), if this StaticBody is circular and colliding with another circular body. - * - * @name Phaser.Physics.Arcade.StaticBody#overlapR - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.overlapR = 0; - - /** - * Whether this StaticBody has ever overlapped with another while both were not moving. - * - * @name Phaser.Physics.Arcade.StaticBody#embedded - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.embedded = false; - - /** - * Whether this StaticBody interacts with the world boundary. - * Always false for a Static Body. (Static Bodies never collide with the world boundary.) - * - * @name Phaser.Physics.Arcade.StaticBody#collideWorldBounds - * @type {boolean} - * @readonly - * @default false - * @since 3.0.0 - */ - this.collideWorldBounds = false; - - /** - * Whether this StaticBody is checked for collisions and for which directions. You can set `checkCollision.none = false` to disable collision checks. - * - * @name Phaser.Physics.Arcade.StaticBody#checkCollision - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * - * @name Phaser.Physics.Arcade.StaticBody#touching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.touching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * The values are always false for a Static Body. - * - * @name Phaser.Physics.Arcade.StaticBody#wasTouching - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This property is kept for compatibility with Dynamic Bodies. - * Avoid using it. - * - * @name Phaser.Physics.Arcade.StaticBody#blocked - * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} - * @since 3.0.0 - */ - this.blocked = { none: true, up: false, down: false, left: false, right: false }; - - /** - * The StaticBody's physics type (static by default). - * - * @name Phaser.Physics.Arcade.StaticBody#physicsType - * @type {number} - * @default Phaser.Physics.Arcade.STATIC_BODY - * @since 3.0.0 - */ - this.physicsType = CONST.STATIC_BODY; - - /** - * The calculated change in the Static Body's horizontal position during the current step. - * For a static body this is always zero. - * - * @name Phaser.Physics.Arcade.StaticBody#_dx - * @type {number} - * @private - * @default 0 - * @since 3.10.0 - */ - this._dx = 0; - - /** - * The calculated change in the Static Body's vertical position during the current step. - * For a static body this is always zero. - * - * @name Phaser.Physics.Arcade.StaticBody#_dy - * @type {number} - * @private - * @default 0 - * @since 3.10.0 - */ - this._dy = 0; - }, - - /** - * Changes the Game Object this Body is bound to. - * First it removes its reference from the old Game Object, then sets the new one. - * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#setGameObject - * @since 3.1.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. - * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - * - * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject - */ - setGameObject: function (gameObject, update) - { - if (gameObject && gameObject !== this.gameObject) - { - // Remove this body from the old game object - this.gameObject.body = null; - - gameObject.body = this; - - // Update our reference - this.gameObject = gameObject; - } - - if (update) - { - this.updateFromGameObject(); - } - - return this; - }, - - /** - * Syncs the Static Body's position and size with its parent Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject - * @since 3.1.0 - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - updateFromGameObject: function () - { - this.world.staticTree.remove(this); - - var gameObject = this.gameObject; - - gameObject.getTopLeft(this.position); - - this.width = gameObject.displayWidth; - this.height = gameObject.displayHeight; - - this.halfWidth = Math.abs(this.width / 2); - this.halfHeight = Math.abs(this.height / 2); - - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Positions the Static Body at an offset from its Game Object. - * - * @method Phaser.Physics.Arcade.StaticBody#setOffset - * @since 3.4.0 - * - * @param {number} x - The horizontal offset of the Static Body from the Game Object's `x`. - * @param {number} y - The vertical offset of the Static Body from the Game Object's `y`. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setOffset: function (x, y) - { - if (y === undefined) { y = x; } - - this.world.staticTree.remove(this); - - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; - - this.offset.set(x, y); - - this.position.x += this.offset.x; - this.position.y += this.offset.y; - - this.updateCenter(); - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Sets the size of the Static Body. - * When `center` is true, also repositions it. - * Resets the width and height to match current frame, if no width and height provided and a frame is found. - * - * @method Phaser.Physics.Arcade.StaticBody#setSize - * @since 3.0.0 - * - * @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. - * @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. - * @param {boolean} [center=true] - Place the Static Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setSize: function (width, height, center) - { - if (center === undefined) { center = true; } - - var gameObject = this.gameObject; - - if (!width && gameObject.frame) - { - width = gameObject.frame.realWidth; - } - - if (!height && gameObject.frame) - { - height = gameObject.frame.realHeight; - } - - this.world.staticTree.remove(this); - - this.width = width; - this.height = height; - - this.halfWidth = Math.floor(width / 2); - this.halfHeight = Math.floor(height / 2); - - if (center && gameObject.getCenter) - { - var ox = gameObject.displayWidth / 2; - var oy = gameObject.displayHeight / 2; - - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; - - this.offset.set(ox - this.halfWidth, oy - this.halfHeight); - - this.position.x += this.offset.x; - this.position.y += this.offset.y; - } - - this.updateCenter(); - - this.isCircle = false; - this.radius = 0; - - this.world.staticTree.insert(this); - - return this; - }, - - /** - * Sets this Static Body to have a circular body and sets its size and position. - * - * @method Phaser.Physics.Arcade.StaticBody#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the StaticBody, in pixels. - * @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels. - * @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setCircle: function (radius, offsetX, offsetY) - { - if (offsetX === undefined) { offsetX = this.offset.x; } - if (offsetY === undefined) { offsetY = this.offset.y; } - - if (radius > 0) - { - this.world.staticTree.remove(this); - - this.isCircle = true; - - this.radius = radius; - - this.width = radius * 2; - this.height = radius * 2; - - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - - this.offset.set(offsetX, offsetY); - - this.updateCenter(); - - this.world.staticTree.insert(this); - } - else - { - this.isCircle = false; - } - - return this; - }, - - /** - * Updates the StaticBody's `center` from its `position` and dimensions. - * - * @method Phaser.Physics.Arcade.StaticBody#updateCenter - * @since 3.0.0 - */ - updateCenter: function () - { - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - }, - - /** - * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. - * - * @method Phaser.Physics.Arcade.StaticBody#reset - * @since 3.0.0 - * - * @param {number} [x] - The x coordinate to reset the body to. If not given will use the parent Game Object's coordinate. - * @param {number} [y] - The y coordinate to reset the body to. If not given will use the parent Game Object's coordinate. - */ - reset: function (x, y) - { - var gameObject = this.gameObject; - - if (x === undefined) { x = gameObject.x; } - if (y === undefined) { y = gameObject.y; } - - this.world.staticTree.remove(this); - - gameObject.setPosition(x, y); - - gameObject.getTopLeft(this.position); - - this.updateCenter(); - - this.world.staticTree.insert(this); - }, - - /** - * NOOP function. A Static Body cannot be stopped. - * - * @method Phaser.Physics.Arcade.StaticBody#stop - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - stop: function () - { - return this; - }, - - /** - * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. - * - * @method Phaser.Physics.Arcade.StaticBody#getBounds - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. - * - * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody. - */ - getBounds: function (obj) - { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; - - return obj; - }, - - /** - * Checks to see if a given x,y coordinate is colliding with this Static Body. - * - * @method Phaser.Physics.Arcade.StaticBody#hitTest - * @since 3.0.0 - * - * @param {number} x - The x coordinate to check against this body. - * @param {number} y - The y coordinate to check against this body. - * - * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. - */ - hitTest: function (x, y) - { - return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); - }, - - /** - * NOOP - * - * @method Phaser.Physics.Arcade.StaticBody#postUpdate - * @since 3.12.0 - */ - postUpdate: function () - { - }, - - /** - * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX - * @since 3.0.0 - * - * @return {number} Always zero for a Static Body. - */ - deltaAbsX: function () - { - return 0; - }, - - /** - * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY - * @since 3.0.0 - * - * @return {number} Always zero for a Static Body. - */ - deltaAbsY: function () - { - return 0; - }, - - /** - * The change in this StaticBody's horizontal position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaX - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. - */ - deltaX: function () - { - return 0; - }, - - /** - * The change in this StaticBody's vertical position from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaY - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. - */ - deltaY: function () - { - return 0; - }, - - /** - * The change in this StaticBody's rotation from the previous step. Always zero. - * - * @method Phaser.Physics.Arcade.StaticBody#deltaZ - * @since 3.0.0 - * - * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. - */ - deltaZ: function () - { - return 0; - }, - - /** - * Disables this Body and marks it for destruction during the next step. - * - * @method Phaser.Physics.Arcade.StaticBody#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.enable = false; - - this.world.pendingDestroy.set(this); - }, - - /** - * Draws a graphical representation of the StaticBody for visual debugging purposes. - * - * @method Phaser.Physics.Arcade.StaticBody#drawDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. - */ - drawDebug: function (graphic) - { - var pos = this.position; - - var x = pos.x + this.halfWidth; - var y = pos.y + this.halfHeight; - - if (this.debugShowBody) - { - graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor, 1); - - if (this.isCircle) - { - graphic.strokeCircle(x, y, this.width / 2); - } - else - { - graphic.strokeRect(pos.x, pos.y, this.width, this.height); - } - - } - }, - - /** - * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. - * - * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug - * @since 3.0.0 - * - * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. - */ - willDrawDebug: function () - { - return this.debugShowBody; - }, - - /** - * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. - * - * @method Phaser.Physics.Arcade.StaticBody#setMass - * @since 3.0.0 - * - * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. - * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. - */ - setMass: function (value) - { - if (value <= 0) - { - // Causes havoc otherwise - value = 0.1; - } - - this.mass = value; - - return this; - }, - - /** - * The x coordinate of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#x - * @type {number} - * @since 3.0.0 - */ - x: { - - get: function () - { - return this.position.x; - }, - - set: function (value) - { - this.world.staticTree.remove(this); - - this.position.x = value; - - this.world.staticTree.insert(this); - } - - }, - - /** - * The y coordinate of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#y - * @type {number} - * @since 3.0.0 - */ - y: { - - get: function () - { - return this.position.y; - }, - - set: function (value) - { - this.world.staticTree.remove(this); - - this.position.y = value; - - this.world.staticTree.insert(this); - } - - }, - - /** - * Returns the left-most x coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#left - * @type {number} - * @readonly - * @since 3.0.0 - */ - left: { - - get: function () - { - return this.position.x; - } - - }, - - /** - * The right-most x coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#right - * @type {number} - * @readonly - * @since 3.0.0 - */ - right: { - - get: function () - { - return this.position.x + this.width; - } - - }, - - /** - * The highest y coordinate of the area of the StaticBody. - * - * @name Phaser.Physics.Arcade.StaticBody#top - * @type {number} - * @readonly - * @since 3.0.0 - */ - top: { - - get: function () - { - return this.position.y; - } - - }, - - /** - * The lowest y coordinate of the area of the StaticBody. (y + height) - * - * @name Phaser.Physics.Arcade.StaticBody#bottom - * @type {number} - * @readonly - * @since 3.0.0 - */ - bottom: { - - get: function () - { - return this.position.y + this.height; - } - - } - -}); - -module.exports = StaticBody; - - -/***/ }), -/* 518 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Physics.Matter.Components - */ - -module.exports = { - - Bounce: __webpack_require__(1493), - Collision: __webpack_require__(1494), - Force: __webpack_require__(1495), - Friction: __webpack_require__(1496), - Gravity: __webpack_require__(1497), - Mass: __webpack_require__(1498), - Sensor: __webpack_require__(1499), - SetBody: __webpack_require__(1500), - Sleep: __webpack_require__(1501), - Static: __webpack_require__(1518), - Transform: __webpack_require__(1519), - Velocity: __webpack_require__(1520) - -}; - - -/***/ }), -/* 519 */ -/***/ (function(module, exports) { - -/** -* The `Matter.Pair` module contains methods for creating and manipulating collision pairs. -* -* @class Pair -*/ - -var Pair = {}; - -module.exports = Pair; - -(function() { - - /** - * Creates a pair. - * @method create - * @param {collision} collision - * @param {number} timestamp - * @return {pair} A new pair - */ - Pair.create = function(collision, timestamp) { - var bodyA = collision.bodyA, - bodyB = collision.bodyB; - - var pair = { - id: Pair.id(bodyA, bodyB), - bodyA: bodyA, - bodyB: bodyB, - activeContacts: [], - separation: 0, - isActive: true, - confirmedActive: true, - isSensor: bodyA.isSensor || bodyB.isSensor, - timeCreated: timestamp, - timeUpdated: timestamp, - collision: null, - inverseMass: 0, - friction: 0, - frictionStatic: 0, - restitution: 0, - slop: 0 - }; - - Pair.update(pair, collision, timestamp); - - return pair; - }; - - /** - * Updates a pair given a collision. - * @method update - * @param {pair} pair - * @param {collision} collision - * @param {number} timestamp - */ - Pair.update = function(pair, collision, timestamp) { - pair.collision = collision; - - if (collision.collided) { - var supports = collision.supports, - activeContacts = pair.activeContacts, - parentA = collision.parentA, - parentB = collision.parentB; - - pair.inverseMass = parentA.inverseMass + parentB.inverseMass; - pair.friction = Math.min(parentA.friction, parentB.friction); - pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic); - pair.restitution = Math.max(parentA.restitution, parentB.restitution); - pair.slop = Math.max(parentA.slop, parentB.slop); - - for (var i = 0; i < supports.length; i++) { - activeContacts[i] = supports[i].contact; - } - - // optimise array size - var supportCount = supports.length; - if (supportCount < activeContacts.length) { - activeContacts.length = supportCount; - } - - pair.separation = collision.depth; - Pair.setActive(pair, true, timestamp); - } else { - if (pair.isActive === true) - Pair.setActive(pair, false, timestamp); - } - }; - - /** - * Set a pair as active or inactive. - * @method setActive - * @param {pair} pair - * @param {bool} isActive - * @param {number} timestamp - */ - Pair.setActive = function(pair, isActive, timestamp) { - if (isActive) { - pair.isActive = true; - pair.timeUpdated = timestamp; - } else { - pair.isActive = false; - pair.activeContacts.length = 0; - } - }; - - /** - * Get the id for the given pair. - * @method id - * @param {body} bodyA - * @param {body} bodyB - * @return {string} Unique pairId - */ - Pair.id = function(bodyA, bodyB) { - if (bodyA.id < bodyB.id) { - return 'A' + bodyA.id + 'B' + bodyB.id; - } else { - return 'A' + bodyB.id + 'B' + bodyA.id; - } - }; - -})(); - - -/***/ }), -/* 520 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* @author Richard Davey -* @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; - - -/***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); - -/** - * Checks if the given tile coordinate is within the isometric layer bounds, or not. - * - * @function Phaser.Tilemaps.Components.CheckIsoBounds - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to check against. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. - * - * @return {boolean} Returns `true` if the coordinates are within the iso bounds. - */ -var CheckIsoBounds = function (tileX, tileY, layer, camera) -{ - var tilemapLayer = layer.tilemapLayer; - - var cullPaddingX = tilemapLayer.cullPaddingX; - var cullPaddingY = tilemapLayer.cullPaddingY; - - var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer); - - // we always subtract 1/2 of the tile's height/width to make the culling distance start from the center of the tiles. - return pos.x > camera.worldView.x + tilemapLayer.scaleX * layer.tileWidth * (-cullPaddingX - 0.5) - && pos.x < camera.worldView.right + tilemapLayer.scaleX * layer.tileWidth * (cullPaddingX - 0.5) - && pos.y > camera.worldView.y + tilemapLayer.scaleY * layer.tileHeight * (-cullPaddingY - 1.0) - && pos.y < camera.worldView.bottom + tilemapLayer.scaleY * layer.tileHeight * (cullPaddingY - 0.5); -}; - -module.exports = CheckIsoBounds; - - -/***/ }), -/* 522 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetTilesWithin = __webpack_require__(26); - -/** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * @function Phaser.Tilemaps.Components.ReplaceByIndex - * @since 3.0.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var ReplaceByIndex = function (findIndex, newIndex, tileX, tileY, width, height, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - - for (var i = 0; i < tiles.length; i++) - { - if (tiles[i] && tiles[i].index === findIndex) - { - tiles[i].index = newIndex; - } - } -}; - -module.exports = ReplaceByIndex; - - -/***/ }), -/* 523 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Rectangle = __webpack_require__(10); -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -var bounds = new Rectangle(); - -/** - * Returns the bounds in the given orthogonal layer that are within the cameras viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.CullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {Phaser.Geom.Rectangle} A rectangle containing the culled bounds. If you wish to retain this object, clone it, as it's recycled internally. - */ -var CullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY; - - return bounds.setTo( - boundsLeft, - boundsTop, - (boundsRight - boundsLeft), - (boundsBottom - boundsTop) - ); -}; - -module.exports = CullBounds; - - -/***/ }), -/* 524 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(523); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.CullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var CullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - var bounds = CullBounds(layer, camera); - - if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) - { - bounds.left = 0; - bounds.right = layer.width; - bounds.top = 0; - bounds.bottom = layer.height; - } - - RunCull(layer, bounds, renderOrder, outputArray); - - return outputArray; -}; - -module.exports = CullTiles; - - -/***/ }), -/* 525 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(526); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.HexagonalCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var HexagonalCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) - { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - - var bounds = CullBounds(layer, camera); - - RunCull(layer, bounds, renderOrder, outputArray); - } - - return outputArray; -}; - -module.exports = HexagonalCullTiles; - - -/***/ }), -/* 526 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -/** - * Returns the bounds in the given layer that are within the camera's viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.HexagonalCullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. - */ -var HexagonalCullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var len = layer.hexSideLength; - var rowH = ((tileH - len) / 2 + len); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY; - - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; -}; - -module.exports = HexagonalCullBounds; - - -/***/ }), -/* 527 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CheckIsoBounds = __webpack_require__(521); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.IsometricCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; - - var drawLeft = 0; - var drawRight = mapWidth; - var drawTop = 0; - var drawBottom = mapHeight; - - if (!tilemapLayer.skipCull) - { - var x; - var y; - var tile; - - if (renderOrder === 0) - { - // right-down - - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 1) - { - // left-down - - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 2) - { - // right-up - - for (y = drawBottom; y >= drawTop; y--) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 3) - { - // left-up - - for (y = drawBottom; y >= drawTop; y--) - { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - if (CheckIsoBounds(x, y, layer, camera)) - { - tile = mapData[y][x]; - - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } - - outputArray.push(tile); - } - } - } - } - } - - tilemapLayer.tilesDrawn = outputArray.length; - tilemapLayer.tilesTotal = mapWidth * mapHeight; - - return outputArray; -}; - -module.exports = IsometricCullTiles; - - -/***/ }), -/* 528 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CullBounds = __webpack_require__(529); -var RunCull = __webpack_require__(156); - -/** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.StaggeredCullTiles - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * @param {array} [outputArray] - An optional array to store the Tile objects within. - * @param {number} [renderOrder=0] - The rendering order constant. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ -var StaggeredCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; - - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) - { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - - var bounds = CullBounds(layer, camera); - - RunCull(layer, bounds, renderOrder, outputArray); - } - - return outputArray; -}; - -module.exports = StaggeredCullTiles; - - -/***/ }), -/* 529 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var SnapCeil = __webpack_require__(137); -var SnapFloor = __webpack_require__(76); - -/** - * Returns the bounds in the given layer that are within the camera's viewport. - * This is used internally by the cull tiles function. - * - * @function Phaser.Tilemaps.Components.StaggeredCullBounds - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. - * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. - */ -var StaggeredCullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; - - // We need to use the tile sizes defined for the map as a whole, not the layer, - // in order to calculate the bounds correctly. As different sized tiles may be - // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. - var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); - var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); - - var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; - var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; - - var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH / 2, 0, true) - tilemapLayer.cullPaddingY; - var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH / 2, 0, true) + tilemapLayer.cullPaddingY; - - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; -}; - -module.exports = StaggeredCullBounds; - - -/***/ }), -/* 530 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from hexagonal tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.HexagonalTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = layer.hexSideLength; - var rowHeight = ((tileHeight - len) / 2 + len); - - // similar to staggered, because Tiled uses the oddr representation. - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * rowHeight; - - return point.set(x, y); -}; - -module.exports = HexagonalTileToWorldXY; - - -/***/ }), -/* 531 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from isometric tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.IsometricTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var IsometricTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); - var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); - - return point.set(x, y); -}; - -module.exports = IsometricTileToWorldXY; - - -/***/ }), -/* 532 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from staggered tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.StaggeredTileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var StaggeredTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - var layerWorldX = 0; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - - tileWidth *= tilemapLayer.scaleX; - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * (tileHeight / 2); - - return point.set(x, y); -}; - -module.exports = StaggeredTileToWorldXY; - - -/***/ }), -/* 533 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var TileToWorldX = __webpack_require__(247); -var TileToWorldY = __webpack_require__(248); -var Vector2 = __webpack_require__(3); - -/** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.TileToWorldXY - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. - */ -var TileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(0, 0); } - - point.x = TileToWorldX(tileX, camera, layer); - point.y = TileToWorldY(tileY, camera, layer); - - return point; -}; - -module.exports = TileToWorldXY; - - -/***/ }), -/* 534 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from hexagonal tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.HexagonalTileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in world coordinates. - */ -var HexagonalTileToWorldY = function (tileY, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = tilemapLayer.tilemap.hexSideLength; - - var rowHeight = ((tileHeight - len) / 2 + len); - - return layerWorldY + tileY * rowHeight; -}; - -module.exports = HexagonalTileToWorldY; - - -/***/ }), -/* 535 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from staggered tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.StaggeredTileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in world coordinates. - */ -var StaggeredTileToWorldY = function (tileY, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - var layerWorldY = 0; - - if (tilemapLayer) - { - if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - return layerWorldY + tileY * (tileHeight / 2); -}; - -module.exports = StaggeredTileToWorldY; - - -/***/ }), -/* 536 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinates down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - var len = layer.hexSideLength; - var rowHeight = ((tileHeight - len) / 2 + len); - - // similar to staggered, because Tiled uses the oddr representation. - var y = (snapToFloor) ? Math.floor((worldY / rowHeight)) : (worldY / rowHeight); - var x = (snapToFloor) ? Math.floor((worldX - (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX - (y % 2) * 0.5 * tileWidth) / tileWidth; - - return point.set(x, y); -}; - -module.exports = HexagonalWorldToTileXY; - - -/***/ }), -/* 537 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to isometric tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.IsometricWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var IsometricWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - worldX -= tileWidth / 2; - - var x = (snapToFloor) ? Math.floor((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2) : ((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2); - var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2) : ((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2); - - return point.set(x, y); -}; - -module.exports = IsometricWorldToTileXY; - - -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to staggered tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var StaggeredWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (!point) { point = new Vector2(); } - - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll - - worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - - tileWidth *= tilemapLayer.scaleX; - } - - var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2))) : (worldY / (tileHeight / 2)); - var x = (snapToFloor) ? Math.floor((worldX + (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX + (y % 2) * 0.5 * tileWidth) / tileWidth; - - return point.set(x, y); -}; - -module.exports = StaggeredWorldToTileXY; - - -/***/ }), -/* 539 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var WorldToTileX = __webpack_require__(249); -var WorldToTileY = __webpack_require__(250); -var Vector2 = __webpack_require__(3); - -/** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layer's position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @function Phaser.Tilemaps.Components.WorldToTileXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Math.Vector2} The XY location in tile units. - */ -var WorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) -{ - if (snapToFloor === undefined) { snapToFloor = true; } - if (!point) { point = new Vector2(0, 0); } - - point.x = WorldToTileX(worldX, snapToFloor, camera, layer); - point.y = WorldToTileY(worldY, snapToFloor, camera, layer); - - return point; -}; - -module.exports = WorldToTileXY; - - -/***/ }), -/* 540 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from world Y coordinates (pixels) to hexagonal tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.HexagonalWorldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in tile units. - */ -var HexagonalWorldToTileY = function (worldY, snapToFloor, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - var len = layer.hexSideLength; - - var rowHeight = ((tileHeight - len) / 2 + len); - - return (snapToFloor) ? Math.floor(worldY / rowHeight) : worldY / rowHeight; -}; - -module.exports = HexagonalWorldToTileY; - - -/***/ }), -/* 541 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts from world Y coordinates (pixels) to staggered tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in tile units. - */ -var StaggeredWorldToTileY = function (worldY, snapToFloor, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's vertical scroll - - worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - - tileHeight *= tilemapLayer.scaleY; - } - - return (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); -}; - -module.exports = StaggeredWorldToTileY; - - -/***/ }), -/* 542 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var IsInLayerBounds = __webpack_require__(116); - -/** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @function Phaser.Tilemaps.Components.HasTileAt - * @since 3.0.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ -var HasTileAt = function (tileX, tileY, layer) -{ - if (IsInLayerBounds(tileX, tileY, layer)) - { - var tile = layer.data[tileY][tileX]; - - return (tile !== null && tile.index > -1); - } - else - { - return false; - } -}; - -module.exports = HasTileAt; - - -/***/ }), -/* 543 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tile = __webpack_require__(83); -var IsInLayerBounds = __webpack_require__(116); -var CalculateFacesAt = __webpack_require__(246); - -/** - * Removes the tile at the given tile coordinates in the specified layer and updates the layer's - * collision information. - * - * @function Phaser.Tilemaps.Components.RemoveTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. - * @param {boolean} replaceWithNull - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} recalculateFaces - `true` if the faces data should be recalculated. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was removed. - */ -var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) -{ - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - if (!IsInLayerBounds(tileX, tileY, layer)) - { - return null; - } - - var tile = layer.data[tileY][tileX]; - - if (!tile) - { - return null; - } - else - { - layer.data[tileY][tileX] = (replaceWithNull) ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight); - } - - // Recalculate faces only if the removed tile was a colliding tile - if (recalculateFaces && tile && tile.collides) - { - CalculateFacesAt(tileX, tileY, layer); - } - - return tile; -}; - -module.exports = RemoveTileAt; - - -/***/ }), -/* 544 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var Parse2DArray = __webpack_require__(253); -var ParseCSV = __webpack_require__(545); -var ParseJSONTiled = __webpack_require__(546); -var ParseWeltmeister = __webpack_require__(557); - -/** - * Parses raw data of a given Tilemap format into a new MapData object. If no recognized data format - * is found, returns `null`. When loading from CSV or a 2D array, you should specify the tileWidth & - * tileHeight. When parsing from a map from Tiled, the tileWidth & tileHeight will be pulled from - * the map data. - * - * @function Phaser.Tilemaps.Parsers.Parse - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {number} mapFormat - See ../Formats.js. - * @param {(number[][]|string|object)} data - 2D array, CSV string or Tiled JSON object. - * @param {number} tileWidth - The width of a tile in pixels. Required for 2D array and CSV, but - * ignored for Tiled JSON. - * @param {number} tileHeight - The height of a tile in pixels. Required for 2D array and CSV, but - * ignored for Tiled JSON. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {Phaser.Tilemaps.MapData} The created `MapData` object. - */ -var Parse = function (name, mapFormat, data, tileWidth, tileHeight, insertNull) -{ - var newMap; - - switch (mapFormat) - { - case (Formats.ARRAY_2D): - newMap = Parse2DArray(name, data, tileWidth, tileHeight, insertNull); - break; - case (Formats.CSV): - newMap = ParseCSV(name, data, tileWidth, tileHeight, insertNull); - break; - case (Formats.TILED_JSON): - newMap = ParseJSONTiled(name, data, insertNull); - break; - case (Formats.WELTMEISTER): - newMap = ParseWeltmeister(name, data, insertNull); - break; - default: - console.warn('Unrecognized tilemap data format: ' + mapFormat); - newMap = null; - } - - return newMap; -}; - -module.exports = Parse; - - -/***/ }), -/* 545 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var Parse2DArray = __webpack_require__(253); - -/** - * Parses a CSV string of tile indexes into a new MapData object with a single layer. - * - * @function Phaser.Tilemaps.Parsers.ParseCSV - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {string} data - CSV string of tile indexes. - * @param {number} tileWidth - The width of a tile in pixels. - * @param {number} tileHeight - The height of a tile in pixels. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {Phaser.Tilemaps.MapData} The resulting MapData object. - */ -var ParseCSV = function (name, data, tileWidth, tileHeight, insertNull) -{ - var array2D = data - .trim() - .split('\n') - .map(function (row) { return row.split(','); }); - - var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); - map.format = Formats.CSV; - - return map; -}; - -module.exports = ParseCSV; - - -/***/ }), -/* 546 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var AssignTileProperties = __webpack_require__(547); -var BuildTilesetIndex = __webpack_require__(548); -var CONST = __webpack_require__(29); -var Formats = __webpack_require__(37); -var FromOrientationString = __webpack_require__(252); -var MapData = __webpack_require__(118); -var ParseImageLayers = __webpack_require__(549); -var ParseObjectLayers = __webpack_require__(550); -var ParseTileLayers = __webpack_require__(553); -var ParseTilesets = __webpack_require__(555); - -/** - * Parses a Tiled JSON object into a new MapData object. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {object} json - The Tiled JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. - */ -var ParseJSONTiled = function (name, json, insertNull) -{ - // Map data will consist of: layers, objects, images, tilesets, sizes - var mapData = new MapData({ - width: json.width, - height: json.height, - name: name, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - orientation: FromOrientationString(json.orientation), - format: Formats.TILED_JSON, - version: json.version, - properties: json.properties, - renderOrder: json.renderorder, - infinite: json.infinite - }); - - if (mapData.orientation === CONST.HEXAGONAL) - { - mapData.hexSideLength = json.hexsidelength; - } - - mapData.layers = ParseTileLayers(json, insertNull); - mapData.images = ParseImageLayers(json); - - var sets = ParseTilesets(json); - - mapData.tilesets = sets.tilesets; - mapData.imageCollections = sets.imageCollections; - - mapData.objects = ParseObjectLayers(json); - - mapData.tiles = BuildTilesetIndex(mapData); - - AssignTileProperties(mapData); - - return mapData; -}; - -module.exports = ParseJSONTiled; - - -/***/ }), -/* 547 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Extend = __webpack_require__(19); - -/** - * Copy properties from tileset to tiles. - * - * @function Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. - */ -var AssignTileProperties = function (mapData) -{ - var layerData; - var tile; - var sid; - var set; - var row; - - // go through each of the map data layers - for (var i = 0; i < mapData.layers.length; i++) - { - layerData = mapData.layers[i]; - - set = null; - - // rows of tiles - for (var j = 0; j < layerData.data.length; j++) - { - row = layerData.data[j]; - - // individual tiles - for (var k = 0; k < row.length; k++) - { - tile = row[k]; - - if (tile === null || tile.index < 0) - { - continue; - } - - // find the relevant tileset - sid = mapData.tiles[tile.index][2]; - set = mapData.tilesets[sid]; - - // Ensure that a tile's size matches its tileset - tile.width = set.tileWidth; - tile.height = set.tileHeight; - - // if that tile type has any properties, add them to the tile object - if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) - { - tile.properties = Extend( - tile.properties, set.tileProperties[tile.index - set.firstgid] - ); - } - } - } - } -}; - -module.exports = AssignTileProperties; - - -/***/ }), -/* 548 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); - -/** - * Master list of tiles -> x, y, index in tileset. - * - * @function Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. - * - * @return {array} An array of Tileset objects. - */ -var BuildTilesetIndex = function (mapData) -{ - var i; - var set; - var tiles = []; - - for (i = 0; i < mapData.imageCollections.length; i++) - { - var collection = mapData.imageCollections[i]; - var images = collection.images; - - for (var j = 0; j < images.length; j++) - { - var image = images[j]; - - set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); - - set.updateTileData(collection.imageWidth, collection.imageHeight); - - mapData.tilesets.push(set); - } - } - - for (i = 0; i < mapData.tilesets.length; i++) - { - set = mapData.tilesets[i]; - - var x = set.tileMargin; - var y = set.tileMargin; - - var count = 0; - var countX = 0; - var countY = 0; - - for (var t = set.firstgid; t < set.firstgid + set.total; t++) - { - // Can add extra properties here as needed - tiles[t] = [ x, y, i ]; - - x += set.tileWidth + set.tileSpacing; - - count++; - - if (count === set.total) - { - break; - } - - countX++; - - if (countX === set.columns) - { - x = set.tileMargin; - y += set.tileHeight + set.tileSpacing; - - countX = 0; - countY++; - - if (countY === set.rows) - { - break; - } - } - } - } - - return tiles; -}; - -module.exports = BuildTilesetIndex; - - -/***/ }), -/* 549 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var CreateGroupLayer = __webpack_require__(158); - -/** - * Parses a Tiled JSON object into an array of objects with details about the image layers. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * - * @return {array} Array of objects that include critical info about the map's image layers - */ -var ParseImageLayers = function (json) -{ - var images = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - // Get current layer and advance iterator - var curi = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - if (curi.type !== 'imagelayer') - { - if (curi.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curi, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - var layerOffsetX = GetFastValue(curi, 'offsetx', 0) + GetFastValue(curi, 'startx', 0); - var layerOffsetY = GetFastValue(curi, 'offsety', 0) + GetFastValue(curi, 'starty', 0); - images.push({ - name: (curGroupState.name + curi.name), - image: curi.image, - x: (curGroupState.x + layerOffsetX + curi.x), - y: (curGroupState.y + layerOffsetY + curi.y), - alpha: (curGroupState.opacity * curi.opacity), - visible: (curGroupState.visible && curi.visible), - properties: GetFastValue(curi, 'properties', {}) - }); - } - - return images; -}; - -module.exports = ParseImageLayers; - - -/***/ }), -/* 550 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetFastValue = __webpack_require__(2); -var ParseObject = __webpack_require__(254); -var ObjectLayer = __webpack_require__(552); -var CreateGroupLayer = __webpack_require__(158); - -/** - * Parses a Tiled JSON object into an array of ObjectLayer objects. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * - * @return {array} An array of all object layers in the tilemap as `ObjectLayer`s. - */ -var ParseObjectLayers = function (json) -{ - var objectLayers = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - // Get current layer and advance iterator - var curo = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - // Modify inherited properties - curo.opacity *= curGroupState.opacity; - curo.visible = curGroupState.visible && curo.visible; - - if (curo.type !== 'objectgroup') - { - if (curo.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curo, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - curo.name = curGroupState.name + curo.name; - var offsetX = curGroupState.x + GetFastValue(curo, 'startx', 0) + GetFastValue(curo, 'offsetx', 0); - var offsetY = curGroupState.y + GetFastValue(curo, 'starty', 0) + GetFastValue(curo, 'offsety', 0); - - var objects = []; - for (var j = 0; j < curo.objects.length; j++) - { - var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); - - objects.push(parsedObject); - } - - var objectLayer = new ObjectLayer(curo); - objectLayer.objects = objects; - - objectLayers.push(objectLayer); - } - - return objectLayers; -}; - -module.exports = ParseObjectLayers; - - -/***/ }), -/* 551 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var HasValue = __webpack_require__(125); - -/** - * Returns a new object that only contains the `keys` that were found on the object provided. - * If no `keys` are found, an empty object is returned. - * - * @function Phaser.Utils.Objects.Pick - * @since 3.18.0 - * - * @param {object} object - The object to pick the provided keys from. - * @param {array} keys - An array of properties to retrieve from the provided object. - * - * @return {object} A new object that only contains the `keys` that were found on the provided object. If no `keys` were found, an empty object will be returned. - */ -var Pick = function (object, keys) -{ - var obj = {}; - - for (var i = 0; i < keys.length; i++) - { - var key = keys[i]; - - if (HasValue(object, key)) - { - obj[key] = object[key]; - } - } - - return obj; -}; - -module.exports = Pick; - - -/***/ }), -/* 552 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * A class for representing a Tiled object layer in a map. This mirrors the structure of a Tiled - * object layer, except: - * - "x" & "y" properties are ignored since these cannot be changed in Tiled. - * - "offsetx" & "offsety" are applied to the individual object coordinates directly, so they - * are ignored as well. - * - "draworder" is ignored. - * - * @class ObjectLayer - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.Tilemaps.ObjectLayerConfig} [config] - The data for the layer from the Tiled JSON object. - */ -var ObjectLayer = new Class({ - - initialize: - - function ObjectLayer (config) - { - if (config === undefined) { config = {}; } - - /** - * The name of the Object Layer. - * - * @name Phaser.Tilemaps.ObjectLayer#name - * @type {string} - * @since 3.0.0 - */ - this.name = GetFastValue(config, 'name', 'object layer'); - - /** - * The opacity of the layer, between 0 and 1. - * - * @name Phaser.Tilemaps.ObjectLayer#opacity - * @type {number} - * @since 3.0.0 - */ - this.opacity = GetFastValue(config, 'opacity', 1); - - /** - * The custom properties defined on the Object Layer, keyed by their name. - * - * @name Phaser.Tilemaps.ObjectLayer#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = GetFastValue(config, 'properties', {}); - - /** - * The type of each custom property defined on the Object Layer, keyed by its name. - * - * @name Phaser.Tilemaps.ObjectLayer#propertyTypes - * @type {object} - * @since 3.0.0 - */ - this.propertyTypes = GetFastValue(config, 'propertytypes', {}); - - /** - * The type of the layer, which should be `objectgroup`. - * - * @name Phaser.Tilemaps.ObjectLayer#type - * @type {string} - * @since 3.0.0 - */ - this.type = GetFastValue(config, 'type', 'objectgroup'); - - /** - * Whether the layer is shown (`true`) or hidden (`false`). - * - * @name Phaser.Tilemaps.ObjectLayer#visible - * @type {boolean} - * @since 3.0.0 - */ - this.visible = GetFastValue(config, 'visible', true); - - /** - * An array of all objects on this Object Layer. - * - * Each Tiled object corresponds to a JavaScript object in this array. It has an `id` (unique), - * `name` (as assigned in Tiled), `type` (as assigned in Tiled), `rotation` (in clockwise degrees), - * `properties` (if any), `visible` state (`true` if visible, `false` otherwise), - * `x` and `y` coordinates (in pixels, relative to the tilemap), and a `width` and `height` (in pixels). - * - * An object tile has a `gid` property (GID of the represented tile), a `flippedHorizontal` property, - * a `flippedVertical` property, and `flippedAntiDiagonal` property. - * The {@link http://docs.mapeditor.org/en/latest/reference/tmx-map-format/|Tiled documentation} contains - * information on flipping and rotation. - * - * Polylines have a `polyline` property, which is an array of objects corresponding to points, - * where each point has an `x` property and a `y` property. Polygons have an identically structured - * array in their `polygon` property. Text objects have a `text` property with the text's properties. - * - * Rectangles and ellipses have a `rectangle` or `ellipse` property set to `true`. - * - * @name Phaser.Tilemaps.ObjectLayer#objects - * @type {Phaser.Types.Tilemaps.TiledObject[]} - * @since 3.0.0 - */ - this.objects = GetFastValue(config, 'objects', []); - } - -}); - -module.exports = ObjectLayer; - - -/***/ }), -/* 553 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Base64Decode = __webpack_require__(554); -var CONST = __webpack_require__(29); -var CreateGroupLayer = __webpack_require__(158); -var FromOrientationString = __webpack_require__(252); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(117); -var ParseGID = __webpack_require__(255); -var Tile = __webpack_require__(83); - -/** - * Parses all tilemap layers in a Tiled JSON object into new LayerData objects. - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). - * - * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in - * json.layers with the type 'tilelayer'. - */ -var ParseTileLayers = function (json, insertNull) -{ - var infiniteMap = GetFastValue(json, 'infinite', false); - var tileLayers = []; - - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); - - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) - { - if (curGroupState.i >= curGroupState.layers.length) - { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } - - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; - } - - var curl = curGroupState.layers[curGroupState.i]; - curGroupState.i++; - - if (curl.type !== 'tilelayer') - { - if (curl.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curl, curGroupState); - - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } - - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } - - // Base64 decode data if necessary. NOTE: uncompressed base64 only. - if (curl.compression) - { - console.warn( - 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' - + curl.name + '\'' - ); - continue; - } - else if (curl.encoding && curl.encoding === 'base64') - { - // Chunks for an infinite map - if (curl.chunks) - { - for (var i = 0; i < curl.chunks.length; i++) - { - curl.chunks[i].data = Base64Decode(curl.chunks[i].data); - } - } - - // Non-infinite map data - if (curl.data) - { - curl.data = Base64Decode(curl.data); - } - - delete curl.encoding; // Allow the same map to be parsed multiple times - } - - // This is an array containing the tile indexes, one after the other. -1 = no tile, - // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map - // contains multiple tilesets then the indexes are relative to that which the set starts - // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this - // manually it means you can use the same map data but a new tileset. - - var layerData; - var gidInfo; - var tile; - var blankTile; - - var output = []; - var x = 0; - - if (infiniteMap) - { - var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x); - var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y); - - layerData = new LayerData({ - name: (curGroupState.name + curl.name), - x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + layerOffsetX * json.tilewidth), - y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + layerOffsetY * json.tileheight), - width: curl.width, - height: curl.height, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - alpha: (curGroupState.opacity * curl.opacity), - visible: (curGroupState.visible && curl.visible), - properties: GetFastValue(curl, 'properties', []), - orientation: FromOrientationString(json.orientation) - }); - - if (layerData.orientation === CONST.HEXAGONAL) - { - layerData.hexSideLength = json.hexsidelength; - } - - for (var c = 0; c < curl.height; c++) - { - output.push([ null ]); - - for (var j = 0; j < curl.width; j++) - { - output[c][j] = null; - } - } - - for (c = 0, len = curl.chunks.length; c < len; c++) - { - var chunk = curl.chunks[c]; - - var offsetX = (chunk.x - layerOffsetX); - var offsetY = (chunk.y - layerOffsetY); - - var y = 0; - - for (var t = 0, len2 = chunk.data.length; t < len2; t++) - { - var newOffsetX = x + offsetX; - var newOffsetY = y + offsetY; - - gidInfo = ParseGID(chunk.data[t]); - - // index, x, y, width, height - if (gidInfo.gid > 0) - { - tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); - - // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal - // propeties into flipX, flipY and rotation - tile.rotation = gidInfo.rotation; - tile.flipX = gidInfo.flipped; - - output[newOffsetY][newOffsetX] = tile; - } - else - { - blankTile = insertNull - ? null - : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); - - output[newOffsetY][newOffsetX] = blankTile; - } - - x++; - - if (x === chunk.width) - { - y++; - x = 0; - } - } - } - } - else - { - layerData = new LayerData({ - name: (curGroupState.name + curl.name), - x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + curl.x), - y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + curl.y), - width: curl.width, - height: curl.height, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - alpha: (curGroupState.opacity * curl.opacity), - visible: (curGroupState.visible && curl.visible), - properties: GetFastValue(curl, 'properties', []), - orientation: FromOrientationString(json.orientation) - }); - - if (layerData.orientation === CONST.HEXAGONAL) - { - layerData.hexSideLength = json.hexsidelength; - } - var row = []; - - // Loop through the data field in the JSON. - for (var k = 0, len = curl.data.length; k < len; k++) - { - gidInfo = ParseGID(curl.data[k]); - - // index, x, y, width, height - if (gidInfo.gid > 0) - { - tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); - - // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal - // propeties into flipX, flipY and rotation - tile.rotation = gidInfo.rotation; - tile.flipX = gidInfo.flipped; - - row.push(tile); - } - else - { - blankTile = insertNull - ? null - : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); - row.push(blankTile); - } - - x++; - - if (x === curl.width) - { - output.push(row); - x = 0; - row = []; - } - } - } - - layerData.data = output; - tileLayers.push(layerData); - } - - return tileLayers; -}; - -module.exports = ParseTileLayers; - - -/***/ }), -/* 554 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Decode base-64 encoded data, for example as exported by Tiled. - * - * @function Phaser.Tilemaps.Parsers.Tiled.Base64Decode - * @since 3.0.0 - * - * @param {object} data - Base-64 encoded data to decode. - * - * @return {array} Array containing the decoded bytes. - */ -var Base64Decode = function (data) -{ - var binaryString = window.atob(data); - var len = binaryString.length; - var bytes = new Array(len / 4); - - // Interpret binaryString as an array of bytes representing little-endian encoded uint32 values. - for (var i = 0; i < len; i += 4) - { - bytes[i / 4] = ( - binaryString.charCodeAt(i) | - binaryString.charCodeAt(i + 1) << 8 | - binaryString.charCodeAt(i + 2) << 16 | - binaryString.charCodeAt(i + 3) << 24 - ) >>> 0; - } - - return bytes; -}; - -module.exports = Base64Decode; - - -/***/ }), -/* 555 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); -var ImageCollection = __webpack_require__(556); -var ParseObject = __webpack_require__(254); - -/** - * Tilesets and Image Collections - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseTilesets - * @since 3.0.0 - * - * @param {object} json - The Tiled JSON data. - * - * @return {object} An object containing the tileset and image collection data. - */ -var ParseTilesets = function (json) -{ - var tilesets = []; - var imageCollections = []; - var lastSet = null; - var stringID; - - for (var i = 0; i < json.tilesets.length; i++) - { - // name, firstgid, width, height, margin, spacing, properties - var set = json.tilesets[i]; - - if (set.source) - { - console.warn('External tilesets unsupported. Use Embed Tileset and re-export'); - } - else if (set.image) - { - var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); - - if (json.version > 1) - { - // Tiled 1.2+ - - if (Array.isArray(set.tiles)) - { - var tiles = {}; - var props = {}; - - for (var t = 0; t < set.tiles.length; t++) - { - var tile = set.tiles[t]; - - // Convert tileproperties - if (tile.properties) - { - var newPropData = {}; - - tile.properties.forEach(function (propData) - { - newPropData[propData['name']] = propData['value']; - }); - - props[tile.id] = newPropData; - } - - // Convert objectgroup - if (tile.objectgroup) - { - tiles[tile.id] = { objectgroup: tile.objectgroup }; - - if (tile.objectgroup.objects) - { - var parsedObjects2 = tile.objectgroup.objects.map(function (obj) - { - return ParseObject(obj); - }); - - tiles[tile.id].objectgroup.objects = parsedObjects2; - } - } - - // Copy animation data - if (tile.animation) - { - if (tiles.hasOwnProperty(tile.id)) - { - tiles[tile.id].animation = tile.animation; - } - else - { - tiles[tile.id] = { animation: tile.animation }; - } - } - } - - newSet.tileData = tiles; - newSet.tileProperties = props; - } - } - else - { - // Tiled 1 - - // Properties stored per-tile in object with string indexes starting at "0" - if (set.tileproperties) - { - newSet.tileProperties = set.tileproperties; - } - - // Object & terrain shapes stored per-tile in object with string indexes starting at "0" - if (set.tiles) - { - newSet.tileData = set.tiles; - - // Parse the objects into Phaser format to match handling of other Tiled objects - for (stringID in newSet.tileData) - { - var objectGroup = newSet.tileData[stringID].objectgroup; - - if (objectGroup && objectGroup.objects) - { - var parsedObjects1 = objectGroup.objects.map(function (obj) - { - return ParseObject(obj); - }); - - newSet.tileData[stringID].objectgroup.objects = parsedObjects1; - } - } - } - } - - // For a normal sliced tileset the row/count/size information is computed when updated. - // This is done (again) after the image is set. - newSet.updateTileData(set.imagewidth, set.imageheight); - - tilesets.push(newSet); - } - else - { - var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); - - var maxId = 0; - - for (t = 0; t < set.tiles.length; t++) - { - tile = set.tiles[t]; - - var image = tile.image; - var tileId = parseInt(tile.id, 10); - var gid = set.firstgid + tileId; - newCollection.addImage(gid, image); - - maxId = Math.max(tileId, maxId); - } - - newCollection.maxId = maxId; - - imageCollections.push(newCollection); - } - - // We've got a new Tileset, so set the lastgid into the previous one - if (lastSet) - { - lastSet.lastgid = set.firstgid - 1; - } - - lastSet = set; - } - - return { tilesets: tilesets, imageCollections: imageCollections }; -}; - -module.exports = ParseTilesets; - - -/***/ }), -/* 556 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); - -/** - * @classdesc - * An Image Collection is a special Tile Set containing multiple images, with no slicing into each image. - * - * Image Collections are normally created automatically when Tiled data is loaded. - * - * @class ImageCollection - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {string} name - The name of the image collection in the map data. - * @param {number} firstgid - The first image index this image collection contains. - * @param {number} [width=32] - Width of widest image (in pixels). - * @param {number} [height=32] - Height of tallest image (in pixels). - * @param {number} [margin=0] - The margin around all images in the collection (in pixels). - * @param {number} [spacing=0] - The spacing between each image in the collection (in pixels). - * @param {object} [properties={}] - Custom Image Collection properties. - */ -var ImageCollection = new Class({ - - initialize: - - function ImageCollection (name, firstgid, width, height, margin, spacing, properties) - { - if (width === undefined || width <= 0) { width = 32; } - if (height === undefined || height <= 0) { height = 32; } - if (margin === undefined) { margin = 0; } - if (spacing === undefined) { spacing = 0; } - - /** - * The name of the Image Collection. - * - * @name Phaser.Tilemaps.ImageCollection#name - * @type {string} - * @since 3.0.0 - */ - this.name = name; - - /** - * The Tiled firstgid value. - * This is the starting index of the first image index this Image Collection contains. - * - * @name Phaser.Tilemaps.ImageCollection#firstgid - * @type {number} - * @since 3.0.0 - */ - this.firstgid = firstgid | 0; - - /** - * The width of the widest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageWidth - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageWidth = width | 0; - - /** - * The height of the tallest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageHeight - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageHeight = height | 0; - - /** - * The margin around the images in the collection (in pixels). - * Use `setSpacing` to change. - * - * @name Phaser.Tilemaps.ImageCollection#imageMarge - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageMargin = margin | 0; - - /** - * The spacing between each image in the collection (in pixels). - * Use `setSpacing` to change. - * - * @name Phaser.Tilemaps.ImageCollection#imageSpacing - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageSpacing = spacing | 0; - - /** - * Image Collection-specific properties that are typically defined in the Tiled editor. - * - * @name Phaser.Tilemaps.ImageCollection#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = properties || {}; - - /** - * The cached images that are a part of this collection. - * - * @name Phaser.Tilemaps.ImageCollection#images - * @type {array} - * @readonly - * @since 3.0.0 - */ - this.images = []; - - /** - * The total number of images in the image collection. - * - * @name Phaser.Tilemaps.ImageCollection#total - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.total = 0; - }, - - /** - * Returns true if and only if this image collection contains the given image index. - * - * @method Phaser.Tilemaps.ImageCollection#containsImageIndex - * @since 3.0.0 - * - * @param {number} imageIndex - The image index to search for. - * - * @return {boolean} True if this Image Collection contains the given index. - */ - containsImageIndex: function (imageIndex) - { - return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); - }, - - /** - * Add an image to this Image Collection. - * - * @method Phaser.Tilemaps.ImageCollection#addImage - * @since 3.0.0 - * - * @param {number} gid - The gid of the image in the Image Collection. - * @param {string} image - The the key of the image in the Image Collection and in the cache. - * - * @return {Phaser.Tilemaps.ImageCollection} This ImageCollection object. - */ - addImage: function (gid, image) - { - this.images.push({ gid: gid, image: image }); - this.total++; - - return this; - } - -}); - -module.exports = ImageCollection; - - -/***/ }), -/* 557 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Formats = __webpack_require__(37); -var MapData = __webpack_require__(118); -var ParseTileLayers = __webpack_require__(558); -var ParseTilesets = __webpack_require__(559); - -/** - * Parses a Weltmeister JSON object into a new MapData object. - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {object} json - The Weltmeister JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty - * location will get a Tile object with an index of -1. If you've a large sparsely populated map and - * the tile data doesn't need to change then setting this value to `true` will help with memory - * consumption. However if your map is small or you need to update the tiles dynamically, then leave - * the default value set. - * - * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. - */ -var ParseWeltmeister = function (name, json, insertNull) -{ - if (json.layer.length === 0) - { - console.warn('No layers found in the Weltmeister map: ' + name); - return null; - } - - var width = 0; - var height = 0; - - for (var i = 0; i < json.layer.length; i++) - { - if (json.layer[i].width > width) { width = json.layer[i].width; } - if (json.layer[i].height > height) { height = json.layer[i].height; } - } - - var mapData = new MapData({ - width: width, - height: height, - name: name, - tileWidth: json.layer[0].tilesize, - tileHeight: json.layer[0].tilesize, - format: Formats.WELTMEISTER - }); - - mapData.layers = ParseTileLayers(json, insertNull); - mapData.tilesets = ParseTilesets(json); - - return mapData; -}; - -module.exports = ParseWeltmeister; - - -/***/ }), -/* 558 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var LayerData = __webpack_require__(117); -var Tile = __webpack_require__(83); - -/** - * Parses all tilemap layers in an Impact JSON object into new LayerData objects. - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers - * @since 3.0.0 - * - * @param {object} json - The Impact JSON object. - * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map - * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). - * - * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in - * json.layers with the type 'tilelayer'. - */ -var ParseTileLayers = function (json, insertNull) -{ - var tileLayers = []; - - for (var i = 0; i < json.layer.length; i++) - { - var layer = json.layer[i]; - - var layerData = new LayerData({ - name: layer.name, - width: layer.width, - height: layer.height, - tileWidth: layer.tilesize, - tileHeight: layer.tilesize, - visible: layer.visible === 1 - }); - - var row = []; - var tileGrid = []; - - // Loop through the data field in the JSON. This is a 2D array containing the tile indexes, - // one after the other. The indexes are relative to the tileset that contains the tile. - for (var y = 0; y < layer.data.length; y++) - { - for (var x = 0; x < layer.data[y].length; x++) - { - // In Weltmeister, 0 = no tile, but the Tilemap API expects -1 = no tile. - var index = layer.data[y][x] - 1; - - var tile; - - if (index > -1) - { - tile = new Tile(layerData, index, x, y, layer.tilesize, layer.tilesize); - } - else - { - tile = insertNull - ? null - : new Tile(layerData, -1, x, y, layer.tilesize, layer.tilesize); - } - - row.push(tile); - } - - tileGrid.push(row); - row = []; - } - - layerData.data = tileGrid; - - tileLayers.push(layerData); - } - - return tileLayers; -}; - -module.exports = ParseTileLayers; - - -/***/ }), -/* 559 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Tileset = __webpack_require__(119); - -/** - * Tilesets and Image Collections - * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTilesets - * @since 3.0.0 - * - * @param {object} json - The Impact JSON data. - * - * @return {array} An array of Tilesets. - */ -var ParseTilesets = function (json) -{ - var tilesets = []; - var tilesetsNames = []; - - for (var i = 0; i < json.layer.length; i++) - { - var layer = json.layer[i]; - - // A relative filepath to the source image (within Weltmeister) is used for the name - var tilesetName = layer.tilesetName; - - // Only add unique tilesets that have a valid name. Collision layers will have a blank name. - if (tilesetName !== '' && tilesetsNames.indexOf(tilesetName) === -1) - { - tilesetsNames.push(tilesetName); - - // Tiles are stored with an ID relative to the tileset, rather than a globally unique ID - // across all tilesets. Also, tilesets in Weltmeister have no margin or padding. - tilesets.push(new Tileset(tilesetName, 0, layer.tilesize, layer.tilesize, 0, 0)); - } - } - - return tilesets; -}; - -module.exports = ParseTilesets; - - -/***/ }), -/* 560 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); -var Formats = __webpack_require__(37); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(117); -var ORIENTATION = __webpack_require__(29); -var Rotate = __webpack_require__(356); -var SpliceOne = __webpack_require__(74); -var Sprite = __webpack_require__(73); -var Tile = __webpack_require__(83); -var TilemapComponents = __webpack_require__(245); -var TilemapLayer = __webpack_require__(561); -var Tileset = __webpack_require__(119); - -/** - * @callback TilemapFilterCallback - * - * @param {Phaser.GameObjects.GameObject} value - An object found in the filtered area. - * @param {number} index - The index of the object within the array. - * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. - * - * @return {Phaser.GameObjects.GameObject} The object. - */ - -/** - * @callback TilemapFindCallback - * - * @param {Phaser.GameObjects.GameObject} value - An object found. - * @param {number} index - The index of the object within the array. - * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. - * - * @return {boolean} `true` if the callback should be invoked, otherwise `false`. - */ - -/** - * @classdesc - * A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data - * about the map and allows you to add tilesets and tilemap layers to it. A map can have one or - * more tilemap layers, which are the display objects that actually render the tiles. - * - * The Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free - * software package specifically for creating tile maps, and is available from: - * http://www.mapeditor.org - * - * As of Phaser 3.50.0 the Tilemap API now supports the following types of map: - * - * 1) Orthogonal - * 2) Isometric - * 3) Hexagonal - * 4) Staggered - * - * Prior to this release, only orthogonal maps were supported. - * - * Another large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created - * either a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been - * merged and the API simplified, so now there is just the single `TilemapLayer` class. - * - * A Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing - * you to build or modify the tilemap data at runtime. - * - * Note that all Tilemaps use a base tile size to calculate dimensions from, but that a - * TilemapLayer may have its own unique tile size that overrides this. - * - * As of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these - * will be traversed and the following properties will impact children: - * - * - Opacity (blended with parent) and visibility (parent overrides child) - * - Vertical and horizontal offset - * - * The grouping hierarchy is not preserved and all layers will be flattened into a single array. - * - * Group layers are parsed during Tilemap construction but are discarded after parsing so dynamic - * layers will NOT continue to be affected by a parent. - * - * To avoid duplicate layer names, a layer that is a child of a group layer will have its parent - * group name prepended with a '/'. For example, consider a group called 'ParentGroup' with a - * child called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name - * 'ParentGroup/Layer 1'. - * - * @class Tilemap - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. - * @param {Phaser.Tilemaps.MapData} mapData - A MapData instance containing Tilemap data. - */ -var Tilemap = new Class({ - - initialize: - - function Tilemap (scene, mapData) - { - /** - * @name Phaser.Tilemaps.Tilemap#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * The base width of a tile in pixels. Note that individual layers may have a different tile - * width. - * - * @name Phaser.Tilemaps.Tilemap#tileWidth - * @type {number} - * @since 3.0.0 - */ - this.tileWidth = mapData.tileWidth; - - /** - * The base height of a tile in pixels. Note that individual layers may have a different - * tile height. - * - * @name Phaser.Tilemaps.Tilemap#tileHeight - * @type {number} - * @since 3.0.0 - */ - this.tileHeight = mapData.tileHeight; - - /** - * The width of the map (in tiles). - * - * @name Phaser.Tilemaps.Tilemap#width - * @type {number} - * @since 3.0.0 - */ - this.width = mapData.width; - - /** - * The height of the map (in tiles). - * - * @name Phaser.Tilemaps.Tilemap#height - * @type {number} - * @since 3.0.0 - */ - this.height = mapData.height; - - /** - * The orientation of the map data (as specified in Tiled), usually 'orthogonal'. - * - * @name Phaser.Tilemaps.Tilemap#orientation - * @type {string} - * @since 3.0.0 - */ - this.orientation = mapData.orientation; - - /** - * The render (draw) order of the map data (as specified in Tiled), usually 'right-down'. - * - * The draw orders are: - * - * right-down - * left-down - * right-up - * left-up - * - * This can be changed via the `setRenderOrder` method. - * - * @name Phaser.Tilemaps.Tilemap#renderOrder - * @type {string} - * @since 3.12.0 - */ - this.renderOrder = mapData.renderOrder; - - /** - * The format of the map data. - * - * @name Phaser.Tilemaps.Tilemap#format - * @type {number} - * @since 3.0.0 - */ - this.format = mapData.format; - - /** - * The version of the map data (as specified in Tiled, usually 1). - * - * @name Phaser.Tilemaps.Tilemap#version - * @type {number} - * @since 3.0.0 - */ - this.version = mapData.version; - - /** - * Map specific properties as specified in Tiled. - * - * @name Phaser.Tilemaps.Tilemap#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = mapData.properties; - - /** - * The width of the map in pixels based on width * tileWidth. - * - * @name Phaser.Tilemaps.Tilemap#widthInPixels - * @type {number} - * @since 3.0.0 - */ - this.widthInPixels = mapData.widthInPixels; - - /** - * The height of the map in pixels based on height * tileHeight. - * - * @name Phaser.Tilemaps.Tilemap#heightInPixels - * @type {number} - * @since 3.0.0 - */ - this.heightInPixels = mapData.heightInPixels; - - /** - * A collection of Images, as parsed from Tiled map data. - * - * @name Phaser.Tilemaps.Tilemap#imageCollections - * @type {Phaser.Tilemaps.ImageCollection[]} - * @since 3.0.0 - */ - this.imageCollections = mapData.imageCollections; - - /** - * An array of Tiled Image Layers. - * - * @name Phaser.Tilemaps.Tilemap#images - * @type {array} - * @since 3.0.0 - */ - this.images = mapData.images; - - /** - * An array of Tilemap layer data. - * - * @name Phaser.Tilemaps.Tilemap#layers - * @type {Phaser.Tilemaps.LayerData[]} - * @since 3.0.0 - */ - this.layers = mapData.layers; - - /** - * An array of Tilesets used in the map. - * - * @name Phaser.Tilemaps.Tilemap#tilesets - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.0.0 - */ - this.tilesets = mapData.tilesets; - - /** - * An array of ObjectLayer instances parsed from Tiled object layers. - * - * @name Phaser.Tilemaps.Tilemap#objects - * @type {Phaser.Tilemaps.ObjectLayer[]} - * @since 3.0.0 - */ - this.objects = mapData.objects; - - /** - * The index of the currently selected LayerData object. - * - * @name Phaser.Tilemaps.Tilemap#currentLayerIndex - * @type {number} - * @since 3.0.0 - */ - this.currentLayerIndex = 0; - - /** - * The length of the horizontal sides of the hexagon. - * Only used for hexagonal orientation Tilemaps. - * - * @name Phaser.Tilemaps.Tilemap#hexSideLength - * @type {number} - * @since 3.50.0 - */ - this.hexSideLength = mapData.hexSideLength; - - var orientation = this.orientation; - - /** - * Functions used to handle world to tile, and tile to world, conversion. - * Cached here for internal use by public methods such as `worldToTileXY`, etc. - * - * @name Phaser.Tilemaps.Tilemap#_convert - * @private - * @type {object} - * @since 3.50.0 - */ - this._convert = { - WorldToTileXY: TilemapComponents.GetWorldToTileXYFunction(orientation), - WorldToTileX: TilemapComponents.GetWorldToTileXFunction(orientation), - WorldToTileY: TilemapComponents.GetWorldToTileYFunction(orientation), - TileToWorldXY: TilemapComponents.GetTileToWorldXYFunction(orientation), - TileToWorldX: TilemapComponents.GetTileToWorldXFunction(orientation), - TileToWorldY: TilemapComponents.GetTileToWorldYFunction(orientation) - }; - }, - - /** - * @ignore - */ - createBlankDynamicLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) - { - console.warn('createBlankDynamicLayer is deprecated. Use createBlankLayer'); - - return this.createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight); - }, - - /** - * @ignore - */ - createDynamicLayer: function (layerID, tileset, x, y) - { - console.warn('createDynamicLayer is deprecated. Use createLayer'); - - return this.createLayer(layerID, tileset, x, y); - }, - - /** - * @ignore - */ - createStaticLayer: function (layerID, tileset, x, y) - { - console.warn('createStaticLayer is deprecated. Use createLayer'); - - return this.createLayer(layerID, tileset, x, y); - }, - - /** - * Sets the rendering (draw) order of the tiles in this map. - * - * The default is 'right-down', meaning it will order the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * Setting the render order does not change the tiles or how they are stored in the layer, - * it purely impacts the order in which they are rendered. - * - * You can provide either an integer (0 to 3), or the string version of the order. - * - * Calling this method _after_ creating Tilemap Layers will **not** automatically - * update them to use the new render order. If you call this method after creating layers, use their - * own `setRenderOrder` methods to change them as needed. - * - * @method Phaser.Tilemaps.Tilemap#setRenderOrder - * @since 3.12.0 - * - * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. - * - * @return {this} This Tilemap object. - */ - setRenderOrder: function (renderOrder) - { - var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; - - if (typeof renderOrder === 'number') - { - renderOrder = orders[renderOrder]; - } - - if (orders.indexOf(renderOrder) > -1) - { - this.renderOrder = renderOrder; - } - - return this; - }, - - /** - * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. - * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled - * editor. - * - * @method Phaser.Tilemaps.Tilemap#addTilesetImage - * @since 3.0.0 - * - * @param {string} tilesetName - The name of the tileset as specified in the map data. - * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If - * `undefined` or `null` it will look for an image with a key matching the tilesetName parameter. - * @param {number} [tileWidth] - The width of the tile (in pixels) in the Tileset Image. If not - * given it will default to the map's tileWidth value, or the tileWidth specified in the Tiled - * JSON file. - * @param {number} [tileHeight] - The height of the tiles (in pixels) in the Tileset Image. If - * not given it will default to the map's tileHeight value, or the tileHeight specified in the - * Tiled JSON file. - * @param {number} [tileMargin] - The margin around the tiles in the sheet (in pixels). If not - * specified, it will default to 0 or the value specified in the Tiled JSON file. - * @param {number} [tileSpacing] - The spacing between each the tile in the sheet (in pixels). - * If not specified, it will default to 0 or the value specified in the Tiled JSON file. - * @param {number} [gid=0] - If adding multiple tilesets to a blank map, specify the starting - * GID this set will use here. - * - * @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it - * failed. - */ - addTilesetImage: function (tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid) - { - if (tilesetName === undefined) { return null; } - if (key === undefined || key === null) { key = tilesetName; } - - if (!this.scene.sys.textures.exists(key)) - { - console.warn('Invalid Tileset Image: ' + key); - return null; - } - - var texture = this.scene.sys.textures.get(key); - - var index = this.getTilesetIndex(tilesetName); - - if (index === null && this.format === Formats.TILED_JSON) - { - console.warn('No data found for Tileset: ' + tilesetName); - return null; - } - - var tileset = this.tilesets[index]; - - if (tileset) - { - tileset.setTileSize(tileWidth, tileHeight); - tileset.setSpacing(tileMargin, tileSpacing); - tileset.setImage(texture); - - return tileset; - } - - if (tileWidth === undefined) { tileWidth = this.tileWidth; } - if (tileHeight === undefined) { tileHeight = this.tileHeight; } - if (tileMargin === undefined) { tileMargin = 0; } - if (tileSpacing === undefined) { tileSpacing = 0; } - if (gid === undefined) { gid = 0; } - - tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing); - - tileset.setImage(texture); - - this.tilesets.push(tileset); - - return tileset; - }, - - /** - * Copies the tiles in the source rectangular area to a new destination (all specified in tile - * coordinates) within the layer. This copies all tile properties & recalculates collision - * information in the destination region. - * - * If no layer specified, the map's current layer is used. This cannot be applied to StaticTilemapLayers. - * - * @method Phaser.Tilemaps.Tilemap#copy - * @since 3.0.0 - * - * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. - * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. - * @param {number} width - The width of the area to copy, in tiles, not pixels. - * @param {number} height - The height of the area to copy, in tiles, not pixels. - * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. - * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) - { - layer = this.getLayer(layer); - - if (layer !== null) - { - TilemapComponents.Copy( - srcTileX, srcTileY, - width, height, - destTileX, destTileY, - recalculateFaces, layer - ); - - return this; - } - else - { - return null; - } - }, - - /** - * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. - * - * Prior to v3.50.0 this method was called `createBlankDynamicLayer`. - * - * @method Phaser.Tilemaps.Tilemap#createBlankLayer - * @since 3.0.0 - * - * @param {string} name - The name of this layer. Must be unique within the map. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The world x position where the top left of this layer will be placed. - * @param {number} [y=0] - The world y position where the top left of this layer will be placed. - * @param {number} [width] - The width of the layer in tiles. If not specified, it will default to the map's width. - * @param {number} [height] - The height of the layer in tiles. If not specified, it will default to the map's height. - * @param {number} [tileWidth] - The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth. - * @param {number} [tileHeight] - The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight. - * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed. - */ - createBlankLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } - if (tileWidth === undefined) { tileWidth = this.tileWidth; } - if (tileHeight === undefined) { tileHeight = this.tileHeight; } - - var index = this.getLayerIndex(name); - - if (index !== null) - { - console.warn('Invalid Tilemap Layer ID: ' + name); - return null; - } - - var layerData = new LayerData({ - name: name, - tileWidth: tileWidth, - tileHeight: tileHeight, - width: width, - height: height, - orientation: this.orientation - }); - - var row; - - for (var tileY = 0; tileY < height; tileY++) - { - row = []; - - for (var tileX = 0; tileX < width; tileX++) - { - row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight)); - } - - layerData.data.push(row); - } - - this.layers.push(layerData); - - this.currentLayerIndex = this.layers.length - 1; - - var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y); - - layer.setRenderOrder(this.renderOrder); - - this.scene.sys.displayList.add(layer); - - return layer; - }, - - /** - * Creates a new Tilemap Layer that renders the LayerData associated with the given - * `layerID`. The currently selected layer in the map is set to this new layer. - * - * The `layerID` is important. If you've created your map in Tiled then you can get this by - * looking in Tiled and looking at the layer name. Or you can open the JSON file it exports and - * look at the layers[].name value. Either way it must match. - * - * Prior to v3.50.0 this method was called `createDynamicLayer`. - * - * @method Phaser.Tilemaps.Tilemap#createLayer - * @since 3.0.0 - * - * @param {(number|string)} layerID - The layer array index value, or if a string is given, the layer name from Tiled. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. - * @param {number} [y=0] - The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. - * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed. - */ - createLayer: function (layerID, tileset, x, y) - { - var index = this.getLayerIndex(layerID); - - if (index === null) - { - console.warn('Invalid Tilemap Layer ID: ' + layerID); - - if (typeof layerID === 'string') - { - console.warn('Valid tilelayer names:\n\t' + this.getTileLayerNames().join(',\n\t')); - } - - return null; - } - - var layerData = this.layers[index]; - - // Check for an associated static or dynamic tilemap layer - if (layerData.tilemapLayer) - { - console.warn('Tilemap Layer ID already exists:' + layerID); - return null; - } - - this.currentLayerIndex = index; - - // Default the x/y position to match Tiled layer offset, if it exists. - - if (x === undefined) - { - x = layerData.x; - } - - if (y === undefined) - { - y = layerData.y; - } - - var layer = new TilemapLayer(this.scene, this, index, tileset, x, y); - - layer.setRenderOrder(this.renderOrder); - - this.scene.sys.displayList.add(layer); - - return layer; - }, - - /** - * This method will iterate through all of the objects defined in a Tiled Object Layer and then - * convert the matching results into Phaser Game Objects (by default, Sprites) - * - * Objects are matched on one of 3 criteria: The Object ID, the Object GID or the Object Name. - * - * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects - * using the same image. Finally, Object Names are strings and the same name can be used on multiple - * Objects in Tiled, they do not have to be unique. - * - * You set the configuration parameter accordingly, based on which type of criteria you wish - * to match against. For example, to convert all items on an Object Layer with a `gid` of 26: - * - * ```javascript - * createFromObjects(layerName, { - * gid: 26 - * }); - * ``` - * - * Or, to convert objects with the name 'bonus': - * - * ```javascript - * createFromObjects(layerName, { - * name: 'bonus' - * }); - * ``` - * - * Or, to convert an object with a specific id: - * - * ```javascript - * createFromObjects(layerName, { - * id: 9 - * }); - * ``` - * - * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than - * one criteria to your config. If you do not specify any criteria, then _all_ objects in the - * Object Layer will be converted. - * - * By default this method will convert objects into `Sprite` instances, but you can override - * this by providing your own class type: - * - * ```javascript - * createFromObjects(layerName, { - * gid: 26, - * classType: Coin - * }); - * ``` - * - * This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass - * any class type here, but it _must_ extend `Phaser.GameObjects.GameObject` as its base class. - * Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene - * specified in the config object or, if not given, the Scene to which this Tilemap belongs. - * - * All properties from object are copied into the Game Object, so you can use this as an easy - * way to configure properties from within the map editor. For example giving an object a - * property of `alpha: 0.5` in Tiled will be reflected in the Game Object that is created. - * - * Custom object properties that do not exist as a Game Object property are set in the - * Game Objects {@link Phaser.GameObjects.GameObject#data data store}. - * - * You can use set a `container` property in the config. If given, the class will be added to - * the Container instance instead of the Scene. - * - * Finally, you can provide an array of config objects, to convert multiple types of object in - * a single call: - * - * ```javascript - * createFromObjects(layerName, [ - * { - * gid: 26, - * classType: Coin - * }, - * { - * id: 9, - * classType: BossMonster - * }, - * { - * name: 'lava', - * classType: LavaTile - * } - * ]); - * ``` - * - * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. - * - * @method Phaser.Tilemaps.Tilemap#createFromObjects - * @since 3.0.0 - * - * @param {string} objectLayerName - The name of the Tiled object layer to create the Game Objects from. - * @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]} config - A CreateFromObjects configuration object, or an array of them. - * - * @return {Phaser.GameObjects.GameObject[]} An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found. - */ - createFromObjects: function (objectLayerName, config) - { - var results = []; - - var objectLayer = this.getObjectLayer(objectLayerName); - - if (!objectLayer) - { - console.warn('createFromObjects: Invalid objectLayerName given: ' + objectLayerName); - - return results; - } - - if (!Array.isArray(config)) - { - config = [ config ]; - } - - var objects = objectLayer.objects; - - for (var c = 0; c < config.length; c++) - { - var singleConfig = config[c]; - - var id = GetFastValue(singleConfig, 'id', null); - var gid = GetFastValue(singleConfig, 'gid', null); - var name = GetFastValue(singleConfig, 'name', null); - - var obj; - var toConvert = []; - - // Sweep to get all the objects we want to convert in this pass - for (var s = 0; s < objects.length; s++) - { - obj = objects[s]; - - if ( - (id === null && gid === null && name === null) || - (id !== null && obj.id === id) || - (gid !== null && obj.gid === gid) || - (name !== null && obj.name === name) - ) - { - toConvert.push(obj); - } - } - - // Now let's convert them ... - - var classType = GetFastValue(singleConfig, 'classType', Sprite); - var scene = GetFastValue(singleConfig, 'scene', this.scene); - var container = GetFastValue(singleConfig, 'container', null); - var texture = GetFastValue(singleConfig, 'key', null); - var frame = GetFastValue(singleConfig, 'frame', null); - - for (var i = 0; i < toConvert.length; i++) - { - obj = toConvert[i]; - - var sprite = new classType(scene); - - sprite.setName(obj.name); - sprite.setPosition(obj.x, obj.y); - sprite.setTexture(texture, frame); - - if (obj.width) - { - sprite.displayWidth = obj.width; - } - - if (obj.height) - { - sprite.displayHeight = obj.height; - } - - // Origin is (0, 1) in Tiled, so find the offset that matches the Sprites origin. - // Do not offset objects with zero dimensions (e.g. points). - var offset = { - x: sprite.originX * obj.width, - y: (sprite.originY - 1) * obj.height - }; - - // If the object is rotated, then the origin offset also needs to be rotated. - if (obj.rotation) - { - var angle = DegToRad(obj.rotation); - - Rotate(offset, angle); - - sprite.rotation = angle; - } - - sprite.x += offset.x; - sprite.y += offset.y; - - if (obj.flippedHorizontal !== undefined || obj.flippedVertical !== undefined) - { - sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical); - } - - if (!obj.visible) - { - sprite.visible = false; - } - - // Set properties the class may have, or setData those it doesn't - for (var key in obj.properties) - { - if (sprite[key] !== undefined) - { - sprite[key] = obj.properties[key]; - } - else - { - sprite.setData(key, obj.properties[key]); - } - } - - if (container) - { - container.add(sprite); - } - else - { - scene.add.existing(sprite); - } - - results.push(sprite); - } - } - - return results; - }, - - /** - * Creates a Sprite for every object matching the given tile indexes in the layer. You can - * optionally specify if each tile will be replaced with a new tile after the Sprite has been - * created. This is useful if you want to lay down special tiles in a level that are converted to - * Sprites, but want to replace the tile itself with a floor tile or similar once converted. - * - * @method Phaser.Tilemaps.Tilemap#createFromTiles - * @since 3.0.0 - * - * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. - * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted - * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a - * one-to-one mapping with the indexes array. - * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} spriteConfig - The config object to pass into the Sprite creator (i.e. scene.make.sprite). - * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.GameObjects.Sprite[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); - }, - - /** - * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the - * specified index. Tiles will be set to collide if the given index is a colliding index. - * Collision information in the region will be recalculated. - * - * If no layer specified, the map's current layer is used. - * This cannot be applied to StaticTilemapLayers. - * - * @method Phaser.Tilemaps.Tilemap#fill - * @since 3.0.0 - * - * @param {number} index - The tile index to fill the area with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); - - return this; - }, - - /** - * For each object in the given object layer, run the given filter callback function. Any - * objects that pass the filter test (i.e. where the callback returns true) will returned as a - * new array. Similar to Array.prototype.Filter in vanilla JS. - * - * @method Phaser.Tilemaps.Tilemap#filterObjects - * @since 3.0.0 - * - * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. - * @param {TilemapFilterCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * - * @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid. - */ - filterObjects: function (objectLayer, callback, context) - { - if (typeof objectLayer === 'string') - { - var name = objectLayer; - - objectLayer = this.getObjectLayer(objectLayer); - - if (!objectLayer) - { - console.warn('No object layer found with the name: ' + name); - return null; - } - } - - return objectLayer.objects.filter(callback, context); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns - * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#filterTiles - * @since 3.0.0 - * - * @param {function} callback - The callback. Each tile in the given area will be passed to this - * callback as the first and only parameter. The callback should return true for tiles that pass the - * filter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * Searches the entire map layer for the first tile matching the given index, then returns that Tile - * object. If no match is found, it returns null. The search starts from the top-left tile and - * continues horizontally until it hits the end of the row, then it drops down to the next column. - * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to - * the top-left. - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#findByIndex - * @since 3.0.0 - * - * @param {number} index - The tile index value to search for. - * @param {number} [skip=0] - The number of times to skip a matching tile before returning. - * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. - */ - findByIndex: function (findIndex, skip, reverse, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); - }, - - /** - * Find the first object in the given object layer that satisfies the provided testing function. - * I.e. finds the first object for which `callback` returns true. Similar to - * Array.prototype.find in vanilla JS. - * - * @method Phaser.Tilemaps.Tilemap#findObject - * @since 3.0.0 - * - * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. - * @param {TilemapFindCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * - * @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found. - */ - findObject: function (objectLayer, callback, context) - { - if (typeof objectLayer === 'string') - { - var name = objectLayer; - - objectLayer = this.getObjectLayer(objectLayer); - - if (!objectLayer) - { - console.warn('No object layer found with the name: ' + name); - return null; - } - } - - return objectLayer.objects.find(callback, context) || null; - }, - - /** - * Find the first tile in the given rectangular area (in tile coordinates) of the layer that - * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns - * true. Similar to Array.prototype.find in vanilla JS. - * If no layer specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#findTile - * @since 3.0.0 - * - * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. - */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * callback. Similar to Array.prototype.forEach in vanilla JS. - * - * If no layer specified, the map's current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#forEachTile - * @since 3.0.0 - * - * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); - - return this; - }, - - /** - * Gets the image layer index based on its name. - * - * @method Phaser.Tilemaps.Tilemap#getImageIndex - * @since 3.0.0 - * - * @param {string} name - The name of the image to get. - * - * @return {number} The index of the image in this tilemap, or null if not found. - */ - getImageIndex: function (name) - { - return this.getIndex(this.images, name); - }, - - /** - * Return a list of all valid imagelayer names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getImageLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap. - */ - getImageLayerNames: function () - { - if (!this.images || !Array.isArray(this.images)) - { - return []; - } - - return this.images.map(function (image) - { - return image.name; - }); - }, - - /** - * Internally used. Returns the index of the object in one of the Tilemaps arrays whose name - * property matches the given `name`. - * - * @method Phaser.Tilemaps.Tilemap#getIndex - * @since 3.0.0 - * - * @param {array} location - The Tilemap array to search. - * @param {string} name - The name of the array element to get. - * - * @return {number} The index of the element in the array, or null if not found. - */ - getIndex: function (location, name) - { - for (var i = 0; i < location.length; i++) - { - if (location[i].name === name) - { - return i; - } - } - - return null; - }, - - /** - * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. - * - * @method Phaser.Tilemaps.Tilemap#getLayer - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or Tilemap Layer. If not given will default to the maps current layer index. - * - * @return {Phaser.Tilemaps.LayerData} The corresponding LayerData within this.layers. - */ - getLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - return (index !== null) ? this.layers[index] : null; - }, - - /** - * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. - * - * @method Phaser.Tilemaps.Tilemap#getObjectLayer - * @since 3.0.0 - * - * @param {string} [name] - The name of the object layer from Tiled. - * - * @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null. - */ - getObjectLayer: function (name) - { - var index = this.getIndex(this.objects, name); - - return (index !== null) ? this.objects[index] : null; - }, - - /** - * Return a list of all valid objectgroup names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getObjectLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap. - */ - getObjectLayerNames: function () - { - if (!this.objects || !Array.isArray(this.objects)) - { - return []; - } - - return this.objects.map(function (object) - { - return object.name; - }); - }, - - /** - * Gets the LayerData index of the given `layer` within this.layers, or null if an invalid - * `layer` is given. - * - * @method Phaser.Tilemaps.Tilemap#getLayerIndex - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a Tilemap Layer. If not given will default to the map's current layer index. - * - * @return {number} The LayerData index within this.layers. - */ - getLayerIndex: function (layer) - { - if (layer === undefined) - { - return this.currentLayerIndex; - } - else if (typeof layer === 'string') - { - return this.getLayerIndexByName(layer); - } - else if (typeof layer === 'number' && layer < this.layers.length) - { - return layer; - } - else if (layer instanceof TilemapLayer) - { - return layer.layerIndex; - } - else - { - return null; - } - }, - - /** - * Gets the index of the LayerData within this.layers that has the given `name`, or null if an - * invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getLayerIndexByName - * @since 3.0.0 - * - * @param {string} name - The name of the layer to get. - * - * @return {number} The LayerData index within this.layers. - */ - getLayerIndexByName: function (name) - { - return this.getIndex(this.layers, name); - }, - - /** - * Gets a tile at the given tile coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTileAt - * @since 3.0.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {boolean} [nonNull] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - getTileAt: function (tileX, tileY, nonNull, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); - }, - - /** - * Gets a tile at the given world coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - X position to get the tile from (given in pixels) - * @param {number} worldY - Y position to get the tile from (given in pixels) - * @param {boolean} [nonNull] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); - }, - - /** - * Return a list of all valid tilelayer names loaded in this Tilemap. - * - * @method Phaser.Tilemaps.Tilemap#getTileLayerNames - * @since 3.21.0 - * - * @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap. - */ - getTileLayerNames: function () - { - if (!this.layers || !Array.isArray(this.layers)) - { - return []; - } - - return this.layers.map(function (layer) - { - return layer.name; - }); - }, - - /** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithin - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - }, - - /** - * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, - * Line, Rectangle or Triangle. The shape should be in world coordinates. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinShape - * @since 3.0.0 - * - * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithinShape: function (shape, filteringOptions, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); - }, - - /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. - */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); - }, - - /** - * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getTileset - * @since 3.14.0 - * - * @param {string} name - The name of the Tileset to get. - * - * @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found. - */ - getTileset: function (name) - { - var index = this.getIndex(this.tilesets, name); - - return (index !== null) ? this.tilesets[index] : null; - }, - - /** - * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an - * invalid `name` is given. - * - * @method Phaser.Tilemaps.Tilemap#getTilesetIndex - * @since 3.0.0 - * - * @param {string} name - The name of the Tileset to get. - * - * @return {number} The Tileset index within this.tilesets. - */ - getTilesetIndex: function (name) - { - return this.getIndex(this.tilesets, name); - }, - - /** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#hasTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ - hasTileAt: function (tileX, tileY, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.HasTileAt(tileX, tileY, layer); - }, - - /** - * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. - */ - hasTileAtWorldXY: function (worldX, worldY, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); - }, - - /** - * The LayerData object that is currently selected in the map. You can set this property using - * any type supported by setLayer. - * - * @name Phaser.Tilemaps.Tilemap#layer - * @type {Phaser.Tilemaps.LayerData} - * @since 3.0.0 - */ - layer: { - get: function () - { - return this.layers[this.currentLayerIndex]; - }, - - set: function (layer) - { - this.setLayer(layer); - } - }, - - /** - * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index - * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified - * location. If you pass in an index, only the index at the specified location will be changed. - * Collision information will be recalculated at the specified location. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTileAt - * @since 3.0.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid or the coordinates were out of bounds. - */ - putTileAt: function (tile, tileX, tileY, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer); - }, - - /** - * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either - * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the - * specified location. If you pass in an index, only the index at the specified location will be - * changed. Collision information will be recalculated at the specified location. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTileAtWorldXY - * @since 3.0.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer); - }, - - /** - * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified - * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, - * all attributes will be copied over to the specified location. If you pass in an index, only the - * index at the specified location will be changed. Collision information will be recalculated - * within the region tiles were changed. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#putTilesAt - * @since 3.0.0 - * - * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces, layer) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer); - - return this; - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then - * those will be used for randomly assigning new tile indexes. If an array is not provided, the - * indexes found within the region (excluding -1) will be used for randomly assigning new tile - * indexes. This method only modifies tile indexes and does not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#randomize - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - randomize: function (tileX, tileY, width, height, indexes, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer); - - return this; - }, - - /** - * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting - * faces are used internally for optimizing collisions against tiles. This method is mostly used - * internally to optimize recalculating faces when only one tile has been changed. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#calculateFacesAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - calculateFacesAt: function (tileX, tileY, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.CalculateFacesAt(tileX, tileY, layer); - - return this; - }, - - /** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#calculateFacesWithin - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - calculateFacesWithin: function (tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Removes the given TilemapLayer from this Tilemap without destroying it. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeLayer - * @since 3.17.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be removed. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - removeLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - SpliceOne(this.layers, index); - - for (var i = index; i < this.layers.length; i++) - { - if (this.layers[i].tilemapLayer) - { - this.layers[i].tilemapLayer.layerIndex--; - } - } - - if (this.currentLayerIndex === index) - { - this.currentLayerIndex = 0; - } - - return this; - } - else - { - return null; - } - }, - - /** - * Destroys the given TilemapLayer and removes it from this Tilemap. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#destroyLayer - * @since 3.17.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be destroyed. - * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. - */ - destroyLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - layer = this.layers[index]; - - layer.destroy(); - - SpliceOne(this.layers, index); - - if (this.currentLayerIndex === index) - { - this.currentLayerIndex = 0; - } - - return this; - } - else - { - return null; - } - }, - - /** - * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. - * - * @method Phaser.Tilemaps.Tilemap#removeAllLayers - * @since 3.0.0 - * - * @return {this} This Tilemap object. - */ - removeAllLayers: function () - { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) - { - if (layers[i].tilemapLayer) - { - layers[i].tilemapLayer.destroy(false); - } - } - - layers.length = 0; - - this.currentLayerIndex = 0; - - return this; - }, - - /** - * Removes the given Tile, or an array of Tiles, from the layer to which they belong, - * and optionally recalculates the collision information. - * - * @method Phaser.Tilemaps.Tilemap#removeTile - * @since 3.17.0 - * - * @param {(Phaser.Tilemaps.Tile|Phaser.Tilemaps.Tile[])} tiles - The Tile to remove, or an array of Tiles. - * @param {number} [replaceIndex=-1] - After removing the Tile, insert a brand new Tile into its location with the given index. Leave as -1 to just remove the tile. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed. - */ - removeTile: function (tiles, replaceIndex, recalculateFaces) - { - if (replaceIndex === undefined) { replaceIndex = -1; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - var removed = []; - - if (!Array.isArray(tiles)) - { - tiles = [ tiles ]; - } - - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; - - removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); - - if (replaceIndex > -1) - { - this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); - } - } - - return removed; - }, - - /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layers collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeTileAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns the Tile that was removed, or null if the layer given was invalid. - */ - removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces, layer) - { - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); - }, - - /** - * Removes the tile at the given world coordinates in the specified layer and updates the layers collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#removeTileAtWorldXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. - */ - removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) - { - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); - }, - - /** - * Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to - * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles - * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation - * wherever you want on the screen. - * - * If no layer is specified, the maps current layer is used. - * - * **Note:** This method currently only works with orthogonal tilemap layers. - * - * @method Phaser.Tilemaps.Tilemap#renderDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - renderDebug: function (graphics, styleConfig, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - if (this.orientation === ORIENTATION.ORTHOGONAL) - { - TilemapComponents.RenderDebug(graphics, styleConfig, layer); - } - - return this; - }, - - /** - * Draws a debug representation of all layers within this Tilemap to the given Graphics object. - * - * This is helpful when you want to get a quick idea of which of your tiles are colliding and which - * have interesting faces. The tiles are drawn starting at (0, 0) in the Graphics, allowing you to - * place the debug representation wherever you want on the screen. - * - * @method Phaser.Tilemaps.Tilemap#renderDebugFull - * @since 3.17.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * - * @return {this} This Tilemap instance. - */ - renderDebugFull: function (graphics, styleConfig) - { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) - { - TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); - } - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#replaceByIndex - * @since 3.0.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Sets collision on the given tile or tiles within a layer by index. You can pass in either a - * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if - * collision will be enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollision - * @since 3.0.0 - * - * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollision: function (indexes, collides, recalculateFaces, layer, updateLayer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - if (updateLayer === undefined) { updateLayer = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); - - return this; - }, - - /** - * Sets collision on a range of tiles in a layer whose index is between the specified `start` and - * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set - * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be - * enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionBetween - * @since 3.0.0 - * - * @param {number} start - The first index of the tile to be set for collision. - * @param {number} stop - The last index of the tile to be set for collision. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property - * that matches the given properties object, its collision flag will be set. The `collides` - * parameter controls if collision will be enabled (true) or disabled (false). Passing in - * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that - * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can - * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a - * "types" property that matches any of those values, its collision flag will be updated. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionByProperty - * @since 3.0.0 - * - * @param {object} properties - An object with tile properties and corresponding values that should be checked. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionByProperty: function (properties, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on all tiles in the given layer, except for tiles that have an index specified in - * the given array. The `collides` parameter controls if collision will be enabled (true) or - * disabled (false). Tile indexes not currently in the layer are not affected. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion - * @since 3.0.0 - * - * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking each tiles collision group data - * (typically defined in Tiled within the tileset collision editor). If any objects are found within - * a tiles collision group, the tiles colliding information will be set. The `collides` parameter - * controls if collision will be enabled (true) or disabled (false). - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup - * @since 3.0.0 - * - * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setCollisionFromCollisionGroup: function (collides, recalculateFaces, layer) - { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); - - return this; - }, - - /** - * Sets a global collision callback for the given tile index within the layer. This will affect all - * tiles on this layer that have the same index. If a callback is already set for the tile index it - * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile - * at a specific location on the map then see `setTileLocationCallback`. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setTileIndexCallback - * @since 3.0.0 - * - * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. All values should be integers. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} callbackContext - The context under which the callback is called. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setTileIndexCallback: function (indexes, callback, callbackContext, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer); - - return this; - }, - - /** - * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. - * If a callback is already set for the tile index it will be replaced. Set the callback to null to - * remove it. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#setTileLocationCallback - * @since 3.0.0 - * - * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} width - How many tiles wide from the `tileX` index the area will be. - * @param {number} height - How many tiles tall from the `tileY` index the area will be. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} [callbackContext] - The context under which the callback is called. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); - - return this; - }, - - /** - * Sets the current layer to the LayerData associated with `layer`. - * - * @method Phaser.Tilemaps.Tilemap#setLayer - * @since 3.0.0 - * - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. - * - * @return {this} This Tilemap object. - */ - setLayer: function (layer) - { - var index = this.getLayerIndex(layer); - - if (index !== null) - { - this.currentLayerIndex = index; - } - - return this; - }, - - /** - * Sets the base tile size for the map. Note: this does not necessarily match the tileWidth and - * tileHeight for all layers. This also updates the base size on all tiles across all layers. - * - * @method Phaser.Tilemaps.Tilemap#setBaseTileSize - * @since 3.0.0 - * - * @param {number} tileWidth - The width of the tiles the map uses for calculations. - * @param {number} tileHeight - The height of the tiles the map uses for calculations. - * - * @return {this} This Tilemap object. - */ - setBaseTileSize: function (tileWidth, tileHeight) - { - this.tileWidth = tileWidth; - this.tileHeight = tileHeight; - this.widthInPixels = this.width * tileWidth; - this.heightInPixels = this.height * tileHeight; - - // Update the base tile size on all layers & tiles - for (var i = 0; i < this.layers.length; i++) - { - this.layers[i].baseTileWidth = tileWidth; - this.layers[i].baseTileHeight = tileHeight; - - var mapData = this.layers[i].data; - var mapWidth = this.layers[i].width; - var mapHeight = this.layers[i].height; - - for (var row = 0; row < mapHeight; row++) - { - for (var col = 0; col < mapWidth; col++) - { - var tile = mapData[row][col]; - - if (tile !== null) - { - tile.setSize(undefined, undefined, tileWidth, tileHeight); - } - } - } - } - - return this; - }, - - /** - * Sets the tile size for a specific `layer`. Note: this does not necessarily match the maps - * tileWidth and tileHeight for all layers. This will set the tile size for the layer and any - * tiles the layer has. - * - * @method Phaser.Tilemaps.Tilemap#setLayerTileSize - * @since 3.0.0 - * - * @param {number} tileWidth - The width of the tiles (in pixels) in the layer. - * @param {number} tileHeight - The height of the tiles (in pixels) in the layer. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. - * - * @return {this} This Tilemap object. - */ - setLayerTileSize: function (tileWidth, tileHeight, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return this; } - - layer.tileWidth = tileWidth; - layer.tileHeight = tileHeight; - - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; - - for (var row = 0; row < mapHeight; row++) - { - for (var col = 0; col < mapWidth; col++) - { - var tile = mapData[row][col]; - - if (tile !== null) - { - tile.setSize(tileWidth, tileHeight); - } - } - } - - return this; - }, - - /** - * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given - * layer. It will only randomize the tiles in that area, so if they're all the same nothing will - * appear to have changed! This method only modifies tile indexes and does not change collision - * information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#shuffle - * @since 3.0.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - shuffle: function (tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.Shuffle(tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision - * information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#swapByIndex - * @since 3.0.0 - * - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - swapByIndex: function (indexA, indexB, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); - - return this; - }, - - /** - * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldX - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - tileToWorldX: function (tileX, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldX(tileX, camera, layer); - }, - - /** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldY - * @since 3.0.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - tileToWorldY: function (tileX, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldY(tileX, camera, layer); - }, - - /** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#tileToWorldXY - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid. - */ - tileToWorldXY: function (tileX, tileY, vec2, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. New indexes are drawn from the given - * weightedIndexes array. An example weighted array: - * - * [ - * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 - * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 - * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 - * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 - * ] - * - * The probability of any index being picked is (the indexs weight) / (sum of all weights). This - * method only modifies tile indexes and does not change collision information. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#weightedRandomize - * @since 3.0.0 - * - * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. - */ - weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); - - return this; - }, - - /** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileX - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - worldToTileX: function (worldX, snapToFloor, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); - }, - - /** - * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileY - * @since 3.0.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?number} Returns a number, or null if the layer given was invalid. - */ - worldToTileY: function (worldY, snapToFloor, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); - }, - - /** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileXY - * @since 3.0.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. - * - * @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid. - */ - worldToTileXY: function (worldX, worldY, snapToFloor, vec2, camera, layer) - { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); - }, - - /** - * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any - * TilemapLayers that have been created. - * - * @method Phaser.Tilemaps.Tilemap#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.removeAllLayers(); - - this.tilesets.length = 0; - this.objects.length = 0; - - this.scene = null; - } - -}); - -module.exports = Tilemap; - - -/***/ }), -/* 561 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var TilemapComponents = __webpack_require__(245); -var TilemapLayerRender = __webpack_require__(1442); - -/** - * @classdesc - * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination - * with one, or more, Tilesets. - * - * @class TilemapLayer - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.50.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. - * @param {Phaser.Tilemaps.Tilemap} tilemap - The Tilemap this layer is a part of. - * @param {number} layerIndex - The index of the LayerData associated with this layer. - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - * @param {number} [x=0] - The world x position where the top left of this layer will be placed. - * @param {number} [y=0] - The world y position where the top left of this layer will be placed. - */ -var TilemapLayer = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Origin, - Components.Pipeline, - Components.Transform, - Components.Visible, - Components.ScrollFactor, - TilemapLayerRender - ], - - initialize: - - function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) - { - GameObject.call(this, scene, 'TilemapLayer'); - - /** - * Used internally by physics system to perform fast type checks. - * - * @name Phaser.Tilemaps.TilemapLayer#isTilemap - * @type {boolean} - * @readonly - * @since 3.50.0 - */ - this.isTilemap = true; - - /** - * The Tilemap that this layer is a part of. - * - * @name Phaser.Tilemaps.TilemapLayer#tilemap - * @type {Phaser.Tilemaps.Tilemap} - * @since 3.50.0 - */ - this.tilemap = tilemap; - - /** - * The index of the LayerData associated with this layer. - * - * @name Phaser.Tilemaps.TilemapLayer#layerIndex - * @type {number} - * @since 3.50.0 - */ - this.layerIndex = layerIndex; - - /** - * The LayerData associated with this layer. LayerData can only be associated with one - * tilemap layer. - * - * @name Phaser.Tilemaps.TilemapLayer#layer - * @type {Phaser.Tilemaps.LayerData} - * @since 3.50.0 - */ - this.layer = tilemap.layers[layerIndex]; - - // Link the LayerData with this static tilemap layer - this.layer.tilemapLayer = this; - - /** - * An array of `Tileset` objects associated with this layer. - * - * @name Phaser.Tilemaps.TilemapLayer#tileset - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.50.0 - */ - this.tileset = []; - - /** - * The total number of tiles drawn by the renderer in the last frame. - * - * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.tilesDrawn = 0; - - /** - * The total number of tiles in this layer. Updated every frame. - * - * @name Phaser.Tilemaps.TilemapLayer#tilesTotal - * @type {number} - * @readonly - * @since 3.50.0 - */ - this.tilesTotal = this.layer.width * this.layer.height; - - /** - * Used internally during rendering. This holds the tiles that are visible within the Camera. - * - * @name Phaser.Tilemaps.TilemapLayer#culledTiles - * @type {Phaser.Tilemaps.Tile[]} - * @since 3.50.0 - */ - this.culledTiles = []; - - /** - * You can control if the camera should cull tiles on this layer before rendering them or not. - * - * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. - * - * However, there are some instances when you may wish to disable this, and toggling this flag allows - * you to do so. Also see `setSkipCull` for a chainable method that does the same thing. - * - * @name Phaser.Tilemaps.TilemapLayer#skipCull - * @type {boolean} - * @since 3.50.0 - */ - this.skipCull = false; - - /** - * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. - * - * See the method `setCullPadding` for more details. - * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX - * @type {number} - * @default 1 - * @since 3.50.0 - */ - this.cullPaddingX = 1; - - /** - * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. - * - * See the method `setCullPadding` for more details. - * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY - * @type {number} - * @default 1 - * @since 3.50.0 - */ - this.cullPaddingY = 1; - - /** - * The callback that is invoked when the tiles are culled. - * - * It will call a different function based on the map orientation: - * - * Orthogonal (the default) is `TilemapComponents.CullTiles` - * Isometric is `TilemapComponents.IsometricCullTiles` - * Hexagonal is `TilemapComponents.HexagonalCullTiles` - * Staggered is `TilemapComponents.StaggeredCullTiles` - * - * However, you can override this to call any function you like. - * - * It will be sent 4 arguments: - * - * 1. The Phaser.Tilemaps.LayerData object for this Layer - * 2. The Camera that is culling the layer. You can check its `dirty` property to see if it has changed since the last cull. - * 3. A reference to the `culledTiles` array, which should be used to store the tiles you want rendered. - * 4. The Render Order constant. - * - * See the `TilemapComponents.CullTiles` source code for details on implementing your own culling system. - * - * @name Phaser.Tilemaps.TilemapLayer#cullCallback - * @type {function} - * @since 3.50.0 - */ - this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); - - /** - * The rendering (draw) order of the tiles in this layer. - * - * The default is 0 which is 'right-down', meaning it will draw the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * This can be changed via the `setRenderOrder` method. - * - * @name Phaser.Tilemaps.TilemapLayer#_renderOrder - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - this._renderOrder = 0; - - /** - * An array holding the mapping between the tile indexes and the tileset they belong to. - * - * @name Phaser.Tilemaps.TilemapLayer#gidMap - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.50.0 - */ - this.gidMap = []; - - this.setTilesets(tileset); - this.setAlpha(this.layer.alpha); - this.setPosition(x, y); - this.setOrigin(); - this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height); - - this.initPipeline(); - }, - - /** - * Populates the internal `tileset` array with the Tileset references this Layer requires for rendering. - * - * @method Phaser.Tilemaps.TilemapLayer#setTilesets - * @private - * @since 3.50.0 - * - * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. - */ - setTilesets: function (tilesets) - { - var gidMap = []; - var setList = []; - var map = this.tilemap; - - if (!Array.isArray(tilesets)) - { - tilesets = [ tilesets ]; - } - - for (var i = 0; i < tilesets.length; i++) - { - var tileset = tilesets[i]; - - if (typeof tileset === 'string') - { - tileset = map.getTileset(tileset); - } - - if (tileset) - { - setList.push(tileset); - - var s = tileset.firstgid; - - for (var t = 0; t < tileset.total; t++) - { - gidMap[s + t] = tileset; - } - } - } - - this.gidMap = gidMap; - this.tileset = setList; - }, - - /** - * Sets the rendering (draw) order of the tiles in this layer. - * - * The default is 'right-down', meaning it will order the tiles starting from the top-left, - * drawing to the right and then moving down to the next row. - * - * The draw orders are: - * - * 0 = right-down - * 1 = left-down - * 2 = right-up - * 3 = left-up - * - * Setting the render order does not change the tiles or how they are stored in the layer, - * it purely impacts the order in which they are rendered. - * - * You can provide either an integer (0 to 3), or the string version of the order. - * - * @method Phaser.Tilemaps.TilemapLayer#setRenderOrder - * @since 3.50.0 - * - * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. - * - * @return {this} This Tilemap Layer object. - */ - setRenderOrder: function (renderOrder) - { - var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; - - if (typeof renderOrder === 'string') - { - renderOrder = orders.indexOf(renderOrder); - } - - if (renderOrder >= 0 && renderOrder < 4) - { - this._renderOrder = renderOrder; - } - - return this; - }, - - /** - * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting - * faces are used internally for optimizing collisions against tiles. This method is mostly used - * internally to optimize recalculating faces when only one tile has been changed. - * - * @method Phaser.Tilemaps.TilemapLayer#calculateFacesAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. - * - * @return {this} This Tilemap Layer object. - */ - calculateFacesAt: function (tileX, tileY) - { - TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer); - - return this; - }, - - /** - * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the - * layer. Interesting faces are used internally for optimizing collisions against tiles. This method - * is mostly used internally. - * - * @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - calculateFacesWithin: function (tileX, tileY, width, height) - { - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Creates a Sprite for every object matching the given tile indexes in the layer. You can - * optionally specify if each tile will be replaced with a new tile after the Sprite has been - * created. This is useful if you want to lay down special tiles in a level that are converted to - * Sprites, but want to replace the tile itself with a floor tile or similar once converted. - * - * @method Phaser.Tilemaps.TilemapLayer#createFromTiles - * @since 3.50.0 - * - * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. - * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted - * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a - * one-to-one mapping with the indexes array. - * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e. - * scene.make.sprite). - * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when determining the world XY - * - * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. - */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera) - { - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer); - }, - - /** - * Returns the tiles in the given layer that are within the cameras viewport. - * This is used internally during rendering. - * - * @method Phaser.Tilemaps.TilemapLayer#cull - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render. - */ - cull: function (camera) - { - return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder); - }, - - /** - * Copies the tiles in the source rectangular area to a new destination (all specified in tile - * coordinates) within the layer. This copies all tile properties & recalculates collision - * information in the destination region. - * - * @method Phaser.Tilemaps.TilemapLayer#copy - * @since 3.50.0 - * - * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. - * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. - * @param {number} width - The width of the area to copy, in tiles, not pixels. - * @param {number} height - The height of the area to copy, in tiles, not pixels. - * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. - * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) - { - TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the - * specified index. Tiles will be set to collide if the given index is a colliding index. - * Collision information in the region will be recalculated. - * - * @method Phaser.Tilemaps.TilemapLayer#fill - * @since 3.50.0 - * - * @param {number} index - The tile index to fill the area with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - fill: function (index, tileX, tileY, width, height, recalculateFaces) - { - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); - - return this; - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns - * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#filterTiles - * @since 3.50.0 - * - * @param {function} callback - The callback. Each tile in the given area will be passed to this - * callback as the first and only parameter. The callback should return true for tiles that pass the - * filter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. - */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * Searches the entire map layer for the first tile matching the given index, then returns that Tile - * object. If no match is found, it returns null. The search starts from the top-left tile and - * continues horizontally until it hits the end of the row, then it drops down to the next column. - * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to - * the top-left. - * - * @method Phaser.Tilemaps.TilemapLayer#findByIndex - * @since 3.50.0 - * - * @param {number} index - The tile index value to search for. - * @param {number} [skip=0] - The number of times to skip a matching tile before returning. - * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. - * - * @return {Phaser.Tilemaps.Tile} The first matching Tile object. - */ - findByIndex: function (findIndex, skip, reverse) - { - return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer); - }, - - /** - * Find the first tile in the given rectangular area (in tile coordinates) of the layer that - * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns - * true. Similar to Array.prototype.find in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#findTile - * @since 3.50.0 - * - * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location. - */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given - * callback. Similar to Array.prototype.forEach in vanilla JS. - * - * @method Phaser.Tilemaps.TilemapLayer#forEachTile - * @since 3.50.0 - * - * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. - * @param {object} [context] - The context, or scope, under which the callback should be run. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {this} This Tilemap Layer object. - */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions) - { - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - - return this; - }, - - /** - * Gets a tile at the given tile coordinates from the given layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTileAt - * @since 3.50.0 - * - * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). - * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). - * @param {boolean} [nonNull=false] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. - * - * @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ - getTileAt: function (tileX, tileY, nonNull) - { - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer); - }, - - /** - * Gets a tile at the given world coordinates from the given layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - X position to get the tile from (given in pixels) - * @param {number} worldY - Y position to get the tile from (given in pixels) - * @param {boolean} [nonNull=false] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera) - { - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer); - }, - - /** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. - */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions) - { - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer); - }, - - /** - * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, - * Line, Rectangle or Triangle. The shape should be in world coordinates. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape - * @since 3.50.0 - * - * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. - */ - getTilesWithinShape: function (shape, filteringOptions, camera) - { - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); - }, - - /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The world x coordinate for the top-left of the area. - * @param {number} worldY - The world y coordinate for the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. - */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera) - { - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer); - }, - - /** - * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @method Phaser.Tilemaps.TilemapLayer#hasTileAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. - */ - hasTileAt: function (tileX, tileY) - { - return TilemapComponents.HasTileAt(tileX, tileY, this.layer); - }, - - /** - * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns - * false if there is no tile or if the tile at that location has an index of -1. - * - * @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. - * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. - */ - hasTileAtWorldXY: function (worldX, worldY, camera) - { - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); - }, - - /** - * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index - * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified - * location. If you pass in an index, only the index at the specified location will be changed. - * Collision information will be recalculated at the specified location. - * - * @method Phaser.Tilemaps.TilemapLayer#putTileAt - * @since 3.50.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. - */ - putTileAt: function (tile, tileX, tileY, recalculateFaces) - { - return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer); - }, - - /** - * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either - * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the - * specified location. If you pass in an index, only the index at the specified location will be - * changed. Collision information will be recalculated at the specified location. - * - * @method Phaser.Tilemaps.TilemapLayer#putTileAtWorldXY - * @since 3.50.0 - * - * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. - */ - putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera) - { - return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer); - }, - - /** - * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified - * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, - * all attributes will be copied over to the specified location. If you pass in an index, only the - * index at the specified location will be changed. Collision information will be recalculated - * within the region tiles were changed. - * - * @method Phaser.Tilemaps.TilemapLayer#putTilesAt - * @since 3.50.0 - * - * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {this} This Tilemap Layer object. - */ - putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces) - { - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer); - - return this; - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then - * those will be used for randomly assigning new tile indexes. If an array is not provided, the - * indexes found within the region (excluding -1) will be used for randomly assigning new tile - * indexes. This method only modifies tile indexes and does not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#randomize - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. - * - * @return {this} This Tilemap Layer object. - */ - randomize: function (tileX, tileY, width, height, indexes) - { - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); - - return this; - }, - - /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layers - * collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAt - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * - * @return {Phaser.Tilemaps.Tile} A Tile object. - */ - removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces) - { - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer); - }, - - /** - * Removes the tile at the given world coordinates in the specified layer and updates the layers - * collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate, in pixels. - * @param {number} worldY - The y coordinate, in pixels. - * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. - * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location. - */ - removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera) - { - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer); - }, - - /** - * Draws a debug representation of the layer to the given Graphics. This is helpful when you want to - * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles - * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation - * wherever you want on the screen. - * - * @method Phaser.Tilemaps.TilemapLayer#renderDebug - * @since 3.50.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. - * - * @return {this} This Tilemap Layer object. - */ - renderDebug: function (graphics, styleConfig) - { - TilemapComponents.RenderDebug(graphics, styleConfig, this.layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does - * not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#replaceByIndex - * @since 3.50.0 - * - * @param {number} findIndex - The index of the tile to search for. - * @param {number} newIndex - The index of the tile to replace it with. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height) - { - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * You can control if the Cameras should cull tiles before rendering them or not. - * - * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. - * - * However, there are some instances when you may wish to disable this. - * - * @method Phaser.Tilemaps.TilemapLayer#setSkipCull - * @since 3.50.0 - * - * @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again. - * - * @return {this} This Tilemap Layer object. - */ - setSkipCull: function (value) - { - if (value === undefined) { value = true; } - - this.skipCull = value; - - return this; - }, - - /** - * When a Camera culls the tiles in this layer it does so using its view into the world, building up a - * rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size - * of this 'cull rectangle', especially if you plan on rotating the Camera viewing the layer. Do so - * by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px - * and you set `paddingX` to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale) - * - * @method Phaser.Tilemaps.TilemapLayer#setCullPadding - * @since 3.50.0 - * - * @param {number} [paddingX=1] - The amount of extra horizontal tiles to add to the cull check padding. - * @param {number} [paddingY=1] - The amount of extra vertical tiles to add to the cull check padding. - * - * @return {this} This Tilemap Layer object. - */ - setCullPadding: function (paddingX, paddingY) - { - if (paddingX === undefined) { paddingX = 1; } - if (paddingY === undefined) { paddingY = 1; } - - this.cullPaddingX = paddingX; - this.cullPaddingY = paddingY; - - return this; - }, - - /** - * Sets collision on the given tile or tiles within a layer by index. You can pass in either a - * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if - * collision will be enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollision - * @since 3.50.0 - * - * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. - * - * @return {this} This Tilemap Layer object. - */ - setCollision: function (indexes, collides, recalculateFaces, updateLayer) - { - TilemapComponents.SetCollision(indexes, collides, recalculateFaces, this.layer, updateLayer); - - return this; - }, - - /** - * Sets collision on a range of tiles in a layer whose index is between the specified `start` and - * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set - * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be - * enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween - * @since 3.50.0 - * - * @param {number} start - The first index of the tile to be set for collision. - * @param {number} stop - The last index of the tile to be set for collision. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionBetween: function (start, stop, collides, recalculateFaces) - { - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property - * that matches the given properties object, its collision flag will be set. The `collides` - * parameter controls if collision will be enabled (true) or disabled (false). Passing in - * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that - * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can - * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a - * "types" property that matches any of those values, its collision flag will be updated. - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionByProperty - * @since 3.50.0 - * - * @param {object} properties - An object with tile properties and corresponding values that should be checked. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionByProperty: function (properties, collides, recalculateFaces) - { - TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on all tiles in the given layer, except for tiles that have an index specified in - * the given array. The `collides` parameter controls if collision will be enabled (true) or - * disabled (false). Tile indexes not currently in the layer are not affected. - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion - * @since 3.50.0 - * - * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces) - { - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets collision on the tiles within a layer by checking each tiles collision group data - * (typically defined in Tiled within the tileset collision editor). If any objects are found within - * a tiles collision group, the tile's colliding information will be set. The `collides` parameter - * controls if collision will be enabled (true) or disabled (false). - * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup - * @since 3.50.0 - * - * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. - * - * @return {this} This Tilemap Layer object. - */ - setCollisionFromCollisionGroup: function (collides, recalculateFaces) - { - TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer); - - return this; - }, - - /** - * Sets a global collision callback for the given tile index within the layer. This will affect all - * tiles on this layer that have the same index. If a callback is already set for the tile index it - * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile - * at a specific location on the map then see setTileLocationCallback. - * - * @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback - * @since 3.50.0 - * - * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. - * @param {function} callback - The callback that will be invoked when the tile is collided with. - * @param {object} callbackContext - The context under which the callback is called. - * - * @return {this} This Tilemap Layer object. - */ - setTileIndexCallback: function (indexes, callback, callbackContext) - { - TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer); - - return this; - }, - - /** - * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. - * If a callback is already set for the tile index it will be replaced. Set the callback to null to - * remove it. - * - * @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * @param {function} [callback] - The callback that will be invoked when the tile is collided with. - * @param {object} [callbackContext] - The context, or scope, under which the callback is invoked. - * - * @return {this} This Tilemap Layer object. - */ - setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext) - { - TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer); - - return this; - }, - - /** - * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given - * layer. It will only randomize the tiles in that area, so if they're all the same nothing will - * appear to have changed! This method only modifies tile indexes and does not change collision - * information. - * - * @method Phaser.Tilemaps.TilemapLayer#shuffle - * @since 3.50.0 - * - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - shuffle: function (tileX, tileY, width, height) - { - TilemapComponents.Shuffle(tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching - * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision - * information. - * - * @method Phaser.Tilemaps.TilemapLayer#swapByIndex - * @since 3.50.0 - * - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - swapByIndex: function (indexA, indexB, tileX, tileY, width, height) - { - TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, this.layer); - - return this; - }, - - /** - * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldX - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The Tile X coordinate converted to pixels. - */ - tileToWorldX: function (tileX, camera) - { - return this.tilemap.tileToWorldX(tileX, camera, this); - }, - - /** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldY - * @since 3.50.0 - * - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The Tile Y coordinate converted to pixels. - */ - tileToWorldY: function (tileY, camera) - { - return this.tilemap.tileToWorldY(tileY, camera, this); - }, - - /** - * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @method Phaser.Tilemaps.TilemapLayer#tileToWorldXY - * @since 3.50.0 - * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. - * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Math.Vector2} A Vector2 containing the world coordinates of the Tile. - */ - tileToWorldXY: function (tileX, tileY, point, camera) - { - return this.tilemap.tileToWorldXY(tileX, tileY, point, camera, this); - }, - - /** - * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the - * specified layer. Each tile will receive a new index. New indexes are drawn from the given - * weightedIndexes array. An example weighted array: - * - * [ - * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 - * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 - * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 - * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 - * ] - * - * The probability of any index being choose is (the index's weight) / (sum of all weights). This - * method only modifies tile indexes and does not change collision information. - * - * @method Phaser.Tilemaps.TilemapLayer#weightedRandomize - * @since 3.50.0 - * - * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. - * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. - * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. - * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. - * - * @return {this} This Tilemap Layer object. - */ - weightedRandomize: function (tileX, tileY, width, height, weightedIndexes) - { - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); - - return this; - }, - - /** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileX - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The tile X coordinate based on the world value. - */ - worldToTileX: function (worldX, snapToFloor, camera) - { - return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this); - }, - - /** - * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileY - * @since 3.50.0 - * - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {number} The tile Y coordinate based on the world value. - */ - worldToTileY: function (worldY, snapToFloor, camera) - { - return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); - }, - - /** - * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the - * layers position, scale and scroll. This will return a new Vector2 object or update the given - * `point` object. - * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileXY - * @since 3.50.0 - * - * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. - * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. - * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. - * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. - * - * @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values. - */ - worldToTileXY: function (worldX, worldY, snapToFloor, point, camera) - { - return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this); - }, - - /** - * Destroys this TilemapLayer and removes its link to the associated LayerData. - * - * @method Phaser.Tilemaps.TilemapLayer#destroy - * @since 3.50.0 - * - * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? - */ - destroy: function (removeFromTilemap) - { - if (removeFromTilemap === undefined) { removeFromTilemap = true; } - - if (!this.tilemap) - { - // Abort, we've already been destroyed - return; - } - - // Uninstall this layer only if it is still installed on the LayerData object - if (this.layer.tilemapLayer === this) - { - this.layer.tilemapLayer = undefined; - } - - if (removeFromTilemap) - { - this.tilemap.removeLayer(this); - } - - this.tilemap = undefined; - this.layer = undefined; - this.culledTiles.length = 0; - this.cullCallback = null; - - this.gidMap = []; - this.tileset = []; - - GameObject.prototype.destroy.call(this); - } - -}); - -module.exports = TilemapLayer; - - -/***/ }), -/* 562 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); - -/** - * @classdesc - * A Timer Event represents a delayed function call. It's managed by a Scene's {@link Clock} and will call its function after a set amount of time has passed. The Timer Event can optionally repeat - i.e. call its function multiple times before finishing, or loop indefinitely. - * - * Because it's managed by a Clock, a Timer Event is based on game time, will be affected by its Clock's time scale, and will pause if its Clock pauses. - * - * @class TimerEvent - * @memberof Phaser.Time - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.Time.TimerEventConfig} config - The configuration for the Timer Event, including its delay and callback. - */ -var TimerEvent = new Class({ - - initialize: - - function TimerEvent (config) - { - /** - * The delay in ms at which this TimerEvent fires. - * - * @name Phaser.Time.TimerEvent#delay - * @type {number} - * @default 0 - * @readonly - * @since 3.0.0 - */ - this.delay = 0; - - /** - * The total number of times this TimerEvent will repeat before finishing. - * - * @name Phaser.Time.TimerEvent#repeat - * @type {number} - * @default 0 - * @readonly - * @since 3.0.0 - */ - this.repeat = 0; - - /** - * If repeating this contains the current repeat count. - * - * @name Phaser.Time.TimerEvent#repeatCount - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeatCount = 0; - - /** - * True if this TimerEvent loops, otherwise false. - * - * @name Phaser.Time.TimerEvent#loop - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.loop = false; - - /** - * The callback that will be called when the TimerEvent occurs. - * - * @name Phaser.Time.TimerEvent#callback - * @type {function} - * @since 3.0.0 - */ - this.callback; - - /** - * The scope in which the callback will be called. - * - * @name Phaser.Time.TimerEvent#callbackScope - * @type {object} - * @since 3.0.0 - */ - this.callbackScope; - - /** - * Additional arguments to be passed to the callback. - * - * @name Phaser.Time.TimerEvent#args - * @type {array} - * @since 3.0.0 - */ - this.args; - - /** - * Scale the time causing this TimerEvent to update. - * - * @name Phaser.Time.TimerEvent#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly) - * - * @name Phaser.Time.TimerEvent#startAt - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.startAt = 0; - - /** - * The time in milliseconds which has elapsed since the Timer Event's creation. - * - * This value is local for the Timer Event and is relative to its Clock. As such, it's influenced by the Clock's time scale and paused state, the Timer Event's initial {@link #startAt} property, and the Timer Event's {@link #timeScale} and {@link #paused} state. - * - * @name Phaser.Time.TimerEvent#elapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.elapsed = 0; - - /** - * Whether or not this timer is paused. - * - * @name Phaser.Time.TimerEvent#paused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.paused = false; - - /** - * Whether the Timer Event's function has been called. - * - * When the Timer Event fires, this property will be set to `true` before the callback function is invoked and will be reset immediately afterward if the Timer Event should repeat. The value of this property does not directly influence whether the Timer Event will be removed from its Clock, but can prevent it from firing. - * - * @name Phaser.Time.TimerEvent#hasDispatched - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.hasDispatched = false; - - this.reset(config); - }, - - /** - * Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object. - * - * @method Phaser.Time.TimerEvent#reset - * @since 3.0.0 - * - * @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event. - * - * @return {Phaser.Time.TimerEvent} This TimerEvent object. - */ - reset: function (config) - { - this.delay = GetFastValue(config, 'delay', 0); - - // Can also be set to -1 for an infinite loop (same as setting loop: true) - this.repeat = GetFastValue(config, 'repeat', 0); - - this.loop = GetFastValue(config, 'loop', false); - - this.callback = GetFastValue(config, 'callback', undefined); - - this.callbackScope = GetFastValue(config, 'callbackScope', this.callback); - - this.args = GetFastValue(config, 'args', []); - - this.timeScale = GetFastValue(config, 'timeScale', 1); - - this.startAt = GetFastValue(config, 'startAt', 0); - - this.paused = GetFastValue(config, 'paused', false); - - this.elapsed = this.startAt; - this.hasDispatched = false; - this.repeatCount = (this.repeat === -1 || this.loop) ? 999999999999 : this.repeat; - - return this; - }, - - /** - * Gets the progress of the current iteration, not factoring in repeats. - * - * @method Phaser.Time.TimerEvent#getProgress - * @since 3.0.0 - * - * @return {number} A number between 0 and 1 representing the current progress. - */ - getProgress: function () - { - return (this.elapsed / this.delay); - }, - - /** - * Gets the progress of the timer overall, factoring in repeats. - * - * @method Phaser.Time.TimerEvent#getOverallProgress - * @since 3.0.0 - * - * @return {number} The overall progress of the Timer Event, between 0 and 1. - */ - getOverallProgress: function () - { - if (this.repeat > 0) - { - var totalDuration = this.delay + (this.delay * this.repeat); - var totalElapsed = this.elapsed + (this.delay * (this.repeat - this.repeatCount)); - - return (totalElapsed / totalDuration); - } - else - { - return this.getProgress(); - } - }, - - /** - * Returns the number of times this Timer Event will repeat before finishing. - * - * This should not be confused with the number of times the Timer Event will fire before finishing. A return value of 0 doesn't indicate that the Timer Event has finished running - it indicates that it will not repeat after the next time it fires. - * - * @method Phaser.Time.TimerEvent#getRepeatCount - * @since 3.0.0 - * - * @return {number} How many times the Timer Event will repeat. - */ - getRepeatCount: function () - { - return this.repeatCount; - }, - - /** - * Returns the local elapsed time for the current iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getElapsed - * @since 3.0.0 - * - * @return {number} The local elapsed time in milliseconds. - */ - getElapsed: function () - { - return this.elapsed; - }, - - /** - * Returns the local elapsed time for the current iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getElapsedSeconds - * @since 3.0.0 - * - * @return {number} The local elapsed time in seconds. - */ - getElapsedSeconds: function () - { - return this.elapsed * 0.001; - }, - - /** - * Returns the time interval until the next iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getRemaining - * @since 3.50.0 - * - * @return {number} The time interval in milliseconds. - */ - getRemaining: function () - { - return this.delay - this.elapsed; - }, - - /** - * Returns the time interval until the next iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getRemainingSeconds - * @since 3.50.0 - * - * @return {number} The time interval in seconds. - */ - getRemainingSeconds: function () - { - return this.getRemaining() * 0.001; - }, - - /** - * Returns the time interval until the last iteration of the Timer Event. - * - * @method Phaser.Time.TimerEvent#getOverallRemaining - * @since 3.50.0 - * - * @return {number} The time interval in milliseconds. - */ - getOverallRemaining: function () - { - return this.delay * (1 + this.repeatCount) - this.elapsed; - }, - - /** - * Returns the time interval until the last iteration of the Timer Event in seconds. - * - * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds - * @since 3.50.0 - * - * @return {number} The time interval in seconds. - */ - getOverallRemainingSeconds: function () - { - return this.getOverallRemaining() * 0.001; - }, - - /** - * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. - * - * @method Phaser.Time.TimerEvent#remove - * @since 3.0.0 - * - * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. - */ - remove: function (dispatchCallback) - { - if (dispatchCallback === undefined) { dispatchCallback = false; } - - this.elapsed = this.delay; - - this.hasDispatched = !dispatchCallback; - - this.repeatCount = 0; - }, - - /** - * Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments. - * - * Normally, this method is only called by the Clock when it shuts down. As such, it doesn't stop the Timer Event. If called manually, the Timer Event will still be updated by the Clock, but it won't do anything when it fires. - * - * @method Phaser.Time.TimerEvent#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.callback = undefined; - this.callbackScope = undefined; - this.args = []; - } - -}); - -module.exports = TimerEvent; - - -/***/ }), -/* 563 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var RESERVED = __webpack_require__(1451); - -/** - * Internal function used by the Tween Builder to return an array of properties - * that the Tween will be operating on. It takes a tween configuration object - * and then checks that none of the `props` entries start with an underscore, or that - * none of the direct properties are on the Reserved list. - * - * @function Phaser.Tweens.Builders.GetProps - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TweenBuilderConfig} config - The configuration object of the Tween to get the properties from. - * - * @return {string[]} An array of all the properties the tween will operate on. - */ -var GetProps = function (config) -{ - var key; - var keys = []; - - // First see if we have a props object - - if (config.hasOwnProperty('props')) - { - for (key in config.props) - { - // Skip any property that starts with an underscore - if (key.substr(0, 1) !== '_') - { - keys.push({ key: key, value: config.props[key] }); - } - } - } - else - { - for (key in config) - { - // Skip any property that is in the ReservedProps list or that starts with an underscore - if (RESERVED.indexOf(key) === -1 && key.substr(0, 1) !== '_') - { - keys.push({ key: key, value: config[key] }); - } - } - } - - return keys; -}; - -module.exports = GetProps; - - -/***/ }), -/* 564 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetValue = __webpack_require__(6); - -/** - * Internal function used by the Timeline Builder. - * - * It returns an array of all tweens in the given timeline config. - * - * @function Phaser.Tweens.Builders.GetTweens - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. - * - * @return {Phaser.Tweens.Tween[]} An array of Tween instances that the Timeline will manage. - */ -var GetTweens = function (config) -{ - var tweens = GetValue(config, 'tweens', null); - - if (tweens === null) - { - return []; - } - else if (typeof tweens === 'function') - { - tweens = tweens.call(); - } - - if (!Array.isArray(tweens)) - { - tweens = [ tweens ]; - } - - return tweens; -}; - -module.exports = GetTweens; - - -/***/ }), -/* 565 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Defaults = __webpack_require__(259); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(96); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(258); -var Tween = __webpack_require__(260); -var TweenData = __webpack_require__(262); - -/** - * Creates a new Number Tween. - * - * @function Phaser.Tweens.Builders.NumberTweenBuilder - * @since 3.0.0 - * - * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - The owner of the new Tween. - * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - Configuration for the new Tween. - * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. - * - * @return {Phaser.Tweens.Tween} The new tween. - */ -var NumberTweenBuilder = function (parent, config, defaults) -{ - if (defaults === undefined) - { - defaults = Defaults; - } - - // var tween = this.tweens.addCounter({ - // from: 100, - // to: 200, - // ... (normal tween properties) - // }) - // - // Then use it in your game via: - // - // tween.getValue() - - var from = GetValue(config, 'from', 0); - var to = GetValue(config, 'to', 1); - - var targets = [ { value: from } ]; - - var delay = GetNewValue(config, 'delay', defaults.delay); - var duration = GetNewValue(config, 'duration', defaults.duration); - var easeParams = GetValue(config, 'easeParams', defaults.easeParams); - var ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), easeParams); - var hold = GetNewValue(config, 'hold', defaults.hold); - var repeat = GetNewValue(config, 'repeat', defaults.repeat); - var repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); - var yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); - - var data = []; - - var ops = GetValueOp('value', to); - - var tweenData = TweenData( - targets[0], - 0, - 'value', - ops.getEnd, - ops.getStart, - ops.getActive, - ease, - delay, - duration, - yoyo, - hold, - repeat, - repeatDelay, - false, - false - ); - - tweenData.start = from; - tweenData.current = from; - tweenData.to = to; - - data.push(tweenData); - - var tween = new Tween(parent, data, targets); - - tween.offset = GetAdvancedValue(config, 'offset', null); - tween.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); - tween.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); - tween.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); - tween.paused = GetBoolean(config, 'paused', false); - tween.useFrames = GetBoolean(config, 'useFrames', false); - - // Set the Callbacks - var scope = GetValue(config, 'callbackScope', tween); - - // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params - var tweenArray = [ tween, null ]; - - var callbacks = Tween.TYPES; - - for (var i = 0; i < callbacks.length; i++) - { - var type = callbacks[i]; - - var callback = GetValue(config, type, false); - - if (callback) - { - var callbackScope = GetValue(config, type + 'Scope', scope); - var callbackParams = GetValue(config, type + 'Params', []); - - // The null is reset to be the Tween target - tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); - } - } - - return tween; -}; - -module.exports = NumberTweenBuilder; - - -/***/ }), -/* 566 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetEaseFunction = __webpack_require__(80); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); - -/** - * Creates a Stagger function to be used by a Tween property. - * - * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. - * - * This is only worth using if the tween has multiple targets. - * - * The following will stagger the delay by 100ms across all targets of the tween, causing them to scale down to 0.2 - * over the duration specified: - * - * ```javascript - * this.tweens.add({ - * targets: [ ... ], - * scale: 0.2, - * ease: 'linear', - * duration: 1000, - * delay: this.tweens.stagger(100) - * }); - * ``` - * - * The following will stagger the delay by 500ms across all targets of the tween using a 10 x 6 grid, staggering - * from the center out, using a cubic ease. - * - * ```javascript - * this.tweens.add({ - * targets: [ ... ], - * scale: 0.2, - * ease: 'linear', - * duration: 1000, - * delay: this.tweens.stagger(500, { grid: [ 10, 6 ], from: 'center', ease: 'cubic.out' }) - * }); - * ``` - * - * @function Phaser.Tweens.Builders.StaggerBuilder - * @since 3.19.0 - * - * @param {(number|number[])} value - The amount to stagger by, or an array containing two elements representing the min and max values to stagger between. - * @param {Phaser.Types.Tweens.StaggerConfig} [config] - A Stagger Configuration object. - * - * @return {function} The stagger function. - */ -var StaggerBuilder = function (value, options) -{ - if (options === undefined) { options = {}; } - - var result; - - var start = GetValue(options, 'start', 0); - var ease = GetValue(options, 'ease', null); - var grid = GetValue(options, 'grid', null); - - var from = GetValue(options, 'from', 0); - - var fromFirst = (from === 'first'); - var fromCenter = (from === 'center'); - var fromLast = (from === 'last'); - var fromValue = (typeof(from) === 'number'); - - var isRange = (Array.isArray(value)); - var value1 = (isRange) ? parseFloat(value[0]) : parseFloat(value); - var value2 = (isRange) ? parseFloat(value[1]) : 0; - var maxValue = Math.max(value1, value2); - - if (isRange) - { - start += value1; - } - - if (grid) - { - // Pre-calc the grid to save doing it for ever tweendata update - var gridWidth = grid[0]; - var gridHeight = grid[1]; - - var fromX = 0; - var fromY = 0; - - var distanceX = 0; - var distanceY = 0; - - var gridValues = []; - - if (fromLast) - { - fromX = gridWidth - 1; - fromY = gridHeight - 1; - } - else if (fromValue) - { - fromX = from % gridWidth; - fromY = Math.floor(from / gridWidth); - } - else if (fromCenter) - { - fromX = (gridWidth - 1) / 2; - fromY = (gridHeight - 1) / 2; - } - - var gridMax = MATH_CONST.MIN_SAFE_INTEGER; - - for (var toY = 0; toY < gridHeight; toY++) - { - gridValues[toY] = []; - - for (var toX = 0; toX < gridWidth; toX++) - { - distanceX = fromX - toX; - distanceY = fromY - toY; - - var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); - - if (dist > gridMax) - { - gridMax = dist; - } - - gridValues[toY][toX] = dist; - } - } - } - - var easeFunction = (ease) ? GetEaseFunction(ease) : null; - - if (grid) - { - result = function (target, key, value, index) - { - var gridSpace = 0; - var toX = index % gridWidth; - var toY = Math.floor(index / gridWidth); - - if (toX >= 0 && toX < gridWidth && toY >= 0 && toY < gridHeight) - { - gridSpace = gridValues[toY][toX]; - } - - var output; - - if (isRange) - { - var diff = (value2 - value1); - - if (easeFunction) - { - output = ((gridSpace / gridMax) * diff) * easeFunction(gridSpace / gridMax); - } - else - { - output = (gridSpace / gridMax) * diff; - } - } - else if (easeFunction) - { - output = (gridSpace * value1) * easeFunction(gridSpace / gridMax); - } - else - { - output = gridSpace * value1; - } - - return output + start; - }; - } - else - { - result = function (target, key, value, index, total) - { - // zero offset - total--; - - var fromIndex; - - if (fromFirst) - { - fromIndex = index; - } - else if (fromCenter) - { - fromIndex = Math.abs((total / 2) - index); - } - else if (fromLast) - { - fromIndex = total - index; - } - else if (fromValue) - { - fromIndex = Math.abs(from - index); - } - - var output; - - if (isRange) - { - var spacing; - - if (fromCenter) - { - spacing = ((value2 - value1) / total) * (fromIndex * 2); - } - else - { - spacing = ((value2 - value1) / total) * fromIndex; - } - - if (easeFunction) - { - output = spacing * easeFunction(fromIndex / total); - } - else - { - output = spacing; - } - } - else if (easeFunction) - { - output = (total * maxValue) * easeFunction(fromIndex / total); - } - else - { - output = fromIndex * value1; - } - - return output + start; - }; - } - - return result; -}; - -module.exports = StaggerBuilder; - - -/***/ }), -/* 567 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Clone = __webpack_require__(77); -var Defaults = __webpack_require__(259); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(96); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(159); -var GetTargets = __webpack_require__(257); -var GetTweens = __webpack_require__(564); -var GetValue = __webpack_require__(6); -var Timeline = __webpack_require__(568); -var TweenBuilder = __webpack_require__(160); - -/** - * Builds a Timeline of Tweens based on a configuration object. - * - * @function Phaser.Tweens.Builders.TimelineBuilder - * @since 3.0.0 - * - * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager to which the Timeline will belong. - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. - * - * @return {Phaser.Tweens.Timeline} The created Timeline. - */ -var TimelineBuilder = function (manager, config) -{ - var timeline = new Timeline(manager); - - timeline.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); - timeline.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); - timeline.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); - timeline.paused = GetBoolean(config, 'paused', false); - timeline.useFrames = GetBoolean(config, 'useFrames', false); - - // Callbacks - - var scope = GetValue(config, 'callbackScope', timeline); - - var timelineArray = [ timeline ]; - - var onStart = GetValue(config, 'onStart', false); - - // The Start of the Timeline - if (onStart) - { - var onStartScope = GetValue(config, 'onStartScope', scope); - var onStartParams = GetValue(config, 'onStartParams', []); - - timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope); - } - - var onUpdate = GetValue(config, 'onUpdate', false); - - // Every time the Timeline updates (regardless which Tweens are running) - if (onUpdate) - { - var onUpdateScope = GetValue(config, 'onUpdateScope', scope); - var onUpdateParams = GetValue(config, 'onUpdateParams', []); - - timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope); - } - - var onLoop = GetValue(config, 'onLoop', false); - - // Called when the whole Timeline loops - if (onLoop) - { - var onLoopScope = GetValue(config, 'onLoopScope', scope); - var onLoopParams = GetValue(config, 'onLoopParams', []); - - timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope); - } - - var onYoyo = GetValue(config, 'onYoyo', false); - - // Called when a Timeline yoyos - if (onYoyo) - { - var onYoyoScope = GetValue(config, 'onYoyoScope', scope); - var onYoyoParams = GetValue(config, 'onYoyoParams', []); - - timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope); - } - - var onComplete = GetValue(config, 'onComplete', false); - - // Called when the Timeline completes, after the completeDelay, etc. - if (onComplete) - { - var onCompleteScope = GetValue(config, 'onCompleteScope', scope); - var onCompleteParams = GetValue(config, 'onCompleteParams', []); - - timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope); - } - - // Tweens - - var tweens = GetTweens(config); - - if (tweens.length === 0) - { - timeline.paused = true; - - return timeline; - } - - var defaults = Clone(Defaults); - - defaults.targets = GetTargets(config); - - // totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration - - var totalDuration = GetAdvancedValue(config, 'totalDuration', 0); - - if (totalDuration > 0) - { - defaults.duration = Math.floor(totalDuration / tweens.length); - } - else - { - defaults.duration = GetNewValue(config, 'duration', defaults.duration); - } - - defaults.delay = GetNewValue(config, 'delay', defaults.delay); - defaults.easeParams = GetValue(config, 'easeParams', defaults.easeParams); - defaults.ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), defaults.easeParams); - defaults.hold = GetNewValue(config, 'hold', defaults.hold); - defaults.repeat = GetNewValue(config, 'repeat', defaults.repeat); - defaults.repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); - defaults.yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); - defaults.flipX = GetBoolean(config, 'flipX', defaults.flipX); - defaults.flipY = GetBoolean(config, 'flipY', defaults.flipY); - - // Create the Tweens - for (var i = 0; i < tweens.length; i++) - { - timeline.queue(TweenBuilder(timeline, tweens[i], defaults)); - } - - return timeline; -}; - -module.exports = TimelineBuilder; - - -/***/ }), -/* 568 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(261); -var TweenBuilder = __webpack_require__(160); -var TWEEN_CONST = __webpack_require__(97); - -/** - * @classdesc - * A Timeline combines multiple Tweens into one. Its overall behavior is otherwise similar to a single Tween. - * - * The Timeline updates all of its Tweens simultaneously. Its methods allow you to easily build a sequence - * of Tweens (each one starting after the previous one) or run multiple Tweens at once during given parts of the Timeline. - * - * @class Timeline - * @memberof Phaser.Tweens - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager which owns this Timeline. - */ -var Timeline = new Class({ - - Extends: EventEmitter, - - initialize: - - function Timeline (manager) - { - EventEmitter.call(this); - - /** - * The Tween Manager which owns this Timeline. - * - * @name Phaser.Tweens.Timeline#manager - * @type {Phaser.Tweens.TweenManager} - * @since 3.0.0 - */ - this.manager = manager; - - /** - * A constant value which allows this Timeline to be easily identified as one. - * - * @name Phaser.Tweens.Timeline#isTimeline - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.isTimeline = true; - - /** - * An array of Tween objects, each containing a unique property and target being tweened. - * - * @name Phaser.Tweens.Timeline#data - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.data = []; - - /** - * The cached size of the data array. - * - * @name Phaser.Tweens.Timeline#totalData - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalData = 0; - - /** - * If true then duration, delay, etc values are all frame totals, rather than ms. - * - * @name Phaser.Tweens.Timeline#useFrames - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.useFrames = false; - - /** - * Scales the time applied to this Timeline. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. - * Value isn't used when calculating total duration of the Timeline, it's a run-time delta adjustment only. - * - * @name Phaser.Tweens.Timeline#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; - - /** - * Loop this Timeline? Can be -1 for an infinite loop, or an integer. - * When enabled it will play through ALL Tweens again (use Tween.repeat to loop a single tween) - * - * @name Phaser.Tweens.Timeline#loop - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loop = 0; - - /** - * Time in ms/frames before this Timeline loops. - * - * @name Phaser.Tweens.Timeline#loopDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loopDelay = 0; - - /** - * How many loops are left to run? - * - * @name Phaser.Tweens.Timeline#loopCounter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loopCounter = 0; - - /** - * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes) - * - * @name Phaser.Tweens.Timeline#completeDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.completeDelay = 0; - - /** - * Countdown timer value, as used by `loopDelay` and `completeDelay`. - * - * @name Phaser.Tweens.Timeline#countdown - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.countdown = 0; - - /** - * The current state of the Timeline. - * - * @name Phaser.Tweens.Timeline#state - * @type {number} - * @since 3.0.0 - */ - this.state = TWEEN_CONST.PENDING_ADD; - - /** - * The state of the Timeline when it was paused (used by Resume) - * - * @name Phaser.Tweens.Timeline#_pausedState - * @type {number} - * @private - * @since 3.0.0 - */ - this._pausedState = TWEEN_CONST.PENDING_ADD; - - /** - * Does the Timeline start off paused? (if so it needs to be started with Timeline.play) - * - * @name Phaser.Tweens.Timeline#paused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.paused = false; - - /** - * Elapsed time in ms/frames of this run through of the Timeline. - * - * @name Phaser.Tweens.Timeline#elapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.elapsed = 0; - - /** - * Total elapsed time in ms/frames of the entire Timeline, including looping. - * - * @name Phaser.Tweens.Timeline#totalElapsed - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalElapsed = 0; - - /** - * Time in ms/frames for the whole Timeline to play through once, excluding loop amounts and loop delays. - * - * @name Phaser.Tweens.Timeline#duration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.duration = 0; - - /** - * Value between 0 and 1. The amount of progress through the Timeline, _excluding loops_. - * - * @name Phaser.Tweens.Timeline#progress - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.progress = 0; - - /** - * Time in ms/frames for all Tweens in this Timeline to complete (including looping) - * - * @name Phaser.Tweens.Timeline#totalDuration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalDuration = 0; - - /** - * Value between 0 and 1. The amount through the entire Timeline, including looping. - * - * @name Phaser.Tweens.Timeline#totalProgress - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalProgress = 0; - - /** - * An object containing the different Tween callback functions. - * - * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. - * - * `onComplete` When the Timeline finishes playback fully or `Timeline.stop` is called. Never invoked if timeline is set to repeat infinitely. - * `onLoop` When a Timeline loops. - * `onStart` When the Timeline starts playing. - * `onUpdate` When a Timeline updates a child Tween. - * `onYoyo` When a Timeline starts a yoyo. - * - * @name Phaser.Tweens.Timeline#callbacks - * @type {object} - * @since 3.0.0 - */ - this.callbacks = { - onComplete: null, - onLoop: null, - onStart: null, - onUpdate: null, - onYoyo: null - }; - - /** - * The context in which all callbacks are invoked. - * - * @name Phaser.Tweens.Timeline#callbackScope - * @type {any} - * @since 3.0.0 - */ - this.callbackScope; - }, - - /** - * Internal method that will emit a Timeline based Event and invoke the given callback. - * - * @method Phaser.Tweens.Timeline#dispatchTimelineEvent - * @since 3.19.0 - * - * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. - * @param {function} callback - The callback to be invoked. Can be `null` or `undefined` to skip invocation. - */ - dispatchTimelineEvent: function (event, callback) - { - this.emit(event, this); - - if (callback) - { - callback.func.apply(callback.scope, callback.params); - } - }, - - /** - * Sets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. - * A value of 0.5 runs 50% slower, and so on. - * - * The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only. - * - * @method Phaser.Tweens.Timeline#setTimeScale - * @since 3.0.0 - * - * @param {number} value - The time scale value to set. - * - * @return {this} This Timeline object. - */ - setTimeScale: function (value) - { - this.timeScale = value; - - return this; - }, - - /** - * Gets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. - * A value of 0.5 runs 50% slower, and so on. - * - * @method Phaser.Tweens.Timeline#getTimeScale - * @since 3.0.0 - * - * @return {number} The value of the time scale applied to this Timeline. - */ - getTimeScale: function () - { - return this.timeScale; - }, - - /** - * Check whether or not the Timeline is playing. - * - * @method Phaser.Tweens.Timeline#isPlaying - * @since 3.0.0 - * - * @return {boolean} `true` if this Timeline is active, otherwise `false`. - */ - isPlaying: function () - { - return (this.state === TWEEN_CONST.ACTIVE); - }, - - /** - * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. - * - * @method Phaser.Tweens.Timeline#add - * @since 3.0.0 - * - * @param {(Phaser.Types.Tweens.TweenBuilderConfig|object)} config - The configuration object for the Tween. - * - * @return {this} This Timeline object. - */ - add: function (config) - { - return this.queue(TweenBuilder(this, config)); - }, - - /** - * Adds an existing Tween to this Timeline. - * - * @method Phaser.Tweens.Timeline#queue - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to be added to this Timeline. - * - * @return {this} This Timeline object. - */ - queue: function (tween) - { - if (!this.isPlaying()) - { - tween.parent = this; - tween.parentIsTimeline = true; - - this.data.push(tween); - - this.totalData = this.data.length; - } - - return this; - }, - - /** - * Checks whether a Tween has an offset value. - * - * @method Phaser.Tweens.Timeline#hasOffset - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to check. - * - * @return {boolean} `true` if the tween has a non-null offset. - */ - hasOffset: function (tween) - { - return (tween.offset !== null); - }, - - /** - * Checks whether the offset value is a number or a directive that is relative to previous tweens. - * - * @method Phaser.Tweens.Timeline#isOffsetAbsolute - * @since 3.0.0 - * - * @param {number} value - The offset value to be evaluated. - * - * @return {boolean} `true` if the result is a number, `false` if it is a directive like " -= 1000". - */ - isOffsetAbsolute: function (value) - { - return (typeof(value) === 'number'); - }, - - /** - * Checks if the offset is a relative value rather than an absolute one. - * If the value is just a number, this returns false. - * - * @method Phaser.Tweens.Timeline#isOffsetRelative - * @since 3.0.0 - * - * @param {string} value - The offset value to be evaluated. - * - * @return {boolean} `true` if the value is relative, i.e " -= 1000". If `false`, the offset is absolute. - */ - isOffsetRelative: function (value) - { - var t = typeof(value); - - if (t === 'string') - { - var op = value[0]; - - if (op === '-' || op === '+') - { - return true; - } - } - - return false; - }, - - /** - * Parses the relative offset value, returning a positive or negative number. - * - * @method Phaser.Tweens.Timeline#getRelativeOffset - * @since 3.0.0 - * - * @param {string} value - The relative offset, in the format of '-=500', for example. The first character determines whether it will be a positive or negative number. Spacing matters here. - * @param {number} base - The value to use as the offset. - * - * @return {number} The parsed offset value. - */ - getRelativeOffset: function (value, base) - { - var op = value[0]; - var num = parseFloat(value.substr(2)); - var result = base; - - switch (op) - { - case '+': - result += num; - break; - - case '-': - result -= num; - break; - } - - // Cannot ever be < 0 - return Math.max(0, result); - }, - - /** - * Calculates the total duration of the timeline. - * - * Computes all tween durations and returns the full duration of the timeline. - * - * The resulting number is stored in the timeline, not as a return value. - * - * @method Phaser.Tweens.Timeline#calcDuration - * @since 3.0.0 - */ - calcDuration: function () - { - var prevEnd = 0; - var totalDuration = 0; - var offsetDuration = 0; - - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - tween.init(); - - if (this.hasOffset(tween)) - { - if (this.isOffsetAbsolute(tween.offset)) - { - // An actual number, so it defines the start point from the beginning of the timeline - tween.calculatedOffset = tween.offset; - - if (tween.offset === 0) - { - offsetDuration = 0; - } - } - else if (this.isOffsetRelative(tween.offset)) - { - // A relative offset (i.e. '-=1000', so starts at 'offset' ms relative to the PREVIOUS Tweens ending time) - tween.calculatedOffset = this.getRelativeOffset(tween.offset, prevEnd); - } - } - else - { - // Sequential - tween.calculatedOffset = offsetDuration; - } - - prevEnd = tween.totalDuration + tween.calculatedOffset; - - totalDuration += tween.totalDuration; - offsetDuration += tween.totalDuration; - } - - // Excludes loop values - this.duration = totalDuration; - - this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; - - if (this.loopCounter > 0) - { - this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter); - } - else - { - this.totalDuration = this.duration + this.completeDelay; - } - }, - - /** - * Initializes the timeline, which means all Tweens get their init() called, and the total duration will be computed. - * Returns a boolean indicating whether the timeline is auto-started or not. - * - * @method Phaser.Tweens.Timeline#init - * @since 3.0.0 - * - * @return {boolean} `true` if the Timeline is started. `false` if it is paused. - */ - init: function () - { - this.calcDuration(); - - this.progress = 0; - this.totalProgress = 0; - - if (this.paused) - { - this.state = TWEEN_CONST.PAUSED; - - return false; - } - else - { - return true; - } - }, - - /** - * Resets all of the timeline's tweens back to their initial states. - * The boolean parameter indicates whether tweens that are looping should reset as well, or not. - * - * @method Phaser.Tweens.Timeline#resetTweens - * @since 3.0.0 - * - * @param {boolean} resetFromLoop - If `true`, resets all looping tweens to their initial values. - */ - resetTweens: function (resetFromLoop) - { - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - tween.play(resetFromLoop); - } - }, - - /** - * Sets a callback for the Timeline. - * - * @method Phaser.Tweens.Timeline#setCallback - * @since 3.0.0 - * - * @param {string} type - The internal type of callback to set. - * @param {function} callback - Timeline allows multiple tweens to be linked together to create a streaming sequence. - * @param {array} [params] - The parameters to pass to the callback. - * @param {object} [scope] - The context scope of the callback. - * - * @return {this} This Timeline object. - */ - setCallback: function (type, callback, params, scope) - { - if (Timeline.TYPES.indexOf(type) !== -1) - { - this.callbacks[type] = { func: callback, scope: scope, params: params }; - } - - return this; - }, - - /** - * Passed a Tween to the Tween Manager and requests it be made active. - * - * @method Phaser.Tweens.Timeline#makeActive - * @since 3.3.0 - * - * @param {Phaser.Tweens.Tween} tween - The tween object to make active. - * - * @return {Phaser.Tweens.TweenManager} The Timeline's Tween Manager reference. - */ - makeActive: function (tween) - { - return this.manager.makeActive(tween); - }, - - /** - * Starts playing the Timeline. - * - * @method Phaser.Tweens.Timeline#play - * @fires Phaser.Tweens.Events#TIMELINE_START - * @since 3.0.0 - */ - play: function () - { - if (this.state === TWEEN_CONST.ACTIVE) - { - return; - } - - if (this.paused) - { - this.paused = false; - - this.manager.makeActive(this); - - return; - } - else - { - this.resetTweens(false); - - this.state = TWEEN_CONST.ACTIVE; - } - - this.dispatchTimelineEvent(Events.TIMELINE_START, this.callbacks.onStart); - }, - - /** - * Updates the Timeline's `state` and fires callbacks and events. - * - * @method Phaser.Tweens.Timeline#nextState - * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE - * @fires Phaser.Tweens.Events#TIMELINE_LOOP - * @since 3.0.0 - * - * @see Phaser.Tweens.Timeline#update - */ - nextState: function () - { - if (this.loopCounter > 0) - { - // Reset the elapsed time - this.elapsed = 0; - this.progress = 0; - - this.loopCounter--; - - this.resetTweens(true); - - if (this.loopDelay > 0) - { - this.countdown = this.loopDelay; - - this.state = TWEEN_CONST.LOOP_DELAY; - } - else - { - this.state = TWEEN_CONST.ACTIVE; - - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } - } - else if (this.completeDelay > 0) - { - this.state = TWEEN_CONST.COMPLETE_DELAY; - - this.countdown = this.completeDelay; - } - else - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); - } - }, - - /** - * Returns 'true' if this Timeline has finished and should be removed from the Tween Manager. - * Otherwise, returns false. - * - * @method Phaser.Tweens.Timeline#update - * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE - * @fires Phaser.Tweens.Events#TIMELINE_UPDATE - * @since 3.0.0 - * - * @param {number} timestamp - 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. - * - * @return {boolean} Returns `true` if this Timeline has finished and should be removed from the Tween Manager. - */ - update: function (timestamp, delta) - { - if (this.state === TWEEN_CONST.PAUSED) - { - return; - } - - if (this.useFrames) - { - delta = 1 * this.manager.timeScale; - } - - delta *= this.timeScale; - - this.elapsed += delta; - this.progress = Math.min(this.elapsed / this.duration, 1); - - this.totalElapsed += delta; - this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); - - switch (this.state) - { - case TWEEN_CONST.ACTIVE: - - var stillRunning = this.totalData; - - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; - - if (tween.update(timestamp, delta)) - { - stillRunning--; - } - } - - this.dispatchTimelineEvent(Events.TIMELINE_UPDATE, this.callbacks.onUpdate); - - // Anything still running? If not, we're done - if (stillRunning === 0) - { - this.nextState(); - } - - break; - - case TWEEN_CONST.LOOP_DELAY: - - this.countdown -= delta; - - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.ACTIVE; - - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } - - break; - - case TWEEN_CONST.COMPLETE_DELAY: - - this.countdown -= delta; - - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); - } - - break; - } - - return (this.state === TWEEN_CONST.PENDING_REMOVE); - }, - - /** - * Stops the Timeline immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. - * - * @method Phaser.Tweens.Timeline#stop - * @since 3.0.0 - */ - stop: function () - { - this.state = TWEEN_CONST.PENDING_REMOVE; - }, - - /** - * Pauses the Timeline, retaining its internal state. - * - * Calling this on a Timeline that is already paused has no effect and fires no event. - * - * @method Phaser.Tweens.Timeline#pause - * @fires Phaser.Tweens.Events#TIMELINE_PAUSE - * @since 3.0.0 - * - * @return {this} This Timeline object. - */ - pause: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - return; - } - - this.paused = true; - - this._pausedState = this.state; - - this.state = TWEEN_CONST.PAUSED; - - this.emit(Events.TIMELINE_PAUSE, this); - - return this; - }, - - /** - * Resumes a paused Timeline from where it was when it was paused. - * - * Calling this on a Timeline that isn't paused has no effect and fires no event. - * - * @method Phaser.Tweens.Timeline#resume - * @fires Phaser.Tweens.Events#TIMELINE_RESUME - * @since 3.0.0 - * - * @return {this} This Timeline object. - */ - resume: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - this.paused = false; - - this.state = this._pausedState; - - this.emit(Events.TIMELINE_RESUME, this); - } - - return this; - }, - - /** - * Checks if any of the Tweens in this Timeline as operating on the target object. - * - * Returns `false` if no Tweens operate on the target object. - * - * @method Phaser.Tweens.Timeline#hasTarget - * @since 3.0.0 - * - * @param {object} target - The target to check all Tweens against. - * - * @return {boolean} `true` if there is at least a single Tween that operates on the target object, otherwise `false`. - */ - hasTarget: function (target) - { - for (var i = 0; i < this.data.length; i++) - { - if (this.data[i].hasTarget(target)) - { - return true; - } - } - - return false; - }, - - /** - * Stops all the Tweens in the Timeline immediately, whatever stage of progress they are at and flags - * them for removal by the TweenManager. - * - * @method Phaser.Tweens.Timeline#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var i = 0; i < this.data.length; i++) - { - this.data[i].stop(); - } - } - -}); - -Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ]; - -module.exports = Timeline; - - -/***/ }), -/* 569 */ -/***/ (function(module, exports, __webpack_require__) { - /** * @author Richard Davey * @author Felipe Alfonso <@bitnenfer> @@ -130220,13 +78026,13 @@ module.exports = Timeline; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CameraEvents = __webpack_require__(34); -var CanvasSnapshot = __webpack_require__(570); +var CameraEvents = __webpack_require__(35); +var CanvasSnapshot = __webpack_require__(363); var Class = __webpack_require__(0); var CONST = __webpack_require__(39); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(94); -var GetBlendModes = __webpack_require__(571); +var Events = __webpack_require__(88); +var GetBlendModes = __webpack_require__(364); var ScaleEvents = __webpack_require__(101); var TextureEvents = __webpack_require__(103); var TransformMatrix = __webpack_require__(25); @@ -131054,7 +78860,7 @@ module.exports = CanvasRenderer; /***/ }), -/* 570 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -131064,7 +78870,7 @@ module.exports = CanvasRenderer; */ var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var GetFastValue = __webpack_require__(2); /** @@ -131147,7 +78953,7 @@ module.exports = CanvasSnapshot; /***/ }), -/* 571 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -131156,7 +78962,7 @@ module.exports = CanvasSnapshot; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var modes = __webpack_require__(38); +var modes = __webpack_require__(33); var CanvasFeatures = __webpack_require__(342); /** @@ -131211,7 +79017,7 @@ module.exports = GetBlendModes; /***/ }), -/* 572 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -131221,22 +79027,22 @@ module.exports = GetBlendModes; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(88); -var CameraEvents = __webpack_require__(34); +var ArrayRemove = __webpack_require__(89); +var CameraEvents = __webpack_require__(35); var Class = __webpack_require__(0); var CONST = __webpack_require__(39); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(94); +var Events = __webpack_require__(88); var GameEvents = __webpack_require__(22); var IsSizePowerOfTwo = __webpack_require__(136); -var Matrix4 = __webpack_require__(65); +var Matrix4 = __webpack_require__(67); var NOOP = __webpack_require__(1); -var PipelineManager = __webpack_require__(573); -var RenderTarget = __webpack_require__(162); +var PipelineManager = __webpack_require__(366); +var RenderTarget = __webpack_require__(139); var ScaleEvents = __webpack_require__(101); var TextureEvents = __webpack_require__(103); var Utils = __webpack_require__(12); -var WebGLSnapshot = __webpack_require__(584); +var WebGLSnapshot = __webpack_require__(377); /** * @callback WebGLContextCallback @@ -134184,7 +81990,7 @@ module.exports = WebGLRenderer; /***/ }), -/* 573 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -134194,18 +82000,18 @@ module.exports = WebGLRenderer; */ var Class = __webpack_require__(0); -var CONST = __webpack_require__(72); +var CONST = __webpack_require__(65); var CustomMap = __webpack_require__(99); // Default Phaser 3 Pipelines -var BitmapMaskPipeline = __webpack_require__(574); -var GraphicsPipeline = __webpack_require__(577); -var LightPipeline = __webpack_require__(578); -var MultiPipeline = __webpack_require__(123); -var PointLightPipeline = __webpack_require__(579); -var RopePipeline = __webpack_require__(580); -var SinglePipeline = __webpack_require__(581); -var UtilityPipeline = __webpack_require__(582); +var BitmapMaskPipeline = __webpack_require__(367); +var GraphicsPipeline = __webpack_require__(370); +var LightPipeline = __webpack_require__(371); +var MultiPipeline = __webpack_require__(105); +var PointLightPipeline = __webpack_require__(372); +var RopePipeline = __webpack_require__(373); +var SinglePipeline = __webpack_require__(374); +var UtilityPipeline = __webpack_require__(375); /** * @classdesc @@ -135307,7 +83113,7 @@ module.exports = PipelineManager; /***/ }), -/* 574 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -135321,8 +83127,8 @@ var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var ShaderSourceFS = __webpack_require__(862); var ShaderSourceVS = __webpack_require__(863); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -135505,7 +83311,7 @@ module.exports = BitmapMaskPipeline; /***/ }), -/* 575 */ +/* 368 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -135532,7 +83338,7 @@ module.exports = { /***/ }), -/* 576 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -135543,7 +83349,7 @@ module.exports = { var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var WEBGL_CONST = __webpack_require__(122); +var WEBGL_CONST = __webpack_require__(104); /** * @classdesc @@ -136633,7 +84439,7 @@ module.exports = WebGLShader; /***/ }), -/* 577 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -136644,13 +84450,13 @@ module.exports = WebGLShader; */ var Class = __webpack_require__(0); -var Earcut = __webpack_require__(67); +var Earcut = __webpack_require__(68); var GetFastValue = __webpack_require__(2); var ShaderSourceFS = __webpack_require__(871); var ShaderSourceVS = __webpack_require__(872); var TransformMatrix = __webpack_require__(25); -var WEBGL_CONST = __webpack_require__(122); -var WebGLPipeline = __webpack_require__(66); +var WEBGL_CONST = __webpack_require__(104); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -137316,7 +85122,7 @@ module.exports = GraphicsPipeline; /***/ }), -/* 578 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -137329,9 +85135,9 @@ module.exports = GraphicsPipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var LightShaderSourceFS = __webpack_require__(873); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); var Vec2 = __webpack_require__(3); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); var LIGHT_COUNT = 10; var tempVec2 = new Vec2(); @@ -137691,7 +85497,7 @@ module.exports = LightPipeline; /***/ }), -/* 579 */ +/* 372 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -137704,7 +85510,7 @@ var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); var PointLightShaderSourceFS = __webpack_require__(876); var PointLightShaderSourceVS = __webpack_require__(877); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -137865,7 +85671,7 @@ module.exports = PointLightPipeline; /***/ }), -/* 580 */ +/* 373 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -137876,7 +85682,7 @@ module.exports = PointLightPipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); /** * @classdesc @@ -137932,7 +85738,7 @@ module.exports = RopePipeline; /***/ }), -/* 581 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -137943,10 +85749,10 @@ module.exports = RopePipeline; var Class = __webpack_require__(0); var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(123); +var MultiPipeline = __webpack_require__(105); var ShaderSourceFS = __webpack_require__(878); var ShaderSourceVS = __webpack_require__(879); -var WebGLPipeline = __webpack_require__(66); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -138009,7 +85815,7 @@ module.exports = SinglePipeline; /***/ }), -/* 582 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -138019,15 +85825,15 @@ module.exports = SinglePipeline; */ var AddBlendFS = __webpack_require__(880); -var BlendModes = __webpack_require__(38); +var BlendModes = __webpack_require__(33); var Class = __webpack_require__(0); -var ColorMatrix = __webpack_require__(266); +var ColorMatrix = __webpack_require__(195); var ColorMatrixFS = __webpack_require__(881); var CopyFS = __webpack_require__(882); var GetFastValue = __webpack_require__(2); var LinearBlendFS = __webpack_require__(883); -var QuadVS = __webpack_require__(583); -var WebGLPipeline = __webpack_require__(66); +var QuadVS = __webpack_require__(376); +var WebGLPipeline = __webpack_require__(57); /** * @classdesc @@ -138800,7 +86606,7 @@ module.exports = UtilityPipeline; /***/ }), -/* 583 */ +/* 376 */ /***/ (function(module, exports) { module.exports = [ @@ -138826,7 +86632,7 @@ module.exports = [ /***/ }), -/* 584 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -138836,7 +86642,7 @@ module.exports = [ */ var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(35); +var Color = __webpack_require__(36); var GetFastValue = __webpack_require__(2); /** @@ -138937,6 +86743,52226 @@ var WebGLSnapshot = function (sourceCanvas, config) module.exports = WebGLSnapshot; +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(39); + +/** + * Called automatically by Phaser.Game and responsible for creating the console.log debug header. + * + * You can customize or disable the header via the Game Config object. + * + * @function Phaser.Core.DebugHeader + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance which will output this debug header. + */ +var DebugHeader = function (game) +{ + var config = game.config; + + if (config.hideBanner) + { + return; + } + + var renderType = 'WebGL'; + + if (config.renderType === CONST.CANVAS) + { + renderType = 'Canvas'; + } + else if (config.renderType === CONST.HEADLESS) + { + renderType = 'Headless'; + } + + var audioConfig = config.audio; + var deviceAudio = game.device.audio; + + var audioType; + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + audioType = 'Web Audio'; + } + else if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + audioType = 'No Audio'; + } + else + { + audioType = 'HTML5 Audio'; + } + + if (!game.device.browser.ie) + { + var c = ''; + var args = [ c ]; + + if (Array.isArray(config.bannerBackgroundColor)) + { + var lastColor; + + config.bannerBackgroundColor.forEach(function (color) + { + c = c.concat('%c '); + + args.push('background: ' + color); + + lastColor = color; + + }); + + // inject the text color + args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; + } + else + { + c = c.concat('%c '); + + args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); + } + + // URL link background color (always white) + args.push('background: #fff'); + + if (config.gameTitle) + { + c = c.concat(config.gameTitle); + + if (config.gameVersion) + { + c = c.concat(' v' + config.gameVersion); + } + + if (!config.hidePhaser) + { + c = c.concat(' / '); + } + } + + var fb = ( false) ? undefined : ''; + + if (!config.hidePhaser) + { + c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); + } + + c = c.concat(' %c ' + config.gameURL); + + // Inject the new string back into the args array + args[0] = c; + + console.log.apply(console, args); + } + else if (window['console']) + { + console.log('Phaser v' + CONST.VERSION + ' / https://phaser.io'); + } +}; + +module.exports = DebugHeader; + + +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetValue = __webpack_require__(6); +var NOOP = __webpack_require__(1); +var RequestAnimationFrame = __webpack_require__(380); + +// http://www.testufo.com/#test=animation-time-graph + +/** + * @classdesc + * The core runner class that Phaser uses to handle the game loop. It can use either Request Animation Frame, + * or SetTimeout, based on browser support and config settings, to create a continuous loop within the browser. + * + * Each time the loop fires, `TimeStep.step` is called and this is then passed onto the core Game update loop, + * it is the core heartbeat of your game. It will fire as often as Request Animation Frame is capable of handling + * on the target device. + * + * Note that there are lots of situations where a browser will stop updating your game. Such as if the player + * switches tabs, or covers up the browser window with another application. In these cases, the 'heartbeat' + * of your game will pause, and only resume when focus is returned to it by the player. There is no way to avoid + * this situation, all you can do is use the visibility events the browser, and Phaser, provide to detect when + * it has happened and then gracefully recover. + * + * @class TimeStep + * @memberof Phaser.Core + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step. + * @param {Phaser.Types.Core.FPSConfig} config + */ +var TimeStep = new Class({ + + initialize: + + function TimeStep (game, config) + { + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Core.TimeStep#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; + + /** + * The Request Animation Frame DOM Event handler. + * + * @name Phaser.Core.TimeStep#raf + * @type {Phaser.DOM.RequestAnimationFrame} + * @readonly + * @since 3.0.0 + */ + this.raf = new RequestAnimationFrame(); + + /** + * A flag that is set once the TimeStep has started running and toggled when it stops. + * + * @name Phaser.Core.TimeStep#started + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.started = false; + + /** + * A flag that is set once the TimeStep has started running and toggled when it stops. + * The difference between this value and `started` is that `running` is toggled when + * the TimeStep is sent to sleep, where-as `started` remains `true`, only changing if + * the TimeStep is actually stopped, not just paused. + * + * @name Phaser.Core.TimeStep#running + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.running = false; + + /** + * The minimum fps rate you want the Time Step to run at. + * + * @name Phaser.Core.TimeStep#minFps + * @type {number} + * @default 5 + * @since 3.0.0 + */ + this.minFps = GetValue(config, 'min', 5); + + /** + * The target fps rate for the Time Step to run at. + * + * Setting this value will not actually change the speed at which the browser runs, that is beyond + * the control of Phaser. Instead, it allows you to determine performance issues and if the Time Step + * is spiraling out of control. + * + * @name Phaser.Core.TimeStep#targetFps + * @type {number} + * @default 60 + * @since 3.0.0 + */ + this.targetFps = GetValue(config, 'target', 60); + + /** + * The minFps value in ms. + * Defaults to 200ms between frames (i.e. super slow!) + * + * @name Phaser.Core.TimeStep#_min + * @type {number} + * @private + * @since 3.0.0 + */ + this._min = 1000 / this.minFps; + + /** + * The targetFps value in ms. + * Defaults to 16.66ms between frames (i.e. normal) + * + * @name Phaser.Core.TimeStep#_target + * @type {number} + * @private + * @since 3.0.0 + */ + this._target = 1000 / this.targetFps; + + /** + * An exponential moving average of the frames per second. + * + * @name Phaser.Core.TimeStep#actualFps + * @type {number} + * @readonly + * @default 60 + * @since 3.0.0 + */ + this.actualFps = this.targetFps; + + /** + * The time at which the next fps rate update will take place. + * When an fps update happens, the `framesThisSecond` value is reset. + * + * @name Phaser.Core.TimeStep#nextFpsUpdate + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.nextFpsUpdate = 0; + + /** + * The number of frames processed this second. + * + * @name Phaser.Core.TimeStep#framesThisSecond + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.framesThisSecond = 0; + + /** + * A callback to be invoked each time the Time Step steps. + * + * @name Phaser.Core.TimeStep#callback + * @type {Phaser.Types.Core.TimeStepCallback} + * @default NOOP + * @since 3.0.0 + */ + this.callback = NOOP; + + /** + * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting + * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time. + * + * @name Phaser.Core.TimeStep#forceSetTimeOut + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.forceSetTimeOut = GetValue(config, 'forceSetTimeOut', false); + + /** + * The time, calculated at the start of the current step, as smoothed by the delta value. + * + * @name Phaser.Core.TimeStep#time + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.time = 0; + + /** + * The time at which the game started running. This value is adjusted if the game is then + * paused and resumes. + * + * @name Phaser.Core.TimeStep#startTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * The time, as returned by `performance.now` of the previous step. + * + * @name Phaser.Core.TimeStep#lastTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lastTime = 0; + + /** + * The current frame the game is on. This counter is incremented once every game step, regardless of how much + * time has passed and is unaffected by delta smoothing. + * + * @name Phaser.Core.TimeStep#frame + * @type {number} + * @readonly + * @default 0 + * @since 3.0.0 + */ + this.frame = 0; + + /** + * Is the browser currently considered in focus by the Page Visibility API? + * This value is set in the `blur` method, which is called automatically by the Game instance. + * + * @name Phaser.Core.TimeStep#inFocus + * @type {boolean} + * @readonly + * @default true + * @since 3.0.0 + */ + this.inFocus = true; + + /** + * The timestamp at which the game became paused, as determined by the Page Visibility API. + * + * @name Phaser.Core.TimeStep#_pauseTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._pauseTime = 0; + + /** + * An internal counter to allow for the browser 'cooling down' after coming back into focus. + * + * @name Phaser.Core.TimeStep#_coolDown + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._coolDown = 0; + + /** + * The delta time, in ms, since the last game step. This is a clamped and smoothed average value. + * + * @name Phaser.Core.TimeStep#delta + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.delta = 0; + + /** + * Internal index of the delta history position. + * + * @name Phaser.Core.TimeStep#deltaIndex + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.deltaIndex = 0; + + /** + * Internal array holding the previous delta values, used for delta smoothing. + * + * @name Phaser.Core.TimeStep#deltaHistory + * @type {number[]} + * @since 3.0.0 + */ + this.deltaHistory = []; + + /** + * The maximum number of delta values that are retained in order to calculate a smoothed moving average. + * + * This can be changed in the Game Config via the `fps.deltaHistory` property. The default is 10. + * + * @name Phaser.Core.TimeStep#deltaSmoothingMax + * @type {number} + * @default 10 + * @since 3.0.0 + */ + this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10); + + /** + * The number of frames that the cooldown is set to after the browser panics over the FPS rate, usually + * as a result of switching tabs and regaining focus. + * + * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120. + * + * @name Phaser.Core.TimeStep#panicMax + * @type {number} + * @default 120 + * @since 3.0.0 + */ + this.panicMax = GetValue(config, 'panicMax', 120); + + /** + * The actual elapsed time in ms between one update and the next. + * + * Unlike with `delta`, no smoothing, capping, or averaging is applied to this value. + * So please be careful when using this value in math calculations. + * + * @name Phaser.Core.TimeStep#rawDelta + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.rawDelta = 0; + + /** + * The time, as returned by `performance.now` at the very start of the current step. + * This can differ from the `time` value in that it isn't calculated based on the delta value. + * + * @name Phaser.Core.TimeStep#now + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.now = 0; + + /** + * Apply smoothing to the delta value used within Phasers internal calculations? + * + * This can be changed in the Game Config via the `fps.smoothStep` property. The default is `true`. + * + * Smoothing helps settle down the delta values after browser tab switches, or other situations + * which could cause significant delta spikes or dips. By default it has been enabled in Phaser 3 + * since the first version, but is now exposed under this property (and the corresponding game config + * `smoothStep` value), to allow you to easily disable it, should you require. + * + * @name Phaser.Core.TimeStep#smoothStep + * @type {boolean} + * @since 3.22.0 + */ + this.smoothStep = GetValue(config, 'smoothStep', true); + }, + + /** + * Called by the Game instance when the DOM window.onBlur event triggers. + * + * @method Phaser.Core.TimeStep#blur + * @since 3.0.0 + */ + blur: function () + { + this.inFocus = false; + }, + + /** + * Called by the Game instance when the DOM window.onFocus event triggers. + * + * @method Phaser.Core.TimeStep#focus + * @since 3.0.0 + */ + focus: function () + { + this.inFocus = true; + + this.resetDelta(); + }, + + /** + * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc) + * + * @method Phaser.Core.TimeStep#pause + * @since 3.0.0 + */ + pause: function () + { + this._pauseTime = window.performance.now(); + }, + + /** + * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc) + * + * @method Phaser.Core.TimeStep#resume + * @since 3.0.0 + */ + resume: function () + { + this.resetDelta(); + + this.startTime += this.time - this._pauseTime; + }, + + /** + * Resets the time, lastTime, fps averages and delta history. + * Called automatically when a browser sleeps them resumes. + * + * @method Phaser.Core.TimeStep#resetDelta + * @since 3.0.0 + */ + resetDelta: function () + { + var now = window.performance.now(); + + this.time = now; + this.lastTime = now; + this.nextFpsUpdate = now + 1000; + this.framesThisSecond = 0; + + // Pre-populate smoothing array + + for (var i = 0; i < this.deltaSmoothingMax; i++) + { + this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]); + } + + this.delta = 0; + this.deltaIndex = 0; + + this._coolDown = this.panicMax; + }, + + /** + * Starts the Time Step running, if it is not already doing so. + * Called automatically by the Game Boot process. + * + * @method Phaser.Core.TimeStep#start + * @since 3.0.0 + * + * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps. + */ + start: function (callback) + { + if (this.started) + { + return this; + } + + this.started = true; + this.running = true; + + for (var i = 0; i < this.deltaSmoothingMax; i++) + { + this.deltaHistory[i] = this._target; + } + + this.resetDelta(); + + this.startTime = window.performance.now(); + + this.callback = callback; + + this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target); + }, + + /** + * The main step method. This is called each time the browser updates, either by Request Animation Frame, + * or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more. + * You generally should never call this method directly. + * + * @method Phaser.Core.TimeStep#step + * @since 3.0.0 + */ + step: function () + { + // Because the timestamp passed in from raf represents the beginning of the main thread frame that we’re currently in, + // not the actual time now, and as we want to compare this time value against Event timeStamps and the like, we need a + // more accurate one: + + var time = window.performance.now(); + + this.now = time; + + var before = time - this.lastTime; + + if (before < 0) + { + // Because, Chrome. + before = 0; + } + + this.rawDelta = before; + + var idx = this.deltaIndex; + var history = this.deltaHistory; + var max = this.deltaSmoothingMax; + + // delta time (time is in ms) + var dt = before; + + // Delta Average + var avg = before; + + // When a browser switches tab, then comes back again, it takes around 10 frames before + // the delta time settles down so we employ a 'cooling down' period before we start + // trusting the delta values again, to avoid spikes flooding through our delta average + + if (this.smoothStep) + { + if (this._coolDown > 0 || !this.inFocus) + { + this._coolDown--; + + dt = Math.min(dt, this._target); + } + + if (dt > this._min) + { + // Probably super bad start time or browser tab context loss, + // so use the last 'sane' dt value + + dt = history[idx]; + + // Clamp delta to min (in case history has become corrupted somehow) + dt = Math.min(dt, this._min); + } + + // Smooth out the delta over the previous X frames + + // add the delta to the smoothing array + history[idx] = dt; + + // adjusts the delta history array index based on the smoothing count + // this stops the array growing beyond the size of deltaSmoothingMax + this.deltaIndex++; + + if (this.deltaIndex > max) + { + this.deltaIndex = 0; + } + + // Loop the history array, adding the delta values together + avg = 0; + + for (var i = 0; i < max; i++) + { + avg += history[i]; + } + + // Then divide by the array length to get the average delta + avg /= max; + } + + // Set as the world delta value + this.delta = avg; + + // Real-world timer advance + this.time += this.rawDelta; + + // Update the estimate of the frame rate, `fps`. Every second, the number + // of frames that occurred in that second are included in an exponential + // moving average of all frames per second, with an alpha of 0.25. This + // means that more recent seconds affect the estimated frame rate more than + // older seconds. + // + // When a browser window is NOT minimized, but is covered up (i.e. you're using + // another app which has spawned a window over the top of the browser), then it + // will start to throttle the raf callback time. It waits for a while, and then + // starts to drop the frame rate at 1 frame per second until it's down to just over 1fps. + // So if the game was running at 60fps, and the player opens a new window, then + // after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz. + // + // When they make the game visible again, the frame rate is increased at a rate of + // approx. 8fps, back up to 60fps (or the max it can obtain) + // + // There is no easy way to determine if this drop in frame rate is because the + // browser is throttling raf, or because the game is struggling with performance + // because you're asking it to do too much on the device. + + if (time > this.nextFpsUpdate) + { + // Compute the new exponential moving average with an alpha of 0.25. + this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps; + this.nextFpsUpdate = time + 1000; + this.framesThisSecond = 0; + } + + this.framesThisSecond++; + + // Interpolation - how far between what is expected and where we are? + var interpolation = avg / this._target; + + this.callback(time, avg, interpolation); + + // Shift time value over + this.lastTime = time; + + this.frame++; + }, + + /** + * Manually calls `TimeStep.step`. + * + * @method Phaser.Core.TimeStep#tick + * @since 3.0.0 + */ + tick: function () + { + this.step(); + }, + + /** + * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false. + * + * @method Phaser.Core.TimeStep#sleep + * @since 3.0.0 + */ + sleep: function () + { + if (this.running) + { + this.raf.stop(); + + this.running = false; + } + }, + + /** + * Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true. + * The `seamless` argument controls if the wake-up should adjust the start time or not. + * + * @method Phaser.Core.TimeStep#wake + * @since 3.0.0 + * + * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values. + */ + wake: function (seamless) + { + if (this.running) + { + return; + } + else if (seamless) + { + this.startTime += -this.lastTime + (this.lastTime + window.performance.now()); + } + + this.raf.start(this.step.bind(this), this.useRAF); + + this.running = true; + + this.step(); + }, + + /** + * Gets the duration which the game has been running, in seconds. + * + * @method Phaser.Core.TimeStep#getDuration + * @since 3.17.0 + * + * @return {number} The duration in seconds. + */ + getDuration: function () + { + return Math.round(this.lastTime - this.startTime) / 1000; + }, + + /** + * Gets the duration which the game has been running, in ms. + * + * @method Phaser.Core.TimeStep#getDurationMS + * @since 3.17.0 + * + * @return {number} The duration in ms. + */ + getDurationMS: function () + { + return Math.round(this.lastTime - this.startTime); + }, + + /** + * Stops the TimeStep running. + * + * @method Phaser.Core.TimeStep#stop + * @since 3.0.0 + * + * @return {this} The TimeStep object. + */ + stop: function () + { + this.running = false; + this.started = false; + + this.raf.stop(); + + return this; + }, + + /** + * Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null + * any objects. + * + * @method Phaser.Core.TimeStep#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stop(); + + this.callback = NOOP; + + this.raf = null; + this.game = null; + } + +}); + +module.exports = TimeStep; + + +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * Abstracts away the use of RAF or setTimeOut for the core game update loop. + * This is invoked automatically by the Phaser.Game instance. + * + * @class RequestAnimationFrame + * @memberof Phaser.DOM + * @constructor + * @since 3.0.0 + */ +var RequestAnimationFrame = new Class({ + + initialize: + + function RequestAnimationFrame () + { + /** + * True if RequestAnimationFrame is running, otherwise false. + * + * @name Phaser.DOM.RequestAnimationFrame#isRunning + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isRunning = false; + + /** + * The callback to be invoked each step. + * + * @name Phaser.DOM.RequestAnimationFrame#callback + * @type {FrameRequestCallback} + * @since 3.0.0 + */ + this.callback = NOOP; + + /** + * The most recent timestamp. Either a DOMHighResTimeStamp under RAF or `Date.now` under SetTimeout. + * + * @name Phaser.DOM.RequestAnimationFrame#tick + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.tick = 0; + + /** + * True if the step is using setTimeout instead of RAF. + * + * @name Phaser.DOM.RequestAnimationFrame#isSetTimeOut + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isSetTimeOut = false; + + /** + * The setTimeout or RAF callback ID used when canceling them. + * + * @name Phaser.DOM.RequestAnimationFrame#timeOutID + * @type {?number} + * @default null + * @since 3.0.0 + */ + this.timeOutID = null; + + /** + * The previous time the step was called. + * + * @name Phaser.DOM.RequestAnimationFrame#lastTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lastTime = 0; + + /** + * The target FPS rate in ms. + * Only used when setTimeout is used instead of RAF. + * + * @name Phaser.DOM.RequestAnimationFrame#target + * @type {number} + * @default 0 + * @since 3.21.0 + */ + this.target = 0; + + var _this = this; + + /** + * The RAF step function. + * Updates the local tick value, invokes the callback and schedules another call to requestAnimationFrame. + * + * @name Phaser.DOM.RequestAnimationFrame#step + * @type {FrameRequestCallback} + * @since 3.0.0 + */ + this.step = function step () + { + // Because we cannot trust the time passed to this callback from the browser and need it kept in sync with event times + var timestamp = window.performance.now(); + + // DOMHighResTimeStamp + _this.lastTime = _this.tick; + + _this.tick = timestamp; + + _this.callback(timestamp); + + _this.timeOutID = window.requestAnimationFrame(step); + }; + + /** + * The SetTimeout step function. + * Updates the local tick value, invokes the callback and schedules another call to setTimeout. + * + * @name Phaser.DOM.RequestAnimationFrame#stepTimeout + * @type {function} + * @since 3.0.0 + */ + this.stepTimeout = function stepTimeout () + { + var d = Date.now(); + + var delay = Math.min(Math.max(_this.target * 2 + _this.tick - d, 0), _this.target); + + _this.lastTime = _this.tick; + + _this.tick = d; + + _this.callback(d); + + _this.timeOutID = window.setTimeout(stepTimeout, delay); + }; + }, + + /** + * Starts the requestAnimationFrame or setTimeout process running. + * + * @method Phaser.DOM.RequestAnimationFrame#start + * @since 3.0.0 + * + * @param {FrameRequestCallback} callback - The callback to invoke each step. + * @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available? + * @param {number} targetFPS - The target fps rate (in ms). Only used when setTimeout is used. + */ + start: function (callback, forceSetTimeOut, targetFPS) + { + if (this.isRunning) + { + return; + } + + this.callback = callback; + + this.isSetTimeOut = forceSetTimeOut; + + this.target = targetFPS; + + this.isRunning = true; + + this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); + }, + + /** + * Stops the requestAnimationFrame or setTimeout from running. + * + * @method Phaser.DOM.RequestAnimationFrame#stop + * @since 3.0.0 + */ + stop: function () + { + this.isRunning = false; + + if (this.isSetTimeOut) + { + clearTimeout(this.timeOutID); + } + else + { + window.cancelAnimationFrame(this.timeOutID); + } + }, + + /** + * Stops the step from running and clears the callback reference. + * + * @method Phaser.DOM.RequestAnimationFrame#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stop(); + + this.callback = NOOP; + } + +}); + +module.exports = RequestAnimationFrame; + + +/***/ }), +/* 381 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Events = __webpack_require__(22); + +/** + * The Visibility Handler is responsible for listening out for document level visibility change events. + * This includes `visibilitychange` if the browser supports it, and blur and focus events. It then uses + * the provided Event Emitter and fires the related events. + * + * @function Phaser.Core.VisibilityHandler + * @fires Phaser.Core.Events#BLUR + * @fires Phaser.Core.Events#FOCUS + * @fires Phaser.Core.Events#HIDDEN + * @fires Phaser.Core.Events#VISIBLE + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. + */ +var VisibilityHandler = function (game) +{ + var hiddenVar; + var eventEmitter = game.events; + + if (document.hidden !== undefined) + { + hiddenVar = 'visibilitychange'; + } + else + { + var vendors = [ 'webkit', 'moz', 'ms' ]; + + vendors.forEach(function (prefix) + { + if (document[prefix + 'Hidden'] !== undefined) + { + document.hidden = function () + { + return document[prefix + 'Hidden']; + }; + + hiddenVar = prefix + 'visibilitychange'; + } + + }); + } + + var onChange = function (event) + { + if (document.hidden || event.type === 'pause') + { + eventEmitter.emit(Events.HIDDEN); + } + else + { + eventEmitter.emit(Events.VISIBLE); + } + }; + + if (hiddenVar) + { + document.addEventListener(hiddenVar, onChange, false); + } + + window.onblur = function () + { + eventEmitter.emit(Events.BLUR); + }; + + window.onfocus = function () + { + eventEmitter.emit(Events.FOCUS); + }; + + // Automatically give the window focus unless config says otherwise + if (window.focus && game.config.autoFocus) + { + window.focus(); + } +}; + +module.exports = VisibilityHandler; + + +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Arne16 = __webpack_require__(383); +var CanvasPool = __webpack_require__(31); +var GetValue = __webpack_require__(6); + +/** + * Generates a texture based on the given Create configuration object. + * + * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the + * data cells map to a single color. For example, if the texture config looked like this: + * + * ```javascript + * var star = [ + * '.....828.....', + * '....72227....', + * '....82228....', + * '...7222227...', + * '2222222222222', + * '8222222222228', + * '.72222222227.', + * '..787777787..', + * '..877777778..', + * '.78778887787.', + * '.27887.78872.', + * '.787.....787.' + * ]; + * + * this.textures.generate('star', { data: star, pixelWidth: 4 }); + * ``` + * + * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array + * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color + * number 8 in the palette. If a cell contains a period character `.` then it is transparent. + * + * The default palette is Arne16, but you can specify your own using the `palette` property. + * + * @function Phaser.Create.GenerateTexture + * @since 3.0.0 + * + * @param {Phaser.Types.Create.GenerateTextureConfig} config - The Generate Texture Configuration object. + * + * @return {HTMLCanvasElement} An HTMLCanvasElement which contains the generated texture drawn to it. + */ +var GenerateTexture = function (config) +{ + var data = GetValue(config, 'data', []); + var canvas = GetValue(config, 'canvas', null); + var palette = GetValue(config, 'palette', Arne16); + var pixelWidth = GetValue(config, 'pixelWidth', 1); + var pixelHeight = GetValue(config, 'pixelHeight', pixelWidth); + var resizeCanvas = GetValue(config, 'resizeCanvas', true); + var clearCanvas = GetValue(config, 'clearCanvas', true); + var preRender = GetValue(config, 'preRender', null); + var postRender = GetValue(config, 'postRender', null); + + var width = Math.floor(Math.abs(data[0].length * pixelWidth)); + var height = Math.floor(Math.abs(data.length * pixelHeight)); + + if (!canvas) + { + canvas = CanvasPool.create2D(this, width, height); + resizeCanvas = false; + clearCanvas = false; + } + + if (resizeCanvas) + { + canvas.width = width; + canvas.height = height; + } + + var ctx = canvas.getContext('2d'); + + if (clearCanvas) + { + ctx.clearRect(0, 0, width, height); + } + + // preRender Callback? + if (preRender) + { + preRender(canvas, ctx); + } + + // Draw it + for (var y = 0; y < data.length; y++) + { + var row = data[y]; + + for (var x = 0; x < row.length; x++) + { + var d = row[x]; + + if (d !== '.' && d !== ' ') + { + ctx.fillStyle = palette[d]; + ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight); + } + } + } + + // postRender Callback? + if (postRender) + { + postRender(canvas, ctx); + } + + return canvas; +}; + +module.exports = GenerateTexture; + + +/***/ }), +/* 383 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A 16 color palette by [Arne](http://androidarts.com/palette/16pal.htm) + * + * @name Phaser.Create.Palettes.ARNE16 + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.exports = { + 0: '#000', + 1: '#9D9D9D', + 2: '#FFF', + 3: '#BE2633', + 4: '#E06F8B', + 5: '#493C2B', + 6: '#A46422', + 7: '#EB8931', + 8: '#F7E26B', + 9: '#2F484E', + A: '#44891A', + B: '#A3CE27', + C: '#1B2632', + D: '#005784', + E: '#31A2F2', + F: '#B2DCEF' +}; + + +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var CubicBezier = __webpack_require__(352); +var Curve = __webpack_require__(90); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A higher-order Bézier curve constructed of four points. + * + * @class CubicBezier + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector2[])} p0 - Start point, or an array of point pairs. + * @param {Phaser.Math.Vector2} p1 - Control Point 1. + * @param {Phaser.Math.Vector2} p2 - Control Point 2. + * @param {Phaser.Math.Vector2} p3 - End Point. + */ +var CubicBezierCurve = new Class({ + + Extends: Curve, + + initialize: + + function CubicBezierCurve (p0, p1, p2, p3) + { + Curve.call(this, 'CubicBezierCurve'); + + if (Array.isArray(p0)) + { + p3 = new Vector2(p0[6], p0[7]); + p2 = new Vector2(p0[4], p0[5]); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The start point of this curve. + * + * @name Phaser.Curves.CubicBezier#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = p0; + + /** + * The first control point of this curve. + * + * @name Phaser.Curves.CubicBezier#p1 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p1 = p1; + + /** + * The second control point of this curve. + * + * @name Phaser.Curves.CubicBezier#p2 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p2 = p2; + + /** + * The end point of this curve. + * + * @name Phaser.Curves.CubicBezier#p3 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p3 = p3; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.CubicBezier#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Returns the resolution of this curve. + * + * @method Phaser.Curves.CubicBezier#getResolution + * @since 3.0.0 + * + * @param {number} divisions - The amount of divisions used by this curve. + * + * @return {number} The resolution of the curve. + */ + getResolution: function (divisions) + { + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.CubicBezier#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var p0 = this.p0; + var p1 = this.p1; + var p2 = this.p2; + var p3 = this.p3; + + return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y)); + }, + + /** + * Draws this curve to the specified graphics object. + * + * @method Phaser.Curves.CubicBezier#draw + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - The graphics object this curve should be drawn to. + * @param {number} [pointsTotal=32] - The number of intermediary points that make up this curve. A higher number of points will result in a smoother curve. + * + * @return {Phaser.GameObjects.Graphics} The graphics object this curve was drawn to. Useful for method chaining. + */ + draw: function (graphics, pointsTotal) + { + if (pointsTotal === undefined) { pointsTotal = 32; } + + var points = this.getPoints(pointsTotal); + + graphics.beginPath(); + graphics.moveTo(this.p0.x, this.p0.y); + + for (var i = 1; i < points.length; i++) + { + graphics.lineTo(points[i].x, points[i].y); + } + + graphics.strokePath(); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Returns a JSON object that describes this curve. + * + * @method Phaser.Curves.CubicBezier#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y, + this.p2.x, this.p2.y, + this.p3.x, this.p3.y + ] + }; + } + +}); + +/** + * Generates a curve from a JSON object. + * + * @function Phaser.Curves.CubicBezier.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.CubicBezier} The curve generated from the JSON object. + */ +CubicBezierCurve.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + var p2 = new Vector2(points[4], points[5]); + var p3 = new Vector2(points[6], points[7]); + + return new CubicBezierCurve(p0, p1, p2, p3); +}; + +module.exports = CubicBezierCurve; + + +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var DegToRad = __webpack_require__(34); +var GetValue = __webpack_require__(6); +var RadToDeg = __webpack_require__(193); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * An Elliptical Curve derived from the Base Curve class. + * + * See https://en.wikipedia.org/wiki/Elliptic_curve for more details. + * + * @class Ellipse + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(number|Phaser.Types.Curves.EllipseCurveConfig)} [x=0] - The x coordinate of the ellipse, or an Ellipse Curve configuration object. + * @param {number} [y=0] - The y coordinate of the ellipse. + * @param {number} [xRadius=0] - The horizontal radius of ellipse. + * @param {number} [yRadius=0] - The vertical radius of ellipse. + * @param {number} [startAngle=0] - The start angle of the ellipse, in degrees. + * @param {number} [endAngle=360] - The end angle of the ellipse, in degrees. + * @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`). + * @param {number} [rotation=0] - The rotation of the ellipse, in degrees. + */ +var EllipseCurve = new Class({ + + Extends: Curve, + + initialize: + + function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) + { + if (typeof x === 'object') + { + var config = x; + + x = GetValue(config, 'x', 0); + y = GetValue(config, 'y', 0); + xRadius = GetValue(config, 'xRadius', 0); + yRadius = GetValue(config, 'yRadius', xRadius); + startAngle = GetValue(config, 'startAngle', 0); + endAngle = GetValue(config, 'endAngle', 360); + clockwise = GetValue(config, 'clockwise', false); + rotation = GetValue(config, 'rotation', 0); + } + else + { + if (yRadius === undefined) { yRadius = xRadius; } + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 360; } + if (clockwise === undefined) { clockwise = false; } + if (rotation === undefined) { rotation = 0; } + } + + Curve.call(this, 'EllipseCurve'); + + // Center point + + /** + * The center point of the ellipse. Used for calculating rotation. + * + * @name Phaser.Curves.Ellipse#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = new Vector2(x, y); + + /** + * The horizontal radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#_xRadius + * @type {number} + * @private + * @since 3.0.0 + */ + this._xRadius = xRadius; + + /** + * The vertical radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#_yRadius + * @type {number} + * @private + * @since 3.0.0 + */ + this._yRadius = yRadius; + + // Radians + + /** + * The starting angle of the ellipse in radians. + * + * @name Phaser.Curves.Ellipse#_startAngle + * @type {number} + * @private + * @since 3.0.0 + */ + this._startAngle = DegToRad(startAngle); + + /** + * The end angle of the ellipse in radians. + * + * @name Phaser.Curves.Ellipse#_endAngle + * @type {number} + * @private + * @since 3.0.0 + */ + this._endAngle = DegToRad(endAngle); + + /** + * Anti-clockwise direction. + * + * @name Phaser.Curves.Ellipse#_clockwise + * @type {boolean} + * @private + * @since 3.0.0 + */ + this._clockwise = clockwise; + + /** + * The rotation of the arc. + * + * @name Phaser.Curves.Ellipse#_rotation + * @type {number} + * @private + * @since 3.0.0 + */ + this._rotation = DegToRad(rotation); + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Ellipse#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return this.getPoint(0, out); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.Ellipse#getResolution + * @since 3.0.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions * 2; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Ellipse#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var twoPi = Math.PI * 2; + var deltaAngle = this._endAngle - this._startAngle; + var samePoints = Math.abs(deltaAngle) < Number.EPSILON; + + // ensures that deltaAngle is 0 .. 2 PI + while (deltaAngle < 0) + { + deltaAngle += twoPi; + } + + while (deltaAngle > twoPi) + { + deltaAngle -= twoPi; + } + + if (deltaAngle < Number.EPSILON) + { + if (samePoints) + { + deltaAngle = 0; + } + else + { + deltaAngle = twoPi; + } + } + + if (this._clockwise && !samePoints) + { + if (deltaAngle === twoPi) + { + deltaAngle = - twoPi; + } + else + { + deltaAngle = deltaAngle - twoPi; + } + } + + var angle = this._startAngle + t * deltaAngle; + var x = this.p0.x + this._xRadius * Math.cos(angle); + var y = this.p0.y + this._yRadius * Math.sin(angle); + + if (this._rotation !== 0) + { + var cos = Math.cos(this._rotation); + var sin = Math.sin(this._rotation); + + var tx = x - this.p0.x; + var ty = y - this.p0.y; + + // Rotate the point about the center of the ellipse. + x = tx * cos - ty * sin + this.p0.x; + y = tx * sin + ty * cos + this.p0.y; + } + + return out.set(x, y); + }, + + /** + * Sets the horizontal radius of this curve. + * + * @method Phaser.Curves.Ellipse#setXRadius + * @since 3.0.0 + * + * @param {number} value - The horizontal radius of this curve. + * + * @return {this} This curve object. + */ + setXRadius: function (value) + { + this.xRadius = value; + + return this; + }, + + /** + * Sets the vertical radius of this curve. + * + * @method Phaser.Curves.Ellipse#setYRadius + * @since 3.0.0 + * + * @param {number} value - The vertical radius of this curve. + * + * @return {this} This curve object. + */ + setYRadius: function (value) + { + this.yRadius = value; + + return this; + }, + + /** + * Sets the width of this curve. + * + * @method Phaser.Curves.Ellipse#setWidth + * @since 3.0.0 + * + * @param {number} value - The width of this curve. + * + * @return {this} This curve object. + */ + setWidth: function (value) + { + this.xRadius = value / 2; + + return this; + }, + + /** + * Sets the height of this curve. + * + * @method Phaser.Curves.Ellipse#setHeight + * @since 3.0.0 + * + * @param {number} value - The height of this curve. + * + * @return {this} This curve object. + */ + setHeight: function (value) + { + this.yRadius = value / 2; + + return this; + }, + + /** + * Sets the start angle of this curve. + * + * @method Phaser.Curves.Ellipse#setStartAngle + * @since 3.0.0 + * + * @param {number} value - The start angle of this curve, in radians. + * + * @return {this} This curve object. + */ + setStartAngle: function (value) + { + this.startAngle = value; + + return this; + }, + + /** + * Sets the end angle of this curve. + * + * @method Phaser.Curves.Ellipse#setEndAngle + * @since 3.0.0 + * + * @param {number} value - The end angle of this curve, in radians. + * + * @return {this} This curve object. + */ + setEndAngle: function (value) + { + this.endAngle = value; + + return this; + }, + + /** + * Sets if this curve extends clockwise or anti-clockwise. + * + * @method Phaser.Curves.Ellipse#setClockwise + * @since 3.0.0 + * + * @param {boolean} value - The clockwise state of this curve. + * + * @return {this} This curve object. + */ + setClockwise: function (value) + { + this.clockwise = value; + + return this; + }, + + /** + * Sets the rotation of this curve. + * + * @method Phaser.Curves.Ellipse#setRotation + * @since 3.0.0 + * + * @param {number} value - The rotation of this curve, in radians. + * + * @return {this} This curve object. + */ + setRotation: function (value) + { + this.rotation = value; + + return this; + }, + + /** + * The x coordinate of the center of the ellipse. + * + * @name Phaser.Curves.Ellipse#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.p0.x; + }, + + set: function (value) + { + this.p0.x = value; + } + + }, + + /** + * The y coordinate of the center of the ellipse. + * + * @name Phaser.Curves.Ellipse#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.p0.y; + }, + + set: function (value) + { + this.p0.y = value; + } + + }, + + /** + * The horizontal radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#xRadius + * @type {number} + * @since 3.0.0 + */ + xRadius: { + + get: function () + { + return this._xRadius; + }, + + set: function (value) + { + this._xRadius = value; + } + + }, + + /** + * The vertical radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#yRadius + * @type {number} + * @since 3.0.0 + */ + yRadius: { + + get: function () + { + return this._yRadius; + }, + + set: function (value) + { + this._yRadius = value; + } + + }, + + /** + * The start angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#startAngle + * @type {number} + * @since 3.0.0 + */ + startAngle: { + + get: function () + { + return RadToDeg(this._startAngle); + }, + + set: function (value) + { + this._startAngle = DegToRad(value); + } + + }, + + /** + * The end angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#endAngle + * @type {number} + * @since 3.0.0 + */ + endAngle: { + + get: function () + { + return RadToDeg(this._endAngle); + }, + + set: function (value) + { + this._endAngle = DegToRad(value); + } + + }, + + /** + * `true` if the ellipse rotation is clockwise or `false` if anti-clockwise. + * + * @name Phaser.Curves.Ellipse#clockwise + * @type {boolean} + * @since 3.0.0 + */ + clockwise: { + + get: function () + { + return this._clockwise; + }, + + set: function (value) + { + this._clockwise = value; + } + + }, + + /** + * The rotation of the ellipse, relative to the center, in degrees. + * + * @name Phaser.Curves.Ellipse#angle + * @type {number} + * @since 3.14.0 + */ + angle: { + + get: function () + { + return RadToDeg(this._rotation); + }, + + set: function (value) + { + this._rotation = DegToRad(value); + } + + }, + + /** + * The rotation of the ellipse, relative to the center, in radians. + * + * @name Phaser.Curves.Ellipse#rotation + * @type {number} + * @since 3.0.0 + */ + rotation: { + + get: function () + { + return this._rotation; + }, + + set: function (value) + { + this._rotation = value; + } + + }, + + /** + * JSON serialization of the curve. + * + * @method Phaser.Curves.Ellipse#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONEllipseCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + x: this.p0.x, + y: this.p0.y, + xRadius: this._xRadius, + yRadius: this._yRadius, + startAngle: RadToDeg(this._startAngle), + endAngle: RadToDeg(this._endAngle), + clockwise: this._clockwise, + rotation: RadToDeg(this._rotation) + }; + } + +}); + +/** + * Creates a curve from the provided Ellipse Curve Configuration object. + * + * @function Phaser.Curves.Ellipse.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. + */ +EllipseCurve.fromJSON = function (data) +{ + return new EllipseCurve(data); +}; + +module.exports = EllipseCurve; + + +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var FromPoints = __webpack_require__(196); +var Rectangle = __webpack_require__(10); +var Vector2 = __webpack_require__(3); + +var tmpVec2 = new Vector2(); + +/** + * @classdesc + * A LineCurve is a "curve" comprising exactly two points (a line segment). + * + * @class Line + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. + * @param {Phaser.Math.Vector2} [p1] - The second endpoint. + */ +var LineCurve = new Class({ + + Extends: Curve, + + initialize: + + // vec2s or array + function LineCurve (p0, p1) + { + Curve.call(this, 'LineCurve'); + + if (Array.isArray(p0)) + { + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The first endpoint. + * + * @name Phaser.Curves.Line#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = p0; + + /** + * The second endpoint. + * + * @name Phaser.Curves.Line#p1 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p1 = p1; + + // Override default Curve.arcLengthDivisions + + /** + * The quantity of arc length divisions within the curve. + * + * @name Phaser.Curves.Line#arcLengthDivisions + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.arcLengthDivisions = 1; + }, + + /** + * Returns a Rectangle where the position and dimensions match the bounds of this Curve. + * + * @method Phaser.Curves.Line#getBounds + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the bounds in. If not given a new Rectangle will be created. + * + * @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object. + */ + getBounds: function (out) + { + if (out === undefined) { out = new Rectangle(); } + + return FromPoints([ this.p0, this.p1 ], out); + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Line#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Gets the resolution of the line. + * + * @method Phaser.Curves.Line#getResolution + * @since 3.0.0 + * + * @param {number} [divisions=1] - The number of divisions to consider. + * + * @return {number} The resolution. Equal to the number of divisions. + */ + getResolution: function (divisions) + { + if (divisions === undefined) { divisions = 1; } + + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Line#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + if (t === 1) + { + return out.copy(this.p1); + } + + out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); + + return out; + }, + + // Line curve is linear, so we can overwrite default getPointAt + + /** + * Gets a point at a given position on the line. + * + * @method Phaser.Curves.Line#getPointAt + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} u - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPointAt: function (u, out) + { + return this.getPoint(u, out); + }, + + /** + * Gets the slope of the line as a unit vector. + * + * @method Phaser.Curves.Line#getTangent + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @return {Phaser.Math.Vector2} The tangent vector. + */ + getTangent: function () + { + var tangent = tmpVec2.copy(this.p1).subtract(this.p0); + + return tangent.normalize(); + }, + + /** + * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. + * + * @method Phaser.Curves.Line#getUtoTmapping + * @since 3.0.0 + * + * @param {number} u - A float between 0 and 1. + * @param {number} distance - The distance, in pixels. + * @param {number} [divisions] - Optional amount of divisions. + * + * @return {number} The equidistant value. + */ + getUtoTmapping: function (u, distance, divisions) + { + var t; + + if (distance) + { + var arcLengths = this.getLengths(divisions); + var lineLength = arcLengths[arcLengths.length - 1]; + + // Cannot overshoot the curve + var targetLineLength = Math.min(distance, lineLength); + + t = targetLineLength / lineLength; + } + else + { + t = u; + } + + return t; + }, + + // Override default Curve.draw because this is better than calling getPoints on a line! + + /** + * Draws this curve on the given Graphics object. + * + * The curve is drawn using `Graphics.lineBetween` so will be drawn at whatever the present Graphics line color is. + * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. + * + * @method Phaser.Curves.Line#draw + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn. + * + * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. + */ + draw: function (graphics) + { + graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Gets a JSON representation of the line. + * + * @method Phaser.Curves.Line#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y + ] + }; + } + +}); + +/** + * Configures this line from a JSON representation. + * + * @function Phaser.Curves.Line.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Line} A new LineCurve object. + */ +LineCurve.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + + return new LineCurve(p0, p1); +}; + +module.exports = LineCurve; + + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A MoveTo Curve is a very simple curve consisting of only a single point. + * Its intended use is to move the ending point in a Path. + * + * @class MoveTo + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - `x` pixel coordinate. + * @param {number} [y=0] - `y` pixel coordinate. + */ +var MoveTo = new Class({ + + initialize: + + function MoveTo (x, y) + { + /** + * Denotes that this Curve does not influence the bounds, points, and drawing of its parent Path. Must be `false` or some methods in the parent Path will throw errors. + * + * @name Phaser.Curves.MoveTo#active + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.active = false; + + /** + * The lone point which this curve consists of. + * + * @name Phaser.Curves.MoveTo#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = new Vector2(x, y); + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.MoveTo#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Retrieves the point at given position in the curve. This will always return this curve's only point. + * + * @method Phaser.Curves.MoveTo#getPointAt + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} u - The position in the path to retrieve, between 0 and 1. Not used. + * @param {Phaser.Math.Vector2} [out] - An optional vector in which to store the point. + * + * @return {Phaser.Math.Vector2} The modified `out` vector, or a new `Vector2` if none was provided. + */ + getPointAt: function (u, out) + { + return this.getPoint(u, out); + }, + + /** + * Gets the resolution of this curve. + * + * @method Phaser.Curves.MoveTo#getResolution + * @since 3.0.0 + * + * @return {number} The resolution of this curve. For a MoveTo the value is always 1. + */ + getResolution: function () + { + return 1; + }, + + /** + * Gets the length of this curve. + * + * @method Phaser.Curves.MoveTo#getLength + * @since 3.0.0 + * + * @return {number} The length of this curve. For a MoveTo the value is always 0. + */ + getLength: function () + { + return 0; + }, + + /** + * Converts this curve into a JSON-serializable object. + * + * @method Phaser.Curves.MoveTo#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} A primitive object with the curve's type and only point. + */ + toJSON: function () + { + return { + type: 'MoveTo', + points: [ + this.p0.x, this.p0.y + ] + }; + } + +}); + +module.exports = MoveTo; + + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var QuadraticBezierInterpolation = __webpack_require__(353); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A quadratic Bézier curve constructed from two control points. + * + * @class QuadraticBezier + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.2.0 + * + * @param {(Phaser.Math.Vector2|number[])} p0 - Start point, or an array of point pairs. + * @param {Phaser.Math.Vector2} p1 - Control Point 1. + * @param {Phaser.Math.Vector2} p2 - Control Point 2. + */ +var QuadraticBezier = new Class({ + + Extends: Curve, + + initialize: + + function QuadraticBezier (p0, p1, p2) + { + Curve.call(this, 'QuadraticBezier'); + + if (Array.isArray(p0)) + { + p2 = new Vector2(p0[4], p0[5]); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); + } + + /** + * The start point. + * + * @name Phaser.Curves.QuadraticBezier#p0 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p0 = p0; + + /** + * The first control point. + * + * @name Phaser.Curves.QuadraticBezier#p1 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p1 = p1; + + /** + * The second control point. + * + * @name Phaser.Curves.QuadraticBezier#p2 + * @type {Phaser.Math.Vector2} + * @since 3.2.0 + */ + this.p2 = p2; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.QuadraticBezier#getStartPoint + * @since 3.2.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.p0); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.QuadraticBezier#getResolution + * @since 3.2.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.QuadraticBezier#getPoint + * @since 3.2.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var p0 = this.p0; + var p1 = this.p1; + var p2 = this.p2; + + return out.set( + QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x), + QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y) + ); + }, + + /** + * Draws this curve on the given Graphics object. + * + * The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is. + * The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it. + * + * @method Phaser.Curves.QuadraticBezier#draw + * @since 3.2.0 + * + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * + * @param {Phaser.GameObjects.Graphics} graphics - `Graphics` object to draw onto. + * @param {number} [pointsTotal=32] - Number of points to be used for drawing the curve. Higher numbers result in smoother curve but require more processing. + * + * @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to. + */ + draw: function (graphics, pointsTotal) + { + if (pointsTotal === undefined) { pointsTotal = 32; } + + var points = this.getPoints(pointsTotal); + + graphics.beginPath(); + graphics.moveTo(this.p0.x, this.p0.y); + + for (var i = 1; i < points.length; i++) + { + graphics.lineTo(points[i].x, points[i].y); + } + + graphics.strokePath(); + + // So you can chain graphics calls + return graphics; + }, + + /** + * Converts the curve into a JSON compatible object. + * + * @method Phaser.Curves.QuadraticBezier#toJSON + * @since 3.2.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + return { + type: this.type, + points: [ + this.p0.x, this.p0.y, + this.p1.x, this.p1.y, + this.p2.x, this.p2.y + ] + }; + } + +}); + +/** + * Creates a curve from a JSON object, e. g. created by `toJSON`. + * + * @function Phaser.Curves.QuadraticBezier.fromJSON + * @since 3.2.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.QuadraticBezier} The created curve instance. + */ +QuadraticBezier.fromJSON = function (data) +{ + var points = data.points; + + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); + var p2 = new Vector2(points[4], points[5]); + + return new QuadraticBezier(p0, p1, p2); +}; + +module.exports = QuadraticBezier; + + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var CatmullRom = __webpack_require__(191); +var Class = __webpack_require__(0); +var Curve = __webpack_require__(90); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * Create a smooth 2d spline curve from a series of points. + * + * @class Spline + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2[]|number[]|number[][])} [points] - The points that configure the curve. + */ +var SplineCurve = new Class({ + + Extends: Curve, + + initialize: + + function SplineCurve (points) + { + if (points === undefined) { points = []; } + + Curve.call(this, 'SplineCurve'); + + /** + * The Vector2 points that configure the curve. + * + * @name Phaser.Curves.Spline#points + * @type {Phaser.Math.Vector2[]} + * @default [] + * @since 3.0.0 + */ + this.points = []; + + this.addPoints(points); + }, + + /** + * Add a list of points to the current list of Vector2 points of the curve. + * + * @method Phaser.Curves.Spline#addPoints + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve. + * + * @return {this} This curve object. + */ + addPoints: function (points) + { + for (var i = 0; i < points.length; i++) + { + var p = new Vector2(); + + if (typeof points[i] === 'number') + { + p.x = points[i]; + p.y = points[i + 1]; + i++; + } + else if (Array.isArray(points[i])) + { + // An array of arrays? + p.x = points[i][0]; + p.y = points[i][1]; + } + else + { + p.x = points[i].x; + p.y = points[i].y; + } + + this.points.push(p); + } + + return this; + }, + + /** + * Add a point to the current list of Vector2 points of the curve. + * + * @method Phaser.Curves.Spline#addPoint + * @since 3.0.0 + * + * @param {number} x - The x coordinate of this curve + * @param {number} y - The y coordinate of this curve + * + * @return {Phaser.Math.Vector2} The new Vector2 added to the curve + */ + addPoint: function (x, y) + { + var vec = new Vector2(x, y); + + this.points.push(vec); + + return vec; + }, + + /** + * Gets the starting point on the curve. + * + * @method Phaser.Curves.Spline#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.points[0]); + }, + + /** + * Get the resolution of the curve. + * + * @method Phaser.Curves.Spline#getResolution + * @since 3.0.0 + * + * @param {number} divisions - Optional divisions value. + * + * @return {number} The curve resolution. + */ + getResolution: function (divisions) + { + return divisions * this.points.length; + }, + + /** + * Get point at relative position in curve according to length. + * + * @method Phaser.Curves.Spline#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end. + * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } + + var points = this.points; + + var point = (points.length - 1) * t; + + var intPoint = Math.floor(point); + + var weight = point - intPoint; + + var p0 = points[(intPoint === 0) ? intPoint : intPoint - 1]; + var p1 = points[intPoint]; + var p2 = points[(intPoint > points.length - 2) ? points.length - 1 : intPoint + 1]; + var p3 = points[(intPoint > points.length - 3) ? points.length - 1 : intPoint + 2]; + + return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); + }, + + /** + * Exports a JSON object containing this curve data. + * + * @method Phaser.Curves.Spline#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + */ + toJSON: function () + { + var points = []; + + for (var i = 0; i < this.points.length; i++) + { + points.push(this.points[i].x); + points.push(this.points[i].y); + } + + return { + type: this.type, + points: points + }; + } + +}); + +/** + * Imports a JSON object containing this curve data. + * + * @function Phaser.Curves.Spline.fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * + * @return {Phaser.Curves.Spline} The spline curve created. + */ +SplineCurve.fromJSON = function (data) +{ + return new SplineCurve(data.points); +}; + +module.exports = SplineCurve; + + +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A BaseShader is a small resource class that contains the data required for a WebGL Shader to be created. + * + * It contains the raw source code to the fragment and vertex shader, as well as an object that defines + * the uniforms the shader requires, if any. + * + * BaseShaders are stored in the Shader Cache, available in a Scene via `this.cache.shaders` and are referenced + * by a unique key-based string. Retrieve them via `this.cache.shaders.get(key)`. + * + * BaseShaders are created automatically by the GLSL File Loader when loading an external shader resource. + * They can also be created at runtime, allowing you to use dynamically generated shader source code. + * + * Default fragment and vertex source is used if not provided in the constructor, setting-up a basic shader, + * suitable for debug rendering. + * + * @class BaseShader + * @memberof Phaser.Display + * @constructor + * @since 3.17.0 + * + * @param {string} key - The key of this shader. Must be unique within the shader cache. + * @param {string} [fragmentSrc] - The fragment source for the shader. + * @param {string} [vertexSrc] - The vertex source for the shader. + * @param {any} [uniforms] - Optional object defining the uniforms the shader uses. + */ +var BaseShader = new Class({ + + initialize: + + function BaseShader (key, fragmentSrc, vertexSrc, uniforms) + { + if (!fragmentSrc || fragmentSrc === '') + { + fragmentSrc = [ + 'precision mediump float;', + + 'uniform vec2 resolution;', + + 'varying vec2 fragCoord;', + + 'void main () {', + ' vec2 uv = fragCoord / resolution.xy;', + ' gl_FragColor = vec4(uv.xyx, 1.0);', + '}' + ].join('\n'); + } + + if (!vertexSrc || vertexSrc === '') + { + vertexSrc = [ + 'precision mediump float;', + + 'uniform mat4 uProjectionMatrix;', + 'uniform mat4 uViewMatrix;', + 'uniform vec2 uResolution;', + + 'attribute vec2 inPosition;', + + 'varying vec2 fragCoord;', + 'varying vec2 outTexCoord;', + + 'void main () {', + ' gl_Position = uProjectionMatrix * uViewMatrix * vec4(inPosition, 1.0, 1.0);', + ' fragCoord = vec2(inPosition.x, uResolution.y - inPosition.y);', + ' outTexCoord = vec2(inPosition.x / uResolution.x, fragCoord.y / uResolution.y);', + '}' + ].join('\n'); + } + + if (uniforms === undefined) { uniforms = null; } + + /** + * The key of this shader, unique within the shader cache of this Phaser game instance. + * + * @name Phaser.Display.BaseShader#key + * @type {string} + * @since 3.17.0 + */ + this.key = key; + + /** + * The source code, as a string, of the fragment shader being used. + * + * @name Phaser.Display.BaseShader#fragmentSrc + * @type {string} + * @since 3.17.0 + */ + this.fragmentSrc = fragmentSrc; + + /** + * The source code, as a string, of the vertex shader being used. + * + * @name Phaser.Display.BaseShader#vertexSrc + * @type {string} + * @since 3.17.0 + */ + this.vertexSrc = vertexSrc; + + /** + * The default uniforms for this shader. + * + * @name Phaser.Display.BaseShader#uniforms + * @type {?any} + * @since 3.17.0 + */ + this.uniforms = uniforms; + } + +}); + +module.exports = BaseShader; + + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Color = __webpack_require__(36); + +Color.ColorSpectrum = __webpack_require__(905); +Color.ColorToRGBA = __webpack_require__(906); +Color.ComponentToHex = __webpack_require__(392); +Color.GetColor = __webpack_require__(100); +Color.GetColor32 = __webpack_require__(322); +Color.HexStringToColor = __webpack_require__(321); +Color.HSLToColor = __webpack_require__(907); +Color.HSVColorWheel = __webpack_require__(908); +Color.HSVToRGB = __webpack_require__(185); +Color.HueToComponent = __webpack_require__(393); +Color.IntegerToColor = __webpack_require__(186); +Color.IntegerToRGB = __webpack_require__(324); +Color.Interpolate = __webpack_require__(909); +Color.ObjectToColor = __webpack_require__(325); +Color.RandomRGB = __webpack_require__(910); +Color.RGBStringToColor = __webpack_require__(326); +Color.RGBToHSV = __webpack_require__(323); +Color.RGBToString = __webpack_require__(911); +Color.ValueToColor = __webpack_require__(184); + +module.exports = Color; + + +/***/ }), +/* 392 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns a string containing a hex representation of the given color component. + * + * @function Phaser.Display.Color.ComponentToHex + * @since 3.0.0 + * + * @param {number} color - The color channel to get the hex value for, must be a value between 0 and 255. + * + * @return {string} A string of length 2 characters, i.e. 255 = ff, 100 = 64. + */ +var ComponentToHex = function (color) +{ + var hex = color.toString(16); + + return (hex.length === 1) ? '0' + hex : hex; +}; + +module.exports = ComponentToHex; + + +/***/ }), +/* 393 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts a hue to an RGB color. + * Based on code by Michael Jackson (https://github.com/mjijackson) + * + * @function Phaser.Display.Color.HueToComponent + * @since 3.0.0 + * + * @param {number} p + * @param {number} q + * @param {number} t + * + * @return {number} The combined color value. + */ +var HueToComponent = function (p, q, t) +{ + if (t < 0) + { + t += 1; + } + + if (t > 1) + { + t -= 1; + } + + if (t < 1 / 6) + { + return p + (q - p) * 6 * t; + } + + if (t < 1 / 2) + { + return q; + } + + if (t < 2 / 3) + { + return p + (q - p) * (2 / 3 - t) * 6; + } + + return p; +}; + +module.exports = HueToComponent; + + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var OS = __webpack_require__(102); + +/** + * @callback ContentLoadedCallback + */ + +/** + * Inspects the readyState of the document. If the document is already complete then it invokes the given callback. + * If not complete it sets up several event listeners such as `deviceready`, and once those fire, it invokes the callback. + * Called automatically by the Phaser.Game instance. Should not usually be accessed directly. + * + * @function Phaser.DOM.DOMContentLoaded + * @since 3.0.0 + * + * @param {ContentLoadedCallback} callback - The callback to be invoked when the device is ready and the DOM content is loaded. + */ +var DOMContentLoaded = function (callback) +{ + if (document.readyState === 'complete' || document.readyState === 'interactive') + { + callback(); + + return; + } + + var check = function () + { + document.removeEventListener('deviceready', check, true); + document.removeEventListener('DOMContentLoaded', check, true); + window.removeEventListener('load', check, true); + + callback(); + }; + + if (!document.body) + { + window.setTimeout(check, 20); + } + else if (OS.cordova) + { + // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready + document.addEventListener('deviceready', check, false); + } + else + { + document.addEventListener('DOMContentLoaded', check, true); + window.addEventListener('load', check, true); + } +}; + +module.exports = DOMContentLoaded; + + +/***/ }), +/* 395 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Attempts to determine the document inner height across iOS and standard devices. + * Based on code by @tylerjpeterson + * + * @function Phaser.DOM.GetInnerHeight + * @since 3.16.0 + * + * @param {boolean} iOS - Is this running on iOS? + * + * @return {number} The inner height value. + */ +var GetInnerHeight = function (iOS) +{ + + if (!iOS) + { + return window.innerHeight; + } + + var axis = Math.abs(window.orientation); + + var size = { w: 0, h: 0 }; + + var ruler = document.createElement('div'); + + ruler.setAttribute('style', 'position: fixed; height: 100vh; width: 0; top: 0'); + + document.documentElement.appendChild(ruler); + + size.w = (axis === 90) ? ruler.offsetHeight : window.innerWidth; + size.h = (axis === 90) ? window.innerWidth : ruler.offsetHeight; + + document.documentElement.removeChild(ruler); + + ruler = null; + + if (Math.abs(window.orientation) !== 90) + { + return size.h; + } + else + { + return size.w; + } +}; + +module.exports = GetInnerHeight; + + +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(198); + +/** + * Attempts to determine the screen orientation using the Orientation API. + * + * @function Phaser.DOM.GetScreenOrientation + * @since 3.16.0 + * + * @param {number} width - The width of the viewport. + * @param {number} height - The height of the viewport. + * + * @return {string} The orientation. + */ +var GetScreenOrientation = function (width, height) +{ + var screen = window.screen; + var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; + + if (orientation && typeof orientation.type === 'string') + { + // Screen Orientation API specification + return orientation.type; + } + else if (typeof orientation === 'string') + { + // moz / ms-orientation are strings + return orientation; + } + + if (typeof window.orientation === 'number') + { + // Do this check first, as iOS supports this, but also has an incomplete window.screen implementation + // This may change by device based on "natural" orientation. + return (window.orientation === 0 || window.orientation === 180) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; + } + else if (window.matchMedia) + { + if (window.matchMedia('(orientation: portrait)').matches) + { + return CONST.ORIENTATION.PORTRAIT; + } + else if (window.matchMedia('(orientation: landscape)').matches) + { + return CONST.ORIENTATION.LANDSCAPE; + } + } + else + { + return (height > width) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; + } +}; + +module.exports = GetScreenOrientation; + + +/***/ }), +/* 397 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for centering the game canvas. + * + * @namespace Phaser.Scale.Center + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for centering the game canvas. + * + * To find out what each mode does please see [Phaser.Scale.Center]{@link Phaser.Scale.Center}. + * + * @typedef {Phaser.Scale.Center} Phaser.Scale.CenterType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * The game canvas is not centered within the parent by Phaser. + * You can still center it yourself via CSS. + * + * @name Phaser.Scale.Center.NO_CENTER + * @type {number} + * @const + * @since 3.16.0 + */ + NO_CENTER: 0, + + /** + * The game canvas is centered both horizontally and vertically within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_BOTH + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_BOTH: 1, + + /** + * The game canvas is centered horizontally within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_HORIZONTALLY + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_HORIZONTALLY: 2, + + /** + * The game canvas is centered both vertically within the parent. + * To do this, the parent has to have a bounds that can be calculated and not be empty. + * + * Centering is achieved by setting the margin left and top properties of the + * game canvas, and does not factor in any other CSS styles you may have applied. + * + * @name Phaser.Scale.Center.CENTER_VERTICALLY + * @type {number} + * @const + * @since 3.16.0 + */ + CENTER_VERTICALLY: 3 + +}; + + +/***/ }), +/* 398 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for orientation. + * + * @namespace Phaser.Scale.Orientation + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for orientation. + * + * To find out what each mode does please see [Phaser.Scale.Orientation]{@link Phaser.Scale.Orientation}. + * + * @typedef {Phaser.Scale.Orientation} Phaser.Scale.OrientationType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * A landscape orientation. + * + * @name Phaser.Scale.Orientation.LANDSCAPE + * @type {string} + * @const + * @since 3.16.0 + */ + LANDSCAPE: 'landscape-primary', + + /** + * A portrait orientation. + * + * @name Phaser.Scale.Orientation.PORTRAIT + * @type {string} + * @const + * @since 3.16.0 + */ + PORTRAIT: 'portrait-primary' + +}; + + +/***/ }), +/* 399 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for the different scale modes available. + * + * @namespace Phaser.Scale.ScaleModes + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for the different scale modes available. + * + * To find out what each mode does please see [Phaser.Scale.ScaleModes]{@link Phaser.Scale.ScaleModes}. + * + * @typedef {Phaser.Scale.ScaleModes} Phaser.Scale.ScaleModeType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * No scaling happens at all. The canvas is set to the size given in the game config and Phaser doesn't change it + * again from that point on. If you change the canvas size, either via CSS, or directly via code, then you need + * to call the Scale Managers `resize` method to give the new dimensions, or input events will stop working. + * + * @name Phaser.Scale.ScaleModes.NONE + * @type {number} + * @const + * @since 3.16.0 + */ + NONE: 0, + + /** + * The height is automatically adjusted based on the width. + * + * @name Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT + * @type {number} + * @const + * @since 3.16.0 + */ + WIDTH_CONTROLS_HEIGHT: 1, + + /** + * The width is automatically adjusted based on the height. + * + * @name Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH + * @type {number} + * @const + * @since 3.16.0 + */ + HEIGHT_CONTROLS_WIDTH: 2, + + /** + * The width and height are automatically adjusted to fit inside the given target area, + * while keeping the aspect ratio. Depending on the aspect ratio there may be some space + * inside the area which is not covered. + * + * @name Phaser.Scale.ScaleModes.FIT + * @type {number} + * @const + * @since 3.16.0 + */ + FIT: 3, + + /** + * The width and height are automatically adjusted to make the size cover the entire target + * area while keeping the aspect ratio. This may extend further out than the target size. + * + * @name Phaser.Scale.ScaleModes.ENVELOP + * @type {number} + * @const + * @since 3.16.0 + */ + ENVELOP: 4, + + /** + * The Canvas is resized to fit all available _parent_ space, regardless of aspect ratio. + * + * @name Phaser.Scale.ScaleModes.RESIZE + * @type {number} + * @const + * @since 3.16.0 + */ + RESIZE: 5 + +}; + + +/***/ }), +/* 400 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Scale Manager constants for zoom modes. + * + * @namespace Phaser.Scale.Zoom + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +/** + * Phaser Scale Manager constants for zoom modes. + * + * To find out what each mode does please see [Phaser.Scale.Zoom]{@link Phaser.Scale.Zoom}. + * + * @typedef {Phaser.Scale.Zoom} Phaser.Scale.ZoomType + * @memberof Phaser.Scale + * @since 3.16.0 + */ + +module.exports = { + + /** + * The game canvas will not be zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.NO_ZOOM + * @type {number} + * @const + * @since 3.16.0 + */ + NO_ZOOM: 1, + + /** + * The game canvas will be 2x zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.ZOOM_2X + * @type {number} + * @const + * @since 3.16.0 + */ + ZOOM_2X: 2, + + /** + * The game canvas will be 4x zoomed by Phaser. + * + * @name Phaser.Scale.Zoom.ZOOM_4X + * @type {number} + * @const + * @since 3.16.0 + */ + ZOOM_4X: 4, + + /** + * Calculate the zoom value based on the maximum multiplied game size that will + * fit into the parent, or browser window if no parent is set. + * + * @name Phaser.Scale.Zoom.MAX_ZOOM + * @type {number} + * @const + * @since 3.16.0 + */ + MAX_ZOOM: -1 + +}; + + +/***/ }), +/* 401 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Attempts to get the target DOM element based on the given value, which can be either + * a string, in which case it will be looked-up by ID, or an element node. If nothing + * can be found it will return a reference to the document.body. + * + * @function Phaser.DOM.GetTarget + * @since 3.16.0 + * + * @param {HTMLElement} element - The DOM element to look-up. + */ +var GetTarget = function (element) +{ + var target; + + if (element !== '') + { + if (typeof element === 'string') + { + // Hopefully an element ID + target = document.getElementById(element); + } + else if (element && element.nodeType === 1) + { + // Quick test for a HTMLElement + target = element; + } + } + + // Fallback to the document body. Covers an invalid ID and a non HTMLElement object. + if (!target) + { + // Use the full window + target = document.body; + } + + return target; +}; + +module.exports = GetTarget; + + +/***/ }), +/* 402 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Takes the given data string and parses it as XML. + * First tries to use the window.DOMParser and reverts to the Microsoft.XMLDOM if that fails. + * The parsed XML object is returned, or `null` if there was an error while parsing the data. + * + * @function Phaser.DOM.ParseXML + * @since 3.0.0 + * + * @param {string} data - The XML source stored in a string. + * + * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. + */ +var ParseXML = function (data) +{ + var xml = ''; + + try + { + if (window['DOMParser']) + { + var domparser = new DOMParser(); + xml = domparser.parseFromString(data, 'text/xml'); + } + else + { + xml = new ActiveXObject('Microsoft.XMLDOM'); + xml.loadXML(data); + } + } + catch (e) + { + xml = null; + } + + if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) + { + return null; + } + else + { + return xml; + } +}; + +module.exports = ParseXML; + + +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(200); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(49); +var GameEvents = __webpack_require__(22); +var Keyboard = __webpack_require__(404); +var Mouse = __webpack_require__(405); +var Pointer = __webpack_require__(406); +var Touch = __webpack_require__(407); +var TransformMatrix = __webpack_require__(25); +var TransformXY = __webpack_require__(174); + +/** + * @classdesc + * The Input Manager is responsible for handling the pointer related systems in a single Phaser Game instance. + * + * Based on the Game Config it will create handlers for mouse and touch support. + * + * Keyboard and Gamepad are plugins, handled directly by the InputPlugin class. + * + * It then manages the events, pointer creation and general hit test related operations. + * + * You rarely need to interact with the Input Manager directly, and as such, all of its properties and methods + * should be considered private. Instead, you should use the Input Plugin, which is a Scene level system, responsible + * for dealing with all input events for a Scene. + * + * @class InputManager + * @memberof Phaser.Input + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Game instance that owns the Input Manager. + * @param {object} config - The Input Configuration object, as set in the Game Config. + */ +var InputManager = new Class({ + + initialize: + + function InputManager (game, config) + { + /** + * The Game instance that owns the Input Manager. + * A Game only maintains on instance of the Input Manager at any time. + * + * @name Phaser.Input.InputManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; + + /** + * A reference to the global Game Scale Manager. + * Used for all bounds checks and pointer scaling. + * + * @name Phaser.Input.InputManager#scaleManager + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.0 + */ + this.scaleManager; + + /** + * The Canvas that is used for all DOM event input listeners. + * + * @name Phaser.Input.InputManager#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.canvas; + + /** + * The Game Configuration object, as set during the game boot. + * + * @name Phaser.Input.InputManager#config + * @type {Phaser.Core.Config} + * @since 3.0.0 + */ + this.config = config; + + /** + * If set, the Input Manager will run its update loop every frame. + * + * @name Phaser.Input.InputManager#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * The Event Emitter instance that the Input Manager uses to emit events from. + * + * @name Phaser.Input.InputManager#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = new EventEmitter(); + + /** + * Are any mouse or touch pointers currently over the game canvas? + * This is updated automatically by the canvas over and out handlers. + * + * @name Phaser.Input.InputManager#isOver + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + this.isOver = true; + + /** + * The default CSS cursor to be used when interacting with your game. + * + * See the `setDefaultCursor` method for more details. + * + * @name Phaser.Input.InputManager#defaultCursor + * @type {string} + * @since 3.10.0 + */ + this.defaultCursor = ''; + + /** + * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. + * + * @name Phaser.Input.InputManager#keyboard + * @type {?Phaser.Input.Keyboard.KeyboardManager} + * @since 3.16.0 + */ + this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; + + /** + * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. + * + * @name Phaser.Input.InputManager#mouse + * @type {?Phaser.Input.Mouse.MouseManager} + * @since 3.0.0 + */ + this.mouse = (config.inputMouse) ? new Mouse(this) : null; + + /** + * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. + * + * @name Phaser.Input.InputManager#touch + * @type {Phaser.Input.Touch.TouchManager} + * @since 3.0.0 + */ + this.touch = (config.inputTouch) ? new Touch(this) : null; + + /** + * An array of Pointers that have been added to the game. + * The first entry is reserved for the Mouse Pointer, the rest are Touch Pointers. + * + * By default there is 1 touch pointer enabled. If you need more use the `addPointer` method to start them, + * or set the `input.activePointers` property in the Game Config. + * + * @name Phaser.Input.InputManager#pointers + * @type {Phaser.Input.Pointer[]} + * @since 3.10.0 + */ + this.pointers = []; + + /** + * The number of touch objects activated and being processed each update. + * + * You can change this by either calling `addPointer` at run-time, or by + * setting the `input.activePointers` property in the Game Config. + * + * @name Phaser.Input.InputManager#pointersTotal + * @type {number} + * @readonly + * @since 3.10.0 + */ + this.pointersTotal = config.inputActivePointers; + + if (config.inputTouch && this.pointersTotal === 1) + { + this.pointersTotal = 2; + } + + for (var i = 0; i <= this.pointersTotal; i++) + { + var pointer = new Pointer(this, i); + + pointer.smoothFactor = config.inputSmoothFactor; + + this.pointers.push(pointer); + } + + /** + * The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_. + * If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer` + * which will always map to the most recently interacted pointer. + * + * @name Phaser.Input.InputManager#mousePointer + * @type {?Phaser.Input.Pointer} + * @since 3.10.0 + */ + this.mousePointer = (config.inputMouse) ? this.pointers[0] : null; + + /** + * The most recently active Pointer object. + * + * If you've only 1 Pointer in your game then this will accurately be either the first finger touched, or the mouse. + * + * If your game doesn't need to support multi-touch then you can safely use this property in all of your game + * code and it will adapt to be either the mouse or the touch, based on device. + * + * @name Phaser.Input.InputManager#activePointer + * @type {Phaser.Input.Pointer} + * @since 3.0.0 + */ + this.activePointer = this.pointers[0]; + + /** + * If the top-most Scene in the Scene List receives an input it will stop input from + * propagating any lower down the scene list, i.e. if you have a UI Scene at the top + * and click something on it, that click will not then be passed down to any other + * Scene below. Disable this to have input events passed through all Scenes, all the time. + * + * @name Phaser.Input.InputManager#globalTopOnly + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.globalTopOnly = true; + + /** + * The time this Input Manager was last updated. + * This value is populated by the Game Step each frame. + * + * @name Phaser.Input.InputManager#time + * @type {number} + * @readonly + * @since 3.16.2 + */ + this.time = 0; + + /** + * A re-cycled point-like object to store hit test values in. + * + * @name Phaser.Input.InputManager#_tempPoint + * @type {{x:number, y:number}} + * @private + * @since 3.0.0 + */ + this._tempPoint = { x: 0, y: 0 }; + + /** + * A re-cycled array to store hit results in. + * + * @name Phaser.Input.InputManager#_tempHitTest + * @type {array} + * @private + * @default [] + * @since 3.0.0 + */ + this._tempHitTest = []; + + /** + * A re-cycled matrix used in hit test calculations. + * + * @name Phaser.Input.InputManager#_tempMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.4.0 + */ + this._tempMatrix = new TransformMatrix(); + + /** + * A re-cycled matrix used in hit test calculations. + * + * @name Phaser.Input.InputManager#_tempMatrix2 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + /** + * An internal private var that records Scenes aborting event processing. + * + * @name Phaser.Input.InputManager#_tempSkip + * @type {boolean} + * @private + * @since 3.18.0 + */ + this._tempSkip = false; + + /** + * An internal private array that avoids needing to create a new array on every DOM mouse event. + * + * @name Phaser.Input.InputManager#mousePointerContainer + * @type {Phaser.Input.Pointer[]} + * @private + * @since 3.18.0 + */ + this.mousePointerContainer = [ this.mousePointer ]; + + game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot handler is called by Phaser.Game when it first starts up. + * The renderer is available by now. + * + * @method Phaser.Input.InputManager#boot + * @protected + * @fires Phaser.Input.Events#MANAGER_BOOT + * @since 3.0.0 + */ + boot: function () + { + this.canvas = this.game.canvas; + + this.scaleManager = this.game.scale; + + this.events.emit(Events.MANAGER_BOOT); + + this.game.events.on(GameEvents.PRE_RENDER, this.preRender, this); + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * Internal canvas state change, called automatically by the Mouse Manager. + * + * @method Phaser.Input.InputManager#setCanvasOver + * @fires Phaser.Input.Events#GAME_OVER + * @private + * @since 3.16.0 + * + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + */ + setCanvasOver: function (event) + { + this.isOver = true; + + this.events.emit(Events.GAME_OVER, event); + }, + + /** + * Internal canvas state change, called automatically by the Mouse Manager. + * + * @method Phaser.Input.InputManager#setCanvasOut + * @fires Phaser.Input.Events#GAME_OUT + * @private + * @since 3.16.0 + * + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + */ + setCanvasOut: function (event) + { + this.isOver = false; + + this.events.emit(Events.GAME_OUT, event); + }, + + /** + * Internal update, called automatically by the Game Step right at the start. + * + * @method Phaser.Input.InputManager#preRender + * @private + * @since 3.18.0 + */ + preRender: function () + { + var time = this.game.loop.now; + var delta = this.game.loop.delta; + var scenes = this.game.scene.getScenes(true, true); + + this.time = time; + + this.events.emit(Events.MANAGER_UPDATE); + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene.sys.input && scene.sys.input.updatePoll(time, delta) && this.globalTopOnly) + { + // If the Scene returns true, it means it captured some input that no other Scene should get, so we bail out + return; + } + } + }, + + /** + * Tells the Input system to set a custom cursor. + * + * This cursor will be the default cursor used when interacting with the game canvas. + * + * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. + * + * Any valid CSS cursor value is allowed, including paths to image files, i.e.: + * + * ```javascript + * this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer'); + * ``` + * + * Please read about the differences between browsers when it comes to the file formats and sizes they support: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor + * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property + * + * It's up to you to pick a suitable cursor format that works across the range of browsers you need to support. + * + * @method Phaser.Input.InputManager#setDefaultCursor + * @since 3.10.0 + * + * @param {string} cursor - The CSS to be used when setting the default cursor. + */ + setDefaultCursor: function (cursor) + { + this.defaultCursor = cursor; + + if (this.canvas.style.cursor !== cursor) + { + this.canvas.style.cursor = cursor; + } + }, + + /** + * Called by the InputPlugin when processing over and out events. + * + * Tells the Input Manager to set a custom cursor during its postUpdate step. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor + * + * @method Phaser.Input.InputManager#setCursor + * @private + * @since 3.10.0 + * + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. + */ + setCursor: function (interactiveObject) + { + if (interactiveObject.cursor) + { + this.canvas.style.cursor = interactiveObject.cursor; + } + }, + + /** + * Called by the InputPlugin when processing over and out events. + * + * Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step. + * + * @method Phaser.Input.InputManager#resetCursor + * @private + * @since 3.10.0 + * + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. + */ + resetCursor: function (interactiveObject) + { + if (interactiveObject.cursor && this.canvas) + { + this.canvas.style.cursor = this.defaultCursor; + } + }, + + /** + * Adds new Pointer objects to the Input Manager. + * + * By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`. + * + * You can create more either by calling this method, or by setting the `input.activePointers` property + * in the Game Config, up to a maximum of 10 pointers. + * + * The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added + * via this method. + * + * @method Phaser.Input.InputManager#addPointer + * @since 3.10.0 + * + * @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total. + * + * @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created. + */ + addPointer: function (quantity) + { + if (quantity === undefined) { quantity = 1; } + + var output = []; + + if (this.pointersTotal + quantity > 10) + { + quantity = 10 - this.pointersTotal; + } + + for (var i = 0; i < quantity; i++) + { + var id = this.pointers.length; + + var pointer = new Pointer(this, id); + + pointer.smoothFactor = this.config.inputSmoothFactor; + + this.pointers.push(pointer); + + this.pointersTotal++; + + output.push(pointer); + } + + return output; + }, + + /** + * Internal method that gets a list of all the active Input Plugins in the game + * and updates each of them in turn, in reverse order (top to bottom), to allow + * for DOM top-level event handling simulation. + * + * @method Phaser.Input.InputManager#updateInputPlugins + * @since 3.16.0 + * + * @param {number} type - The type of event to process. + * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. + */ + updateInputPlugins: function (type, pointers) + { + var scenes = this.game.scene.getScenes(true, true); + + this._tempSkip = false; + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene.sys.input) + { + var capture = scene.sys.input.update(type, pointers); + + if ((capture && this.globalTopOnly) || this._tempSkip) + { + // If the Scene returns true, or called stopPropagation, it means it captured some input that no other Scene should get, so we bail out + return; + } + } + } + }, + + // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element) + // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + + /** + * Processes a touch start event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchStart + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchStart: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (!pointer.active) + { + pointer.touchstart(changedTouch, event); + + this.activePointer = pointer; + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_START, changed); + }, + + /** + * Processes a touch move event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchMove + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchMove: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchmove(changedTouch, event); + + this.activePointer = pointer; + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_MOVE, changed); + }, + + // For touch end its a list of the touch points that have been removed from the surface + // https://developer.mozilla.org/en-US/docs/DOM/TouchList + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + + /** + * Processes a touch end event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchEnd + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchEnd: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchend(changedTouch, event); + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_END, changed); + }, + + /** + * Processes a touch cancel event, as passed in by the TouchManager. + * + * @method Phaser.Input.InputManager#onTouchCancel + * @private + * @since 3.18.0 + * + * @param {TouchEvent} event - The native DOM Touch event. + */ + onTouchCancel: function (event) + { + var pointers = this.pointers; + var changed = []; + + for (var c = 0; c < event.changedTouches.length; c++) + { + var changedTouch = event.changedTouches[c]; + + for (var i = 1; i < this.pointersTotal; i++) + { + var pointer = pointers[i]; + + if (pointer.active && pointer.identifier === changedTouch.identifier) + { + pointer.touchcancel(changedTouch, event); + + changed.push(pointer); + + break; + } + } + } + + this.updateInputPlugins(CONST.TOUCH_CANCEL, changed); + }, + + /** + * Processes a mouse down event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseDown + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseDown: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.down(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer); + }, + + /** + * Processes a mouse move event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseMove + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseMove: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.move(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer); + }, + + /** + * Processes a mouse up event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseUp + * @private + * @since 3.18.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onMouseUp: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.up(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); + }, + + /** + * Processes a mouse wheel event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onMouseWheel + * @private + * @since 3.18.0 + * + * @param {WheelEvent} event - The native DOM Wheel event. + */ + onMouseWheel: function (event) + { + var mousePointer = this.mousePointer; + + mousePointer.wheel(event); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer); + }, + + /** + * Processes a pointer lock change event, as passed in by the MouseManager. + * + * @method Phaser.Input.InputManager#onPointerLockChange + * @fires Phaser.Input.Events#POINTERLOCK_CHANGE + * @private + * @since 3.19.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. + */ + onPointerLockChange: function (event) + { + var isLocked = this.mouse.locked; + + this.mousePointer.locked = isLocked; + + this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked); + }, + + /** + * Checks if the given Game Object should be considered as a candidate for input or not. + * + * Checks if the Game Object has an input component that is enabled, that it will render, + * and finally, if it has a parent, that the parent parent, or any ancestor, is visible or not. + * + * @method Phaser.Input.InputManager#inputCandidate + * @private + * @since 3.10.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to test. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * + * @return {boolean} `true` if the Game Object should be considered for input, otherwise `false`. + */ + inputCandidate: function (gameObject, camera) + { + var input = gameObject.input; + + if (!input || !input.enabled || (!input.alwaysEnabled && !gameObject.willRender(camera))) + { + return false; + } + + var visible = true; + var parent = gameObject.parentContainer; + + if (parent) + { + do + { + if (!parent.willRender(camera)) + { + visible = false; + break; + } + + parent = parent.parentContainer; + + } while (parent); + } + + return visible; + }, + + /** + * Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects. + * + * The Game Objects are culled against the camera, and then the coordinates are translated into the local camera space + * and used to determine if they fall within the remaining Game Objects hit areas or not. + * + * If nothing is matched an empty array is returned. + * + * This method is called automatically by InputPlugin.hitTestPointer and doesn't usually need to be invoked directly. + * + * @method Phaser.Input.InputManager#hitTest + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to test against. + * @param {array} gameObjects - An array of interactive Game Objects to check. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * @param {array} [output] - An array to store the results in. If not given, a new empty array is created. + * + * @return {array} An array of the Game Objects that were hit during this hit test. + */ + hitTest: function (pointer, gameObjects, camera, output) + { + if (output === undefined) { output = this._tempHitTest; } + + var tempPoint = this._tempPoint; + + var csx = camera.scrollX; + var csy = camera.scrollY; + + output.length = 0; + + var x = pointer.x; + var y = pointer.y; + + // Stores the world point inside of tempPoint + camera.getWorldPoint(x, y, tempPoint); + + pointer.worldX = tempPoint.x; + pointer.worldY = tempPoint.y; + + var point = { x: 0, y: 0 }; + + var matrix = this._tempMatrix; + var parentMatrix = this._tempMatrix2; + + for (var i = 0; i < gameObjects.length; i++) + { + var gameObject = gameObjects[i]; + + // Checks if the Game Object can receive input (isn't being ignored by the camera, invisible, etc) + // and also checks all of its parents, if any + if (!this.inputCandidate(gameObject, camera)) + { + continue; + } + + var px = tempPoint.x + (csx * gameObject.scrollFactorX) - csx; + var py = tempPoint.y + (csy * gameObject.scrollFactorY) - csy; + + if (gameObject.parentContainer) + { + gameObject.getWorldTransformMatrix(matrix, parentMatrix); + + matrix.applyInverse(px, py, point); + } + else + { + TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); + } + + if (this.pointWithinHitArea(gameObject, point.x, point.y)) + { + output.push(gameObject); + } + } + + return output; + }, + + /** + * Checks if the given x and y coordinate are within the hit area of the Game Object. + * + * This method assumes that the coordinate values have already been translated into the space of the Game Object. + * + * If the coordinates are within the hit area they are set into the Game Objects Input `localX` and `localY` properties. + * + * @method Phaser.Input.InputManager#pointWithinHitArea + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object to check against. + * @param {number} x - The translated x coordinate for the hit test. + * @param {number} y - The translated y coordinate for the hit test. + * + * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. + */ + pointWithinHitArea: function (gameObject, x, y) + { + // Normalize the origin + x += gameObject.displayOriginX; + y += gameObject.displayOriginY; + + var input = gameObject.input; + + if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) + { + input.localX = x; + input.localY = y; + + return true; + } + else + { + return false; + } + }, + + /** + * Checks if the given x and y coordinate are within the hit area of the Interactive Object. + * + * This method assumes that the coordinate values have already been translated into the space of the Interactive Object. + * + * If the coordinates are within the hit area they are set into the Interactive Objects Input `localX` and `localY` properties. + * + * @method Phaser.Input.InputManager#pointWithinInteractiveObject + * @since 3.0.0 + * + * @param {Phaser.Types.Input.InteractiveObject} object - The Interactive Object to check against. + * @param {number} x - The translated x coordinate for the hit test. + * @param {number} y - The translated y coordinate for the hit test. + * + * @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`. + */ + pointWithinInteractiveObject: function (object, x, y) + { + if (!object.hitArea) + { + return false; + } + + // Normalize the origin + x += object.gameObject.displayOriginX; + y += object.gameObject.displayOriginY; + + object.localX = x; + object.localY = y; + + return object.hitAreaCallback(object.hitArea, x, y, object); + }, + + /** + * Transforms the pageX and pageY values of a Pointer into the scaled coordinate space of the Input Manager. + * + * @method Phaser.Input.InputManager#transformPointer + * @since 3.10.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to transform the values for. + * @param {number} pageX - The Page X value. + * @param {number} pageY - The Page Y value. + * @param {boolean} wasMove - Are we transforming the Pointer from a move event, or an up / down event? + */ + transformPointer: function (pointer, pageX, pageY, wasMove) + { + var p0 = pointer.position; + var p1 = pointer.prevPosition; + + // Store previous position + p1.x = p0.x; + p1.y = p0.y; + + // Translate coordinates + var x = this.scaleManager.transformX(pageX); + var y = this.scaleManager.transformY(pageY); + + var a = pointer.smoothFactor; + + if (!wasMove || a === 0) + { + // Set immediately + p0.x = x; + p0.y = y; + } + else + { + // Apply smoothing + p0.x = x * a + p1.x * (1 - a); + p0.y = y * a + p1.y * (1 - a); + } + }, + + /** + * Destroys the Input Manager and all of its systems. + * + * There is no way to recover from doing this. + * + * @method Phaser.Input.InputManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.events.removeAllListeners(); + + this.game.events.off(GameEvents.PRE_RENDER); + + if (this.keyboard) + { + this.keyboard.destroy(); + } + + if (this.mouse) + { + this.mouse.destroy(); + } + + if (this.touch) + { + this.touch.destroy(); + } + + for (var i = 0; i < this.pointers.length; i++) + { + this.pointers[i].destroy(); + } + + this.pointers = []; + this._tempHitTest = []; + this._tempMatrix.destroy(); + this.canvas = null; + this.game = null; + } + +}); + +module.exports = InputManager; + + +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArrayRemove = __webpack_require__(89); +var Class = __webpack_require__(0); +var GameEvents = __webpack_require__(22); +var InputEvents = __webpack_require__(49); +var KeyCodes = __webpack_require__(141); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * The Keyboard Manager is a helper class that belongs to the global Input Manager. + * + * Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically if keyboard + * input has been enabled in the Game Config. + * + * @class KeyboardManager + * @memberof Phaser.Input.Keyboard + * @constructor + * @since 3.16.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var KeyboardManager = new Class({ + + initialize: + + function KeyboardManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Keyboard.KeyboardManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.16.0 + */ + this.manager = inputManager; + + /** + * An internal event queue. + * + * @name Phaser.Input.Keyboard.KeyboardManager#queue + * @type {KeyboardEvent[]} + * @private + * @since 3.16.0 + */ + this.queue = []; + + /** + * A flag that controls if the non-modified keys, matching those stored in the `captures` array, + * have `preventDefault` called on them or not. + * + * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are + * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). + * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. + * However, if the user presses just the r key on its own, it will have its event prevented. + * + * If you wish to stop capturing the keys, for example switching out to a DOM based element, then + * you can toggle this property at run-time. + * + * @name Phaser.Input.Keyboard.KeyboardManager#preventDefault + * @type {boolean} + * @since 3.16.0 + */ + this.preventDefault = true; + + /** + * An array of Key Code values that will automatically have `preventDefault` called on them, + * as long as the `KeyboardManager.preventDefault` boolean is set to `true`. + * + * By default the array is empty. + * + * The key must be non-modified when pressed in order to be captured. + * + * A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are + * shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows). + * Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier. + * However, if the user presses just the r key on its own, it will have its event prevented. + * + * If you wish to stop capturing the keys, for example switching out to a DOM based element, then + * you can toggle the `KeyboardManager.preventDefault` boolean at run-time. + * + * If you need more specific control, you can create Key objects and set the flag on each of those instead. + * + * This array can be populated via the Game Config by setting the `input.keyboard.capture` array, or you + * can call the `addCapture` method. See also `removeCapture` and `clearCaptures`. + * + * @name Phaser.Input.Keyboard.KeyboardManager#captures + * @type {number[]} + * @since 3.16.0 + */ + this.captures = []; + + /** + * A boolean that controls if the Keyboard Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Keyboard.KeyboardManager#enabled + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.enabled = false; + + /** + * The Keyboard Event target, as defined in the Game Config. + * Typically the window in which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Keyboard.KeyboardManager#target + * @type {any} + * @since 3.16.0 + */ + this.target; + + /** + * The Key Down Event handler. + * This function is sent the native DOM KeyEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Keyboard.KeyboardManager#onKeyDown + * @type {function} + * @since 3.16.00 + */ + this.onKeyDown = NOOP; + + /** + * The Key Up Event handler. + * This function is sent the native DOM KeyEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp + * @type {function} + * @since 3.16.00 + */ + this.onKeyUp = NOOP; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Keyboard Manager boot process. + * + * @method Phaser.Input.Keyboard.KeyboardManager#boot + * @private + * @since 3.16.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputKeyboard; + this.target = config.inputKeyboardEventTarget; + + this.addCapture(config.inputKeyboardCapture); + + if (!this.target && window) + { + this.target = window; + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + + this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, this); + }, + + /** + * Starts the Keyboard Event listeners running. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Keyboard.KeyboardManager#startListeners + * @since 3.16.0 + */ + startListeners: function () + { + var _this = this; + + this.onKeyDown = function (event) + { + if (event.defaultPrevented || !_this.enabled || !_this.manager) + { + // Do nothing if event already handled + return; + } + + _this.queue.push(event); + + _this.manager.events.emit(InputEvents.MANAGER_PROCESS); + + var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); + + if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) + { + event.preventDefault(); + } + }; + + this.onKeyUp = function (event) + { + if (event.defaultPrevented || !_this.enabled || !_this.manager) + { + // Do nothing if event already handled + return; + } + + _this.queue.push(event); + + _this.manager.events.emit(InputEvents.MANAGER_PROCESS); + + var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); + + if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) + { + event.preventDefault(); + } + }; + + var target = this.target; + + if (target) + { + target.addEventListener('keydown', this.onKeyDown, false); + target.addEventListener('keyup', this.onKeyUp, false); + + this.enabled = true; + } + }, + + /** + * Stops the Key Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Keyboard.KeyboardManager#stopListeners + * @since 3.16.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('keydown', this.onKeyDown, false); + target.removeEventListener('keyup', this.onKeyUp, false); + + this.enabled = false; + }, + + /** + * Clears the event queue. + * Called automatically by the Input Manager. + * + * @method Phaser.Input.Keyboard.KeyboardManager#postUpdate + * @private + * @since 3.16.0 + */ + postUpdate: function () + { + this.queue = []; + }, + + /** + * By default when a key is pressed Phaser will not stop the event from propagating up to the browser. + * There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll. + * + * This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser + * and cause the default browser behavior. + * + * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent + * the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one. + * + * You can pass in a single key code value, or an array of key codes, or a string: + * + * ```javascript + * this.input.keyboard.addCapture(62); + * ``` + * + * An array of key codes: + * + * ```javascript + * this.input.keyboard.addCapture([ 62, 63, 64 ]); + * ``` + * + * Or a string: + * + * ```javascript + * this.input.keyboard.addCapture('W,S,A,D'); + * ``` + * + * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * + * You can also provide an array mixing both strings and key code integers. + * + * If there are active captures after calling this method, the `preventDefault` property is set to `true`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#addCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser. + */ + addCapture: function (keycode) + { + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } + + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } + + var captures = this.captures; + + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; + + if (typeof code === 'string') + { + code = KeyCodes[code.trim().toUpperCase()]; + } + + if (captures.indexOf(code) === -1) + { + captures.push(code); + } + } + + this.preventDefault = captures.length > 0; + }, + + /** + * Removes an existing key capture. + * + * Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove + * the capture of a key, then it will remove it for any Scene in your game, not just the calling one. + * + * You can pass in a single key code value, or an array of key codes, or a string: + * + * ```javascript + * this.input.keyboard.removeCapture(62); + * ``` + * + * An array of key codes: + * + * ```javascript + * this.input.keyboard.removeCapture([ 62, 63, 64 ]); + * ``` + * + * Or a string: + * + * ```javascript + * this.input.keyboard.removeCapture('W,S,A,D'); + * ``` + * + * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * + * You can also provide an array mixing both strings and key code integers. + * + * If there are no captures left after calling this method, the `preventDefault` property is set to `false`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#removeCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again. + */ + removeCapture: function (keycode) + { + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } + + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } + + var captures = this.captures; + + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; + + if (typeof code === 'string') + { + code = KeyCodes[code.toUpperCase()]; + } + + ArrayRemove(captures, code); + } + + this.preventDefault = captures.length > 0; + }, + + /** + * Removes all keyboard captures and sets the `preventDefault` property to `false`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures + * @since 3.16.0 + */ + clearCaptures: function () + { + this.captures = []; + + this.preventDefault = false; + }, + + /** + * Destroys this Keyboard Manager instance. + * + * @method Phaser.Input.Keyboard.KeyboardManager#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.stopListeners(); + + this.clearCaptures(); + + this.queue = []; + + this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = KeyboardManager; + + +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Features = __webpack_require__(188); +var InputEvents = __webpack_require__(49); +var NOOP = __webpack_require__(1); + +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent +// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md + +/** + * @classdesc + * The Mouse Manager is a helper class that belongs to the Input Manager. + * + * Its role is to listen for native DOM Mouse Events and then pass them onto the Input Manager for further processing. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. + * + * @class MouseManager + * @memberof Phaser.Input.Mouse + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var MouseManager = new Class({ + + initialize: + + function MouseManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Mouse.MouseManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = inputManager; + + /** + * If `true` the DOM `mousedown` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultDown + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultDown = true; + + /** + * If `true` the DOM `mouseup` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultUp + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultUp = true; + + /** + * If `true` the DOM `mousemove` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultMove + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultMove = true; + + /** + * If `true` the DOM `wheel` event will have `preventDefault` set. + * + * @name Phaser.Input.Mouse.MouseManager#preventDefaultWheel + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.preventDefaultWheel = false; + + /** + * A boolean that controls if the Mouse Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Mouse.MouseManager#enabled + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.enabled = false; + + /** + * The Mouse target, as defined in the Game Config. + * Typically the canvas to which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Mouse.MouseManager#target + * @type {any} + * @since 3.0.0 + */ + this.target; + + /** + * If the mouse has been pointer locked successfully this will be set to true. + * + * @name Phaser.Input.Mouse.MouseManager#locked + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.locked = false; + + /** + * The Mouse Move Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseMove + * @type {function} + * @since 3.10.0 + */ + this.onMouseMove = NOOP; + + /** + * The Mouse Down Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseDown + * @type {function} + * @since 3.10.0 + */ + this.onMouseDown = NOOP; + + /** + * The Mouse Up Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseUp + * @type {function} + * @since 3.10.0 + */ + this.onMouseUp = NOOP; + + /** + * The Mouse Down Event handler specifically for events on the Window. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseDownWindow + * @type {function} + * @since 3.17.0 + */ + this.onMouseDownWindow = NOOP; + + /** + * The Mouse Up Event handler specifically for events on the Window. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseUpWindow + * @type {function} + * @since 3.17.0 + */ + this.onMouseUpWindow = NOOP; + + /** + * The Mouse Over Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseOver + * @type {function} + * @since 3.16.0 + */ + this.onMouseOver = NOOP; + + /** + * The Mouse Out Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseOut + * @type {function} + * @since 3.16.0 + */ + this.onMouseOut = NOOP; + + /** + * The Mouse Wheel Event handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#onMouseWheel + * @type {function} + * @since 3.18.0 + */ + this.onMouseWheel = NOOP; + + /** + * Internal pointerLockChange handler. + * This function is sent the native DOM MouseEvent. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Mouse.MouseManager#pointerLockChange + * @type {function} + * @since 3.0.0 + */ + this.pointerLockChange = NOOP; + + /** + * Are the event listeners hooked into `window.top` or `window`? + * + * This is set during the `boot` sequence. If the browser does not have access to `window.top`, + * such as in cross-origin iframe environments, this property gets set to `false` and the events + * are hooked into `window` instead. + * + * @name Phaser.Input.Mouse.MouseManager#isTop + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.isTop = true; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Touch Manager boot process. + * + * @method Phaser.Input.Mouse.MouseManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputMouse; + this.target = config.inputMouseEventTarget; + this.passive = config.inputMousePassive; + + this.preventDefaultDown = config.inputMousePreventDefaultDown; + this.preventDefaultUp = config.inputMousePreventDefaultUp; + this.preventDefaultMove = config.inputMousePreventDefaultMove; + this.preventDefaultWheel = config.inputMousePreventDefaultWheel; + + if (!this.target) + { + this.target = this.manager.game.canvas; + } + else if (typeof this.target === 'string') + { + this.target = document.getElementById(this.target); + } + + if (config.disableContextMenu) + { + this.disableContextMenu(); + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + }, + + /** + * Attempts to disable the context menu from appearing if you right-click on the browser. + * + * Works by listening for the `contextmenu` event and prevent defaulting it. + * + * Use this if you need to enable right-button mouse support in your game, and the browser + * menu keeps getting in the way. + * + * @method Phaser.Input.Mouse.MouseManager#disableContextMenu + * @since 3.0.0 + * + * @return {this} This Mouse Manager instance. + */ + disableContextMenu: function () + { + document.body.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return false; + }); + + return this; + }, + + /** + * If the browser supports it, you can request that the pointer be locked to the browser window. + * + * This is classically known as 'FPS controls', where the pointer can't leave the browser until + * the user presses an exit key. + * + * If the browser successfully enters a locked state, a `POINTER_LOCK_CHANGE_EVENT` will be dispatched, + * from the games Input Manager, with an `isPointerLocked` property. + * + * It is important to note that pointer lock can only be enabled after an 'engagement gesture', + * see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture. + * + * Note for Firefox: There is a bug in certain Firefox releases that cause native DOM events like + * `mousemove` to fire continuously when in pointer lock mode. You can get around this by setting + * `this.preventDefaultMove` to `false` in this class. You may also need to do the same for + * `preventDefaultDown` and/or `preventDefaultUp`. Please test combinations of these if you encounter + * the error. + * + * @method Phaser.Input.Mouse.MouseManager#requestPointerLock + * @since 3.0.0 + */ + requestPointerLock: function () + { + if (Features.pointerLock) + { + var element = this.target; + + element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; + + element.requestPointerLock(); + } + }, + + /** + * If the browser supports pointer lock, this will request that the pointer lock is released. If + * the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be + * dispatched - from the game's input manager - with an `isPointerLocked` property. + * + * @method Phaser.Input.Mouse.MouseManager#releasePointerLock + * @since 3.0.0 + */ + releasePointerLock: function () + { + if (Features.pointerLock) + { + document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; + document.exitPointerLock(); + } + }, + + /** + * Starts the Mouse Event listeners running. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Mouse.MouseManager#startListeners + * @since 3.0.0 + */ + startListeners: function () + { + var target = this.target; + + if (!target) + { + return; + } + + var _this = this; + var manager = this.manager; + var canvas = manager.canvas; + var autoFocus = (window && window.focus && manager.game.config.autoFocus); + + this.onMouseMove = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseMove(event); + + if (_this.preventDefaultMove) + { + event.preventDefault(); + } + } + }; + + this.onMouseDown = function (event) + { + if (autoFocus) + { + window.focus(); + } + + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseDown(event); + + if (_this.preventDefaultDown && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onMouseDownWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + manager.onMouseDown(event); + } + }; + + this.onMouseUp = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseUp(event); + + if (_this.preventDefaultUp && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onMouseUpWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + manager.onMouseUp(event); + } + }; + + this.onMouseOver = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOver(event); + } + }; + + this.onMouseOut = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOut(event); + } + }; + + this.onMouseWheel = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseWheel(event); + } + + if (_this.preventDefaultWheel && event.target === canvas) + { + event.preventDefault(); + } + }; + + var passive = { passive: true }; + + target.addEventListener('mousemove', this.onMouseMove); + target.addEventListener('mousedown', this.onMouseDown); + target.addEventListener('mouseup', this.onMouseUp); + target.addEventListener('mouseover', this.onMouseOver, passive); + target.addEventListener('mouseout', this.onMouseOut, passive); + + if (this.preventDefaultWheel) + { + target.addEventListener('wheel', this.onMouseWheel, { passive: false }); + } + else + { + target.addEventListener('wheel', this.onMouseWheel, passive); + } + + if (window && manager.game.config.inputWindowEvents) + { + try + { + window.top.addEventListener('mousedown', this.onMouseDownWindow, passive); + window.top.addEventListener('mouseup', this.onMouseUpWindow, passive); + } + catch (exception) + { + window.addEventListener('mousedown', this.onMouseDownWindow, passive); + window.addEventListener('mouseup', this.onMouseUpWindow, passive); + + this.isTop = false; + } + } + + if (Features.pointerLock) + { + this.pointerLockChange = function (event) + { + var element = _this.target; + + _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; + + manager.onPointerLockChange(event); + }; + + document.addEventListener('pointerlockchange', this.pointerLockChange, true); + document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } + + this.enabled = true; + }, + + /** + * Stops the Mouse Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Mouse.MouseManager#stopListeners + * @since 3.0.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('mousemove', this.onMouseMove); + target.removeEventListener('mousedown', this.onMouseDown); + target.removeEventListener('mouseup', this.onMouseUp); + target.removeEventListener('mouseover', this.onMouseOver); + target.removeEventListener('mouseout', this.onMouseOut); + + if (window) + { + target = (this.isTop) ? window.top : window; + + target.removeEventListener('mousedown', this.onMouseDownWindow); + target.removeEventListener('mouseup', this.onMouseUpWindow); + } + + if (Features.pointerLock) + { + document.removeEventListener('pointerlockchange', this.pointerLockChange, true); + document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } + }, + + /** + * Destroys this Mouse Manager instance. + * + * @method Phaser.Input.Mouse.MouseManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stopListeners(); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = MouseManager; + + +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Angle = __webpack_require__(343); +var Class = __webpack_require__(0); +var Distance = __webpack_require__(48); +var FuzzyEqual = __webpack_require__(123); +var SmoothStepInterpolation = __webpack_require__(354); +var Vector2 = __webpack_require__(3); +var OS = __webpack_require__(102); + +/** + * @classdesc + * A Pointer object encapsulates both mouse and touch input within Phaser. + * + * By default, Phaser will create 2 pointers for your game to use. If you require more, i.e. for a multi-touch + * game, then use the `InputPlugin.addPointer` method to do so, rather than instantiating this class directly, + * otherwise it won't be managed by the input system. + * + * You can reference the current active pointer via `InputPlugin.activePointer`. You can also use the properties + * `InputPlugin.pointer1` through to `pointer10`, for each pointer you have enabled in your game. + * + * The properties of this object are set by the Input Plugin during processing. This object is then sent in all + * input related events that the Input Plugin emits, so you can reference properties from it directly in your + * callbacks. + * + * @class Pointer + * @memberof Phaser.Input + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} manager - A reference to the Input Manager. + * @param {number} id - The internal ID of this Pointer. + */ +var Pointer = new Class({ + + initialize: + + function Pointer (manager, id) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Pointer#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * The internal ID of this Pointer. + * + * @name Phaser.Input.Pointer#id + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.id = id; + + /** + * The most recent native DOM Event this Pointer has processed. + * + * @name Phaser.Input.Pointer#event + * @type {(TouchEvent|MouseEvent)} + * @since 3.0.0 + */ + this.event; + + /** + * The DOM element the Pointer was pressed down on, taken from the DOM event. + * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. + * + * @name Phaser.Input.Pointer#downElement + * @type {any} + * @readonly + * @since 3.16.0 + */ + this.downElement; + + /** + * The DOM element the Pointer was released on, taken from the DOM event. + * In a default set-up this will be the Canvas that Phaser is rendering to, or the Window element. + * + * @name Phaser.Input.Pointer#upElement + * @type {any} + * @readonly + * @since 3.16.0 + */ + this.upElement; + + /** + * The camera the Pointer interacted with during its last update. + * + * A Pointer can only ever interact with one camera at once, which will be the top-most camera + * in the list should multiple cameras be positioned on-top of each other. + * + * @name Phaser.Input.Pointer#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @default null + * @since 3.0.0 + */ + this.camera = null; + + /** + * A read-only property that indicates which button was pressed, or released, on the pointer + * during the most recent event. It is only set during `up` and `down` events. + * + * On Touch devices the value is always 0. + * + * Users may change the configuration of buttons on their pointing device so that if an event's button property + * is zero, it may not have been caused by the button that is physically left–most on the pointing device; + * however, it should behave as if the left button was clicked in the standard button layout. + * + * @name Phaser.Input.Pointer#button + * @type {number} + * @readonly + * @default 0 + * @since 3.18.0 + */ + this.button = 0; + + /** + * 0: No button or un-initialized + * 1: Left button + * 2: Right button + * 4: Wheel button or middle button + * 8: 4th button (typically the "Browser Back" button) + * 16: 5th button (typically the "Browser Forward" button) + * + * For a mouse configured for left-handed use, the button actions are reversed. + * In this case, the values are read from right to left. + * + * @name Phaser.Input.Pointer#buttons + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.buttons = 0; + + /** + * The position of the Pointer in screen space. + * + * @name Phaser.Input.Pointer#position + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.position = new Vector2(); + + /** + * The previous position of the Pointer in screen space. + * + * The old x and y values are stored in here during the InputManager.transformPointer call. + * + * Use the properties `velocity`, `angle` and `distance` to create your own gesture recognition. + * + * @name Phaser.Input.Pointer#prevPosition + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.11.0 + */ + this.prevPosition = new Vector2(); + + /** + * An internal vector used for calculations of the pointer speed and angle. + * + * @name Phaser.Input.Pointer#midPoint + * @type {Phaser.Math.Vector2} + * @private + * @since 3.16.0 + */ + this.midPoint = new Vector2(-1, -1); + + /** + * The current velocity of the Pointer, based on its current and previous positions. + * + * This value is smoothed out each frame, according to the `motionFactor` property. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * @name Phaser.Input.Pointer#velocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.16.0 + */ + this.velocity = new Vector2(); + + /** + * The current angle the Pointer is moving, in radians, based on its previous and current position. + * + * The angle is based on the old position facing to the current position. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * @name Phaser.Input.Pointer#angle + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.angle = 0; + + /** + * The distance the Pointer has moved, based on its previous and current position. + * + * This value is smoothed out each frame, according to the `motionFactor` property. + * + * This property is updated whenever the Pointer moves, regardless of any button states. In other words, + * it changes based on movement alone - a button doesn't have to be pressed first. + * + * If you need the total distance travelled since the primary buttons was pressed down, + * then use the `Pointer.getDistance` method. + * + * @name Phaser.Input.Pointer#distance + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.distance = 0; + + /** + * The smoothing factor to apply to the Pointer position. + * + * Due to their nature, pointer positions are inherently noisy. While this is fine for lots of games, if you need cleaner positions + * then you can set this value to apply an automatic smoothing to the positions as they are recorded. + * + * The default value of zero means 'no smoothing'. + * Set to a small value, such as 0.2, to apply an average level of smoothing between positions. You can do this by changing this + * value directly, or by setting the `input.smoothFactor` property in the Game Config. + * + * Positions are only smoothed when the pointer moves. If the primary button on this Pointer enters an Up or Down state, then the position + * is always precise, and not smoothed. + * + * @name Phaser.Input.Pointer#smoothFactor + * @type {number} + * @default 0 + * @since 3.16.0 + */ + this.smoothFactor = 0; + + /** + * The factor applied to the motion smoothing each frame. + * + * This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, + * angle and distance of the Pointer. It's applied every frame, until the midPoint reaches the current + * position of the Pointer. 0.2 provides a good average but can be increased if you need a + * quicker update and are working in a high performance environment. Never set this value to + * zero. + * + * @name Phaser.Input.Pointer#motionFactor + * @type {number} + * @default 0.2 + * @since 3.16.0 + */ + this.motionFactor = 0.2; + + /** + * The x position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. + * + * If you wish to use this value _outside_ of an input event handler then you should update it first by calling + * the `Pointer.updateWorldPoint` method. + * + * @name Phaser.Input.Pointer#worldX + * @type {number} + * @default 0 + * @since 3.10.0 + */ + this.worldX = 0; + + /** + * The y position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. + * + * If you wish to use this value _outside_ of an input event handler then you should update it first by calling + * the `Pointer.updateWorldPoint` method. + * + * @name Phaser.Input.Pointer#worldY + * @type {number} + * @default 0 + * @since 3.10.0 + */ + this.worldY = 0; + + /** + * Time when this Pointer was most recently moved (regardless of the state of its buttons, if any) + * + * @name Phaser.Input.Pointer#moveTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.moveTime = 0; + + /** + * X coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. + * + * @name Phaser.Input.Pointer#downX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downX = 0; + + /** + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. + * + * @name Phaser.Input.Pointer#downY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downY = 0; + + /** + * The Event timestamp when the first button, or Touch input, was pressed. Used for dragging objects. + * + * @name Phaser.Input.Pointer#downTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.downTime = 0; + + /** + * X coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. + * + * @name Phaser.Input.Pointer#upX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upX = 0; + + /** + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. + * + * @name Phaser.Input.Pointer#upY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upY = 0; + + /** + * The Event timestamp when the final button, or Touch input, was released. Used for dragging objects. + * + * @name Phaser.Input.Pointer#upTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.upTime = 0; + + /** + * Is the primary button down? (usually button 0, the left mouse button) + * + * @name Phaser.Input.Pointer#primaryDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.primaryDown = false; + + /** + * Is _any_ button on this pointer considered as being down? + * + * @name Phaser.Input.Pointer#isDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isDown = false; + + /** + * Did the previous input event come from a Touch input (true) or Mouse? (false) + * + * @name Phaser.Input.Pointer#wasTouch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.wasTouch = false; + + /** + * Did this Pointer get canceled by a touchcancel event? + * + * Note: "canceled" is the American-English spelling of "cancelled". Please don't submit PRs correcting it! + * + * @name Phaser.Input.Pointer#wasCanceled + * @type {boolean} + * @default false + * @since 3.15.0 + */ + this.wasCanceled = false; + + /** + * If the mouse is locked, the horizontal relative movement of the Pointer in pixels since last frame. + * + * @name Phaser.Input.Pointer#movementX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.movementX = 0; + + /** + * If the mouse is locked, the vertical relative movement of the Pointer in pixels since last frame. + * + * @name Phaser.Input.Pointer#movementY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.movementY = 0; + + /** + * The identifier property of the Pointer as set by the DOM event when this Pointer is started. + * + * @name Phaser.Input.Pointer#identifier + * @type {number} + * @since 3.10.0 + */ + this.identifier = 0; + + /** + * The pointerId property of the Pointer as set by the DOM event when this Pointer is started. + * The browser can and will recycle this value. + * + * @name Phaser.Input.Pointer#pointerId + * @type {number} + * @since 3.10.0 + */ + this.pointerId = null; + + /** + * An active Pointer is one that is currently pressed down on the display. + * A Mouse is always considered as active. + * + * @name Phaser.Input.Pointer#active + * @type {boolean} + * @since 3.10.0 + */ + this.active = (id === 0) ? true : false; + + /** + * Is this pointer Pointer Locked? + * + * Only a mouse pointer can be locked and it only becomes locked when requested via + * the browsers Pointer Lock API. + * + * You can request this by calling the `this.input.mouse.requestPointerLock()` method from + * a `pointerdown` or `pointerup` event handler. + * + * @name Phaser.Input.Pointer#locked + * @readonly + * @type {boolean} + * @since 3.19.0 + */ + this.locked = false; + + /** + * The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * + * @name Phaser.Input.Pointer#deltaX + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaX = 0; + + /** + * The vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * This value will typically be less than 0 if the user scrolls up and greater than zero if scrolling down. + * + * @name Phaser.Input.Pointer#deltaY + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaY = 0; + + /** + * The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * + * @name Phaser.Input.Pointer#deltaZ + * @type {number} + * @default 0 + * @since 3.18.0 + */ + this.deltaZ = 0; + }, + + /** + * Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are + * the result of a translation through the given Camera. + * + * Note that the values will be automatically replaced the moment the Pointer is + * updated by an input event, such as a mouse move, so should be used immediately. + * + * @method Phaser.Input.Pointer#updateWorldPoint + * @since 3.19.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * + * @return {this} This Pointer object. + */ + updateWorldPoint: function (camera) + { + // Stores the world point inside of tempPoint + var temp = camera.getWorldPoint(this.x, this.y); + + this.worldX = temp.x; + this.worldY = temp.y; + + return this; + }, + + /** + * Takes a Camera and returns a Vector2 containing the translated position of this Pointer + * within that Camera. This can be used to convert this Pointers position into camera space. + * + * @method Phaser.Input.Pointer#positionToCamera + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the translation. + * @param {(Phaser.Math.Vector2|object)} [output] - A Vector2-like object in which to store the translated position. + * + * @return {(Phaser.Math.Vector2|object)} A Vector2 containing the translated coordinates of this Pointer, based on the given camera. + */ + positionToCamera: function (camera, output) + { + return camera.getWorldPoint(this.x, this.y, output); + }, + + /** + * Calculates the motion of this Pointer, including its velocity and angle of movement. + * This method is called automatically each frame by the Input Manager. + * + * @method Phaser.Input.Pointer#updateMotion + * @private + * @since 3.16.0 + */ + updateMotion: function () + { + var cx = this.position.x; + var cy = this.position.y; + + var mx = this.midPoint.x; + var my = this.midPoint.y; + + if (cx === mx && cy === my) + { + // Nothing to do here + return; + } + + // Moving towards our goal ... + var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); + var vy = SmoothStepInterpolation(this.motionFactor, my, cy); + + if (FuzzyEqual(vx, cx, 0.1)) + { + vx = cx; + } + + if (FuzzyEqual(vy, cy, 0.1)) + { + vy = cy; + } + + this.midPoint.set(vx, vy); + + var dx = cx - vx; + var dy = cy - vy; + + this.velocity.set(dx, dy); + + this.angle = Angle(vx, vy, cx, cy); + + this.distance = Math.sqrt(dx * dx + dy * dy); + }, + + /** + * Internal method to handle a Mouse Up Event. + * + * @method Phaser.Input.Pointer#up + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + up: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + this.button = event.button; + + this.upElement = event.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + // 0: Main button pressed, usually the left button or the un-initialized state + if (event.button === 0) + { + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + } + + if (this.buttons === 0) + { + // No more buttons are still down + this.isDown = false; + + this.upTime = event.timeStamp; + + this.wasTouch = false; + } + }, + + /** + * Internal method to handle a Mouse Down Event. + * + * @method Phaser.Input.Pointer#down + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + down: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + this.button = event.button; + + this.downElement = event.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + // 0: Main button pressed, usually the left button or the un-initialized state + if (event.button === 0) + { + this.primaryDown = true; + this.downX = this.x; + this.downY = this.y; + } + + if (OS.macOS && event.ctrlKey) + { + // Override button settings on macOS + this.buttons = 2; + this.primaryDown = false; + } + + if (!this.isDown) + { + this.isDown = true; + + this.downTime = event.timeStamp; + } + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Mouse Move Event. + * + * @method Phaser.Input.Pointer#move + * @private + * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. + */ + move: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, true); + + if (this.locked) + { + // Multiple DOM events may occur within one frame, but only one Phaser event will fire + this.movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; + this.movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; + } + + this.moveTime = event.timeStamp; + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Mouse Wheel Event. + * + * @method Phaser.Input.Pointer#wheel + * @private + * @since 3.18.0 + * + * @param {WheelEvent} event - The Wheel Event to process. + */ + wheel: function (event) + { + if ('buttons' in event) + { + this.buttons = event.buttons; + } + + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); + + this.deltaX = event.deltaX; + this.deltaY = event.deltaY; + this.deltaZ = event.deltaZ; + + this.wasTouch = false; + }, + + /** + * Internal method to handle a Touch Start Event. + * + * @method Phaser.Input.Pointer#touchstart + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchstart: function (touch, event) + { + if (touch['pointerId']) + { + this.pointerId = touch.pointerId; + } + + this.identifier = touch.identifier; + this.target = touch.target; + this.active = true; + + this.buttons = 1; + + this.event = event; + + this.downElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = true; + this.downX = this.x; + this.downY = this.y; + this.downTime = event.timeStamp; + + this.isDown = true; + + this.wasTouch = true; + this.wasCanceled = false; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch Move Event. + * + * @method Phaser.Input.Pointer#touchmove + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchmove: function (touch, event) + { + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, true); + + this.moveTime = event.timeStamp; + + this.wasTouch = true; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch End Event. + * + * @method Phaser.Input.Pointer#touchend + * @private + * @since 3.0.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchend: function (touch, event) + { + this.buttons = 0; + + this.event = event; + + this.upElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; + + this.isDown = false; + + this.wasTouch = true; + this.wasCanceled = false; + + this.active = false; + + this.updateMotion(); + }, + + /** + * Internal method to handle a Touch Cancel Event. + * + * @method Phaser.Input.Pointer#touchcancel + * @private + * @since 3.15.0 + * + * @param {Touch} touch - The Changed Touch from the Touch Event. + * @param {TouchEvent} event - The full Touch Event. + */ + touchcancel: function (touch, event) + { + this.buttons = 0; + + this.event = event; + + this.upElement = touch.target; + + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); + + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; + + this.isDown = false; + + this.wasTouch = true; + this.wasCanceled = true; + + this.active = false; + }, + + /** + * Checks to see if any buttons are being held down on this Pointer. + * + * @method Phaser.Input.Pointer#noButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if no buttons are being held down. + */ + noButtonDown: function () + { + return (this.buttons === 0); + }, + + /** + * Checks to see if the left button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#leftButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the left button is being held down. + */ + leftButtonDown: function () + { + return (this.buttons & 1) ? true : false; + }, + + /** + * Checks to see if the right button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#rightButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the right button is being held down. + */ + rightButtonDown: function () + { + return (this.buttons & 2) ? true : false; + }, + + /** + * Checks to see if the middle button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#middleButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the middle button is being held down. + */ + middleButtonDown: function () + { + return (this.buttons & 4) ? true : false; + }, + + /** + * Checks to see if the back button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#backButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the back button is being held down. + */ + backButtonDown: function () + { + return (this.buttons & 8) ? true : false; + }, + + /** + * Checks to see if the forward button is being held down on this Pointer. + * + * @method Phaser.Input.Pointer#forwardButtonDown + * @since 3.0.0 + * + * @return {boolean} `true` if the forward button is being held down. + */ + forwardButtonDown: function () + { + return (this.buttons & 16) ? true : false; + }, + + /** + * Checks to see if the left button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#leftButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the left button was just released. + */ + leftButtonReleased: function () + { + return (this.button === 0 && !this.isDown); + }, + + /** + * Checks to see if the right button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#rightButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the right button was just released. + */ + rightButtonReleased: function () + { + return (this.button === 2 && !this.isDown); + }, + + /** + * Checks to see if the middle button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#middleButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the middle button was just released. + */ + middleButtonReleased: function () + { + return (this.button === 1 && !this.isDown); + }, + + /** + * Checks to see if the back button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#backButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the back button was just released. + */ + backButtonReleased: function () + { + return (this.button === 3 && !this.isDown); + }, + + /** + * Checks to see if the forward button was just released on this Pointer. + * + * @method Phaser.Input.Pointer#forwardButtonReleased + * @since 3.18.0 + * + * @return {boolean} `true` if the forward button was just released. + */ + forwardButtonReleased: function () + { + return (this.button === 4 && !this.isDown); + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded distance, based on where + * the Pointer was when the button was released. + * + * If you wish to get the distance being travelled currently, based on the velocity of the Pointer, + * then see the `Pointer.distance` property. + * + * @method Phaser.Input.Pointer#getDistance + * @since 3.13.0 + * + * @return {number} The distance the Pointer moved. + */ + getDistance: function () + { + if (this.isDown) + { + return Distance(this.downX, this.downY, this.x, this.y); + } + else + { + return Distance(this.downX, this.downY, this.upX, this.upY); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * horizontal distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded horizontal distance, based on where + * the Pointer was when the button was released. + * + * @method Phaser.Input.Pointer#getDistanceX + * @since 3.16.0 + * + * @return {number} The horizontal distance the Pointer moved. + */ + getDistanceX: function () + { + if (this.isDown) + { + return Math.abs(this.downX - this.x); + } + else + { + return Math.abs(this.downX - this.upX); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * vertical distance between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded vertical distance, based on where + * the Pointer was when the button was released. + * + * @method Phaser.Input.Pointer#getDistanceY + * @since 3.16.0 + * + * @return {number} The vertical distance the Pointer moved. + */ + getDistanceY: function () + { + if (this.isDown) + { + return Math.abs(this.downY - this.y); + } + else + { + return Math.abs(this.downY - this.upY); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * duration since the button was pressed down. + * + * If no button is held down, it will return the last recorded duration, based on the time + * the last button on the Pointer was released. + * + * @method Phaser.Input.Pointer#getDuration + * @since 3.16.0 + * + * @return {number} The duration the Pointer was held down for in milliseconds. + */ + getDuration: function () + { + if (this.isDown) + { + return (this.manager.time - this.downTime); + } + else + { + return (this.upTime - this.downTime); + } + }, + + /** + * If the Pointer has a button pressed down at the time this method is called, it will return the + * angle between the Pointer's `downX` and `downY` values and the current position. + * + * If no button is held down, it will return the last recorded angle, based on where + * the Pointer was when the button was released. + * + * The angle is based on the old position facing to the current position. + * + * If you wish to get the current angle, based on the velocity of the Pointer, then + * see the `Pointer.angle` property. + * + * @method Phaser.Input.Pointer#getAngle + * @since 3.16.0 + * + * @return {number} The angle between the Pointer's coordinates in radians. + */ + getAngle: function () + { + if (this.isDown) + { + return Angle(this.downX, this.downY, this.x, this.y); + } + else + { + return Angle(this.downX, this.downY, this.upX, this.upY); + } + }, + + /** + * Takes the previous and current Pointer positions and then generates an array of interpolated values between + * the two. The array will be populated up to the size of the `steps` argument. + * + * ```javaScript + * var points = pointer.getInterpolatedPosition(4); + * + * // points[0] = { x: 0, y: 0 } + * // points[1] = { x: 2, y: 1 } + * // points[2] = { x: 3, y: 2 } + * // points[3] = { x: 6, y: 3 } + * ``` + * + * Use this if you need to get smoothed values between the previous and current pointer positions. DOM pointer + * events can often fire faster than the main browser loop, and this will help you avoid janky movement + * especially if you have an object following a Pointer. + * + * Note that if you provide an output array it will only be populated up to the number of steps provided. + * It will not clear any previous data that may have existed beyond the range of the steps count. + * + * Internally it uses the Smooth Step interpolation calculation. + * + * @method Phaser.Input.Pointer#getInterpolatedPosition + * @since 3.11.0 + * + * @param {number} [steps=10] - The number of interpolation steps to use. + * @param {array} [out] - An array to store the results in. If not provided a new one will be created. + * + * @return {array} An array of interpolated values. + */ + getInterpolatedPosition: function (steps, out) + { + if (steps === undefined) { steps = 10; } + if (out === undefined) { out = []; } + + var prevX = this.prevPosition.x; + var prevY = this.prevPosition.y; + + var curX = this.position.x; + var curY = this.position.y; + + for (var i = 0; i < steps; i++) + { + var t = (1 / steps) * i; + + out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; + } + + return out; + }, + + /** + * Destroys this Pointer instance and resets its external references. + * + * @method Phaser.Input.Pointer#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.camera = null; + this.manager = null; + this.position = null; + }, + + /** + * The x position of this Pointer. + * The value is in screen space. + * See `worldX` to get a camera converted position. + * + * @name Phaser.Input.Pointer#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.position.x = value; + } + + }, + + /** + * The y position of this Pointer. + * The value is in screen space. + * See `worldY` to get a camera converted position. + * + * @name Phaser.Input.Pointer#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.position.y = value; + } + + }, + + /** + * Time when this Pointer was most recently updated by a DOM Event. + * This comes directly from the `event.timeStamp` property. + * If no event has yet taken place, it will return zero. + * + * @name Phaser.Input.Pointer#time + * @type {number} + * @readonly + * @since 3.16.0 + */ + time: { + + get: function () + { + return (this.event) ? this.event.timeStamp : 0; + } + + } + +}); + +module.exports = Pointer; + + +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var InputEvents = __webpack_require__(49); +var NOOP = __webpack_require__(1); + +// https://developer.mozilla.org/en-US/docs/Web/API/Touch_events +// https://patrickhlauke.github.io/touch/tests/results/ +// https://www.html5rocks.com/en/mobile/touch/ + +/** + * @classdesc + * The Touch Manager is a helper class that belongs to the Input Manager. + * + * Its role is to listen for native DOM Touch Events and then pass them onto the Input Manager for further processing. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. + * + * @class TouchManager + * @memberof Phaser.Input.Touch + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + */ +var TouchManager = new Class({ + + initialize: + + function TouchManager (inputManager) + { + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Touch.TouchManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = inputManager; + + /** + * If true the DOM events will have event.preventDefault applied to them, if false they will propagate fully. + * + * @name Phaser.Input.Touch.TouchManager#capture + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.capture = true; + + /** + * A boolean that controls if the Touch Manager is enabled or not. + * Can be toggled on the fly. + * + * @name Phaser.Input.Touch.TouchManager#enabled + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.enabled = false; + + /** + * The Touch Event target, as defined in the Game Config. + * Typically the canvas to which the game is rendering, but can be any interactive DOM element. + * + * @name Phaser.Input.Touch.TouchManager#target + * @type {any} + * @since 3.0.0 + */ + this.target; + + /** + * The Touch Start event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchStart + * @type {function} + * @since 3.0.0 + */ + this.onTouchStart = NOOP; + + /** + * The Touch Start event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchStartWindow + * @type {function} + * @since 3.17.0 + */ + this.onTouchStartWindow = NOOP; + + /** + * The Touch Move event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchMove + * @type {function} + * @since 3.0.0 + */ + this.onTouchMove = NOOP; + + /** + * The Touch End event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchEnd + * @type {function} + * @since 3.0.0 + */ + this.onTouchEnd = NOOP; + + /** + * The Touch End event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchEndWindow + * @type {function} + * @since 3.17.0 + */ + this.onTouchEndWindow = NOOP; + + /** + * The Touch Cancel event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchCancel + * @type {function} + * @since 3.15.0 + */ + this.onTouchCancel = NOOP; + + /** + * The Touch Cancel event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchCancelWindow + * @type {function} + * @since 3.18.0 + */ + this.onTouchCancelWindow = NOOP; + + /** + * The Touch Over event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchOver + * @type {function} + * @since 3.16.0 + */ + this.onTouchOver = NOOP; + + /** + * The Touch Out event handler function. + * Initially empty and bound in the `startListeners` method. + * + * @name Phaser.Input.Touch.TouchManager#onTouchOut + * @type {function} + * @since 3.16.0 + */ + this.onTouchOut = NOOP; + + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, + + /** + * The Touch Manager boot process. + * + * @method Phaser.Input.Touch.TouchManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + var config = this.manager.config; + + this.enabled = config.inputTouch; + this.target = config.inputTouchEventTarget; + this.capture = config.inputTouchCapture; + + if (!this.target) + { + this.target = this.manager.game.canvas; + } + + if (config.disableContextMenu) + { + this.disableContextMenu(); + } + + if (this.enabled && this.target) + { + this.startListeners(); + } + }, + + /** + * Attempts to disable the context menu from appearing if you touch-hold on the browser. + * + * Works by listening for the `contextmenu` event and prevent defaulting it. + * + * Use this if you need to disable the OS context menu on mobile. + * + * @method Phaser.Input.Touch.TouchManager#disableContextMenu + * @since 3.20.0 + * + * @return {this} This Touch Manager instance. + */ + disableContextMenu: function () + { + document.body.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return false; + }); + + return this; + }, + + /** + * Starts the Touch Event listeners running as long as an input target is set. + * + * This method is called automatically if Touch Input is enabled in the game config, + * which it is by default. However, you can call it manually should you need to + * delay input capturing until later in the game. + * + * @method Phaser.Input.Touch.TouchManager#startListeners + * @since 3.0.0 + */ + startListeners: function () + { + var _this = this; + var canvas = this.manager.canvas; + var autoFocus = (window && window.focus && this.manager.game.config.autoFocus); + + this.onTouchStart = function (event) + { + if (autoFocus) + { + window.focus(); + } + + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchStart(event); + + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onTouchStartWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + _this.manager.onTouchStart(event); + } + }; + + this.onTouchMove = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchMove(event); + + if (_this.capture && event.cancelable) + { + event.preventDefault(); + } + } + }; + + this.onTouchEnd = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchEnd(event); + + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onTouchEndWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) + { + // Only process the event if the target isn't the canvas + _this.manager.onTouchEnd(event); + } + }; + + this.onTouchCancel = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchCancel(event); + + if (_this.capture) + { + event.preventDefault(); + } + } + }; + + this.onTouchCancelWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.onTouchCancel(event); + } + }; + + this.onTouchOver = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.setCanvasOver(event); + } + }; + + this.onTouchOut = function (event) + { + if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + { + _this.manager.setCanvasOut(event); + } + }; + + var target = this.target; + + if (!target) + { + return; + } + + var passive = { passive: true }; + var nonPassive = { passive: false }; + + target.addEventListener('touchstart', this.onTouchStart, (this.capture) ? nonPassive : passive); + target.addEventListener('touchmove', this.onTouchMove, (this.capture) ? nonPassive : passive); + target.addEventListener('touchend', this.onTouchEnd, (this.capture) ? nonPassive : passive); + target.addEventListener('touchcancel', this.onTouchCancel, (this.capture) ? nonPassive : passive); + target.addEventListener('touchover', this.onTouchOver, (this.capture) ? nonPassive : passive); + target.addEventListener('touchout', this.onTouchOut, (this.capture) ? nonPassive : passive); + + if (window && this.manager.game.config.inputWindowEvents) + { + window.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); + window.addEventListener('touchend', this.onTouchEndWindow, nonPassive); + window.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); + } + + this.enabled = true; + }, + + /** + * Stops the Touch Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Touch.TouchManager#stopListeners + * @since 3.0.0 + */ + stopListeners: function () + { + var target = this.target; + + target.removeEventListener('touchstart', this.onTouchStart); + target.removeEventListener('touchmove', this.onTouchMove); + target.removeEventListener('touchend', this.onTouchEnd); + target.removeEventListener('touchcancel', this.onTouchCancel); + target.removeEventListener('touchover', this.onTouchOver); + target.removeEventListener('touchout', this.onTouchOut); + + if (window) + { + window.removeEventListener('touchstart', this.onTouchStartWindow); + window.removeEventListener('touchend', this.onTouchEndWindow); + } + }, + + /** + * Destroys this Touch Manager instance. + * + * @method Phaser.Input.Touch.TouchManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.stopListeners(); + + this.target = null; + this.enabled = false; + this.manager = null; + } + +}); + +module.exports = TouchManager; + + +/***/ }), +/* 408 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GameEvents = __webpack_require__(22); +var EventEmitter = __webpack_require__(9); +var FileTypesManager = __webpack_require__(8); +var GameObjectCreator = __webpack_require__(16); +var GameObjectFactory = __webpack_require__(5); +var GetFastValue = __webpack_require__(2); +var PluginCache = __webpack_require__(24); +var Remove = __webpack_require__(89); + +/** + * @classdesc + * The PluginManager is responsible for installing and adding plugins to Phaser. + * + * It is a global system and therefore belongs to the Game instance, not a specific Scene. + * + * It works in conjunction with the PluginCache. Core internal plugins automatically register themselves + * with the Cache, but it's the Plugin Manager that is responsible for injecting them into the Scenes. + * + * There are two types of plugin: + * + * 1. A Global Plugin + * 2. A Scene Plugin + * + * A Global Plugin is a plugin that lives within the Plugin Manager rather than a Scene. You can get + * access to it by calling `PluginManager.get` and providing a key. Any Scene that requests a plugin in + * this way will all get access to the same plugin instance, allowing you to use a single plugin across + * multiple Scenes. + * + * A Scene Plugin is a plugin dedicated to running within a Scene. These are different to Global Plugins + * in that their instances do not live within the Plugin Manager, but within the Scene Systems class instead. + * And that every Scene created is given its own unique instance of a Scene Plugin. Examples of core Scene + * Plugins include the Input Plugin, the Tween Plugin and the physics Plugins. + * + * You can add a plugin to Phaser in three different ways: + * + * 1. Preload it + * 2. Include it in your source code and install it via the Game Config + * 3. Include it in your source code and install it within a Scene + * + * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. + * + * For information on creating your own plugin please see the Phaser 3 Plugin Template. + * + * @class PluginManager + * @memberof Phaser.Plugins + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. + */ +var PluginManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function PluginManager (game) + { + EventEmitter.call(this); + + /** + * The game instance that owns this Plugin Manager. + * + * @name Phaser.Plugins.PluginManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * The global plugins currently running and managed by this Plugin Manager. + * A plugin must have been started at least once in order to appear in this list. + * + * @name Phaser.Plugins.PluginManager#plugins + * @type {Phaser.Types.Plugins.GlobalPlugin[]} + * @since 3.8.0 + */ + this.plugins = []; + + /** + * A list of plugin keys that should be installed into Scenes as well as the Core Plugins. + * + * @name Phaser.Plugins.PluginManager#scenePlugins + * @type {string[]} + * @since 3.8.0 + */ + this.scenePlugins = []; + + /** + * A temporary list of plugins to install when the game has booted. + * + * @name Phaser.Plugins.PluginManager#_pendingGlobal + * @private + * @type {array} + * @since 3.8.0 + */ + this._pendingGlobal = []; + + /** + * A temporary list of scene plugins to install when the game has booted. + * + * @name Phaser.Plugins.PluginManager#_pendingScene + * @private + * @type {array} + * @since 3.8.0 + */ + this._pendingScene = []; + + if (game.isBooted) + { + this.boot(); + } + else + { + game.events.once(GameEvents.BOOT, this.boot, this); + } + }, + + /** + * Run once the game has booted and installs all of the plugins configured in the Game Config. + * + * @method Phaser.Plugins.PluginManager#boot + * @protected + * @since 3.0.0 + */ + boot: function () + { + var i; + var entry; + var key; + var plugin; + var start; + var mapping; + var data; + var config = this.game.config; + + // Any plugins to install? + var list = config.installGlobalPlugins; + + // Any plugins added outside of the game config, but before the game booted? + list = list.concat(this._pendingGlobal); + + for (i = 0; i < list.length; i++) + { + entry = list[i]; + + // { key: 'TestPlugin', plugin: TestPlugin, start: true, mapping: 'test', data: { msg: 'The plugin is alive' } } + + key = GetFastValue(entry, 'key', null); + plugin = GetFastValue(entry, 'plugin', null); + start = GetFastValue(entry, 'start', false); + mapping = GetFastValue(entry, 'mapping', null); + data = GetFastValue(entry, 'data', null); + + if (key) + { + if (plugin) + { + this.install(key, plugin, start, mapping, data); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } + + } + } + + // Any scene plugins to install? + list = config.installScenePlugins; + + // Any plugins added outside of the game config, but before the game booted? + list = list.concat(this._pendingScene); + + for (i = 0; i < list.length; i++) + { + entry = list[i]; + + // { key: 'moveSpritePlugin', plugin: MoveSpritePlugin, , mapping: 'move' } + + key = GetFastValue(entry, 'key', null); + plugin = GetFastValue(entry, 'plugin', null); + mapping = GetFastValue(entry, 'mapping', null); + + if (key) + { + if (plugin) + { + this.installScenePlugin(key, plugin, mapping); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } + } + } + + this._pendingGlobal = []; + this._pendingScene = []; + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * Called by the Scene Systems class. Tells the plugin manager to install all Scene plugins into it. + * + * First it will install global references, i.e. references from the Game systems into the Scene Systems (and Scene if mapped.) + * Then it will install Core Scene Plugins followed by Scene Plugins registered with the PluginManager. + * Finally it will install any references to Global Plugins that have a Scene mapping property into the Scene itself. + * + * @method Phaser.Plugins.PluginManager#addToScene + * @protected + * @since 3.8.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems class to install all the plugins in to. + * @param {array} globalPlugins - An array of global plugins to install. + * @param {array} scenePlugins - An array of scene plugins to install. + */ + addToScene: function (sys, globalPlugins, scenePlugins) + { + var i; + var pluginKey; + var pluginList; + var game = this.game; + var scene = sys.scene; + var map = sys.settings.map; + var isBooted = sys.settings.isBooted; + + // Reference the GlobalPlugins from Game into Scene.Systems + for (i = 0; i < globalPlugins.length; i++) + { + pluginKey = globalPlugins[i]; + + if (game[pluginKey]) + { + sys[pluginKey] = game[pluginKey]; + + // Scene level injection + if (map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = sys[pluginKey]; + } + } + else if (pluginKey === 'game' && map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = game; + } + } + + for (var s = 0; s < scenePlugins.length; s++) + { + pluginList = scenePlugins[s]; + + for (i = 0; i < pluginList.length; i++) + { + pluginKey = pluginList[i]; + + if (!PluginCache.hasCore(pluginKey)) + { + continue; + } + + var source = PluginCache.getCore(pluginKey); + + var plugin = new source.plugin(scene, this); + + sys[source.mapping] = plugin; + + // Scene level injection + if (source.custom) + { + scene[source.mapping] = plugin; + } + else if (map.hasOwnProperty(source.mapping)) + { + scene[map[source.mapping]] = plugin; + } + + // Scene is already booted, usually because this method is being called at run-time, so boot the plugin + if (isBooted) + { + plugin.boot(); + } + } + } + + // And finally, inject any 'global scene plugins' + pluginList = this.plugins; + + for (i = 0; i < pluginList.length; i++) + { + var entry = pluginList[i]; + + if (entry.mapping) + { + scene[entry.mapping] = entry.plugin; + } + } + }, + + /** + * Called by the Scene Systems class. Returns a list of plugins to be installed. + * + * @method Phaser.Plugins.PluginManager#getDefaultScenePlugins + * @protected + * @since 3.8.0 + * + * @return {string[]} A list keys of all the Scene Plugins to install. + */ + getDefaultScenePlugins: function () + { + var list = this.game.config.defaultPlugins; + + // Merge in custom Scene plugins + list = list.concat(this.scenePlugins); + + return list; + }, + + /** + * Installs a new Scene Plugin into the Plugin Manager and optionally adds it + * to the given Scene as well. A Scene Plugin added to the manager in this way + * will be automatically installed into all new Scenes using the key and mapping given. + * + * The `key` property is what the plugin is injected into Scene.Systems as. + * The `mapping` property is optional, and if specified is what the plugin is installed into + * the Scene as. For example: + * + * ```javascript + * this.plugins.installScenePlugin('powerupsPlugin', pluginCode, 'powerups'); + * + * // and from within the scene: + * this.sys.powerupsPlugin; // key value + * this.powerups; // mapping value + * ``` + * + * This method is called automatically by Phaser if you install your plugins using either the + * Game Configuration object, or by preloading them via the Loader. + * + * @method Phaser.Plugins.PluginManager#installScenePlugin + * @since 3.8.0 + * + * @param {string} key - The property key that will be used to add this plugin to Scene.Systems. + * @param {function} plugin - The plugin code. This should be the non-instantiated version. + * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. + * @param {Phaser.Scene} [addToScene] - Optionally automatically add this plugin to the given Scene. + * @param {boolean} [fromLoader=false] - Is this being called by the Loader? + */ + installScenePlugin: function (key, plugin, mapping, addToScene, fromLoader) + { + if (fromLoader === undefined) { fromLoader = false; } + + if (typeof plugin !== 'function') + { + console.warn('Invalid Scene Plugin: ' + key); + return; + } + + if (!PluginCache.hasCore(key)) + { + // Plugin is freshly loaded + PluginCache.register(key, plugin, mapping, true); + + this.scenePlugins.push(key); + } + else if (!fromLoader && PluginCache.hasCore(key)) + { + // Plugin wasn't from the loader but already exists + console.warn('Scene Plugin key in use: ' + key); + return; + } + + if (addToScene) + { + var instance = new plugin(addToScene, this); + + addToScene.sys[key] = instance; + + if (mapping && mapping !== '') + { + addToScene[mapping] = instance; + } + + instance.boot(); + } + }, + + /** + * Installs a new Global Plugin into the Plugin Manager and optionally starts it running. + * A global plugin belongs to the Plugin Manager, rather than a specific Scene, and can be accessed + * and used by all Scenes in your game. + * + * The `key` property is what you use to access this plugin from the Plugin Manager. + * + * ```javascript + * this.plugins.install('powerupsPlugin', pluginCode); + * + * // and from within the scene: + * this.plugins.get('powerupsPlugin'); + * ``` + * + * This method is called automatically by Phaser if you install your plugins using either the + * Game Configuration object, or by preloading them via the Loader. + * + * The same plugin can be installed multiple times into the Plugin Manager by simply giving each + * instance its own unique key. + * + * @method Phaser.Plugins.PluginManager#install + * @since 3.8.0 + * + * @param {string} key - The unique handle given to this plugin within the Plugin Manager. + * @param {function} plugin - The plugin code. This should be the non-instantiated version. + * @param {boolean} [start=false] - Automatically start the plugin running? This is always `true` if you provide a mapping value. + * @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use. + * @param {any} [data] - A value passed to the plugin's `init` method. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if `start` was false, or game isn't yet booted. + */ + install: function (key, plugin, start, mapping, data) + { + if (start === undefined) { start = false; } + if (mapping === undefined) { mapping = null; } + if (data === undefined) { data = null; } + + if (typeof plugin !== 'function') + { + console.warn('Invalid Plugin: ' + key); + return null; + } + + if (PluginCache.hasCustom(key)) + { + console.warn('Plugin key in use: ' + key); + return null; + } + + if (mapping !== null) + { + start = true; + } + + if (!this.game.isBooted) + { + this._pendingGlobal.push({ key: key, plugin: plugin, start: start, mapping: mapping, data: data }); + } + else + { + // Add it to the plugin store + PluginCache.registerCustom(key, plugin, mapping, data); + + if (start) + { + return this.start(key); + } + } + + return null; + }, + + /** + * Gets an index of a global plugin based on the given key. + * + * @method Phaser.Plugins.PluginManager#getIndex + * @protected + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {number} The index of the plugin within the plugins array. + */ + getIndex: function (key) + { + var list = this.plugins; + + for (var i = 0; i < list.length; i++) + { + var entry = list[i]; + + if (entry.key === key) + { + return i; + } + } + + return -1; + }, + + /** + * Gets a global plugin based on the given key. + * + * @method Phaser.Plugins.PluginManager#getEntry + * @protected + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {Phaser.Types.Plugins.GlobalPlugin} The plugin entry. + */ + getEntry: function (key) + { + var idx = this.getIndex(key); + + if (idx !== -1) + { + return this.plugins[idx]; + } + }, + + /** + * Checks if the given global plugin, based on its key, is active or not. + * + * @method Phaser.Plugins.PluginManager#isActive + * @since 3.8.0 + * + * @param {string} key - The unique plugin key. + * + * @return {boolean} `true` if the plugin is active, otherwise `false`. + */ + isActive: function (key) + { + var entry = this.getEntry(key); + + return (entry && entry.active); + }, + + /** + * Starts a global plugin running. + * + * If the plugin was previously active then calling `start` will reset it to an active state and then + * call its `start` method. + * + * If the plugin has never been run before a new instance of it will be created within the Plugin Manager, + * its active state set and then both of its `init` and `start` methods called, in that order. + * + * If the plugin is already running under the given key then nothing happens. + * + * @method Phaser.Plugins.PluginManager#start + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to start. + * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given or plugin is already stopped. + */ + start: function (key, runAs) + { + if (runAs === undefined) { runAs = key; } + + var entry = this.getEntry(runAs); + + // Plugin already running under this key? + if (entry && !entry.active) + { + // It exists, we just need to start it up again + entry.active = true; + entry.plugin.start(); + } + else if (!entry) + { + entry = this.createEntry(key, runAs); + } + + return (entry) ? entry.plugin : null; + }, + + /** + * Creates a new instance of a global plugin, adds an entry into the plugins array and returns it. + * + * @method Phaser.Plugins.PluginManager#createEntry + * @private + * @since 3.9.0 + * + * @param {string} key - The key of the plugin to create an instance of. + * @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times. + * + * @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given. + */ + createEntry: function (key, runAs) + { + var entry = PluginCache.getCustom(key); + + if (entry) + { + var instance = new entry.plugin(this); + + entry = { + key: runAs, + plugin: instance, + active: true, + mapping: entry.mapping, + data: entry.data + }; + + this.plugins.push(entry); + + instance.init(entry.data); + instance.start(); + } + + return entry; + }, + + /** + * Stops a global plugin from running. + * + * If the plugin is active then its active state will be set to false and the plugins `stop` method + * will be called. + * + * If the plugin is not already running, nothing will happen. + * + * @method Phaser.Plugins.PluginManager#stop + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to stop. + * + * @return {this} The Plugin Manager. + */ + stop: function (key) + { + var entry = this.getEntry(key); + + if (entry && entry.active) + { + entry.active = false; + entry.plugin.stop(); + } + + return this; + }, + + /** + * Gets a global plugin from the Plugin Manager based on the given key and returns it. + * + * If it cannot find an active plugin based on the key, but there is one in the Plugin Cache with the same key, + * then it will create a new instance of the cached plugin and return that. + * + * @method Phaser.Plugins.PluginManager#get + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to get. + * @param {boolean} [autoStart=true] - Automatically start a new instance of the plugin if found in the cache, but not actively running. + * + * @return {?(Phaser.Plugins.BasePlugin|function)} The plugin, or `null` if no plugin was found matching the key. + */ + get: function (key, autoStart) + { + if (autoStart === undefined) { autoStart = true; } + + var entry = this.getEntry(key); + + if (entry) + { + return entry.plugin; + } + else + { + var plugin = this.getClass(key); + + if (plugin && autoStart) + { + entry = this.createEntry(key, key); + + return (entry) ? entry.plugin : null; + } + else if (plugin) + { + return plugin; + } + } + + return null; + }, + + /** + * Returns the plugin class from the cache. + * Used internally by the Plugin Manager. + * + * @method Phaser.Plugins.PluginManager#getClass + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to get. + * + * @return {Phaser.Plugins.BasePlugin} A Plugin object + */ + getClass: function (key) + { + return PluginCache.getCustomClass(key); + }, + + /** + * Removes a global plugin from the Plugin Manager and Plugin Cache. + * + * It is up to you to remove all references to this plugin that you may hold within your game code. + * + * @method Phaser.Plugins.PluginManager#removeGlobalPlugin + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to remove. + */ + removeGlobalPlugin: function (key) + { + var entry = this.getEntry(key); + + if (entry) + { + Remove(this.plugins, entry); + } + + PluginCache.removeCustom(key); + }, + + /** + * Removes a scene plugin from the Plugin Manager and Plugin Cache. + * + * This will not remove the plugin from any active Scenes that are already using it. + * + * It is up to you to remove all references to this plugin that you may hold within your game code. + * + * @method Phaser.Plugins.PluginManager#removeScenePlugin + * @since 3.8.0 + * + * @param {string} key - The key of the plugin to remove. + */ + removeScenePlugin: function (key) + { + Remove(this.scenePlugins, key); + + PluginCache.remove(key); + }, + + /** + * Registers a new type of Game Object with the global Game Object Factory and / or Creator. + * This is usually called from within your Plugin code and is a helpful short-cut for creating + * new Game Objects. + * + * The key is the property that will be injected into the factories and used to create the + * Game Object. For example: + * + * ```javascript + * this.plugins.registerGameObject('clown', clownFactoryCallback, clownCreatorCallback); + * // later in your game code: + * this.add.clown(); + * this.make.clown(); + * ``` + * + * The callbacks are what are called when the factories try to create a Game Object + * matching the given key. It's important to understand that the callbacks are invoked within + * the context of the GameObjectFactory. In this context there are several properties available + * to use: + * + * this.scene - A reference to the Scene that owns the GameObjectFactory. + * this.displayList - A reference to the Display List the Scene owns. + * this.updateList - A reference to the Update List the Scene owns. + * + * See the GameObjectFactory and GameObjectCreator classes for more details. + * Any public property or method listed is available from your callbacks under `this`. + * + * @method Phaser.Plugins.PluginManager#registerGameObject + * @since 3.8.0 + * + * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. + * @param {function} [factoryCallback] - The callback to invoke when the Game Object Factory is called. + * @param {function} [creatorCallback] - The callback to invoke when the Game Object Creator is called. + */ + registerGameObject: function (key, factoryCallback, creatorCallback) + { + if (factoryCallback) + { + GameObjectFactory.register(key, factoryCallback); + } + + if (creatorCallback) + { + GameObjectCreator.register(key, creatorCallback); + } + + return this; + }, + + /** + * Removes a previously registered Game Object from the global Game Object Factory and / or Creator. + * This is usually called from within your Plugin destruction code to help clean-up after your plugin has been removed. + * + * @method Phaser.Plugins.PluginManager#removeGameObject + * @since 3.19.0 + * + * @param {string} key - The key of the Game Object to be removed from the factories. + * @param {boolean} [removeFromFactory=true] - Should the Game Object be removed from the Game Object Factory? + * @param {boolean} [removeFromCreator=true] - Should the Game Object be removed from the Game Object Creator? + */ + removeGameObject: function (key, removeFromFactory, removeFromCreator) + { + if (removeFromFactory === undefined) { removeFromFactory = true; } + if (removeFromCreator === undefined) { removeFromCreator = true; } + + if (removeFromFactory) + { + GameObjectFactory.remove(key); + } + + if (removeFromCreator) + { + GameObjectCreator.remove(key); + } + + return this; + }, + + /** + * Registers a new file type with the global File Types Manager, making it available to all Loader + * Plugins created after this. + * + * This is usually called from within your Plugin code and is a helpful short-cut for creating + * new loader file types. + * + * The key is the property that will be injected into the Loader Plugin and used to load the + * files. For example: + * + * ```javascript + * this.plugins.registerFileType('wad', doomWadLoaderCallback); + * // later in your preload code: + * this.load.wad(); + * ``` + * + * The callback is what is called when the loader tries to load a file matching the given key. + * It's important to understand that the callback is invoked within + * the context of the LoaderPlugin. In this context there are several properties / methods available + * to use: + * + * this.addFile - A method to add the new file to the load queue. + * this.scene - The Scene that owns the Loader Plugin instance. + * + * See the LoaderPlugin class for more details. Any public property or method listed is available from + * your callback under `this`. + * + * @method Phaser.Plugins.PluginManager#registerFileType + * @since 3.8.0 + * + * @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`. + * @param {function} callback - The callback to invoke when the Game Object Factory is called. + * @param {Phaser.Scene} [addToScene] - Optionally add this file type into the Loader Plugin owned by the given Scene. + */ + registerFileType: function (key, callback, addToScene) + { + FileTypesManager.register(key, callback); + + if (addToScene && addToScene.sys.load) + { + addToScene.sys.load[key] = callback; + } + }, + + /** + * Destroys this Plugin Manager and all associated plugins. + * It will iterate all plugins found and call their `destroy` methods. + * + * The PluginCache will remove all custom plugins. + * + * @method Phaser.Plugins.PluginManager#destroy + * @since 3.8.0 + */ + destroy: function () + { + for (var i = 0; i < this.plugins.length; i++) + { + this.plugins[i].plugin.destroy(); + } + + PluginCache.destroyCustomPlugins(); + + if (this.game.noReturn) + { + PluginCache.destroyCorePlugins(); + } + + this.game = null; + this.plugins = []; + this.scenePlugins = []; + } + +}); + +/* + * "Sometimes, the elegant implementation is just a function. + * Not a method. Not a class. Not a framework. Just a function." + * -- John Carmack + */ + +module.exports = PluginManager; + + +/***/ }), +/* 409 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(198); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(101); +var GameEvents = __webpack_require__(22); +var GetInnerHeight = __webpack_require__(395); +var GetTarget = __webpack_require__(401); +var GetScreenOrientation = __webpack_require__(396); +var NOOP = __webpack_require__(1); +var Rectangle = __webpack_require__(10); +var Size = __webpack_require__(410); +var SnapFloor = __webpack_require__(76); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * The Scale Manager handles the scaling, resizing and alignment of the game canvas. + * + * The way scaling is handled is by setting the game canvas to a fixed size, which is defined in the + * game configuration. You also define the parent container in the game config. If no parent is given, + * it will default to using the document body. The Scale Manager will then look at the available space + * within the _parent_ and scale the canvas accordingly. Scaling is handled by setting the canvas CSS + * width and height properties, leaving the width and height of the canvas element itself untouched. + * Scaling is therefore achieved by keeping the core canvas the same size and 'stretching' + * it via its CSS properties. This gives the same result and speed as using the `transform-scale` CSS + * property, without the need for browser prefix handling. + * + * The calculations for the scale are heavily influenced by the bounding parent size, which is the computed + * dimensions of the canvas's parent. The CSS rules of the parent element play an important role in the + * operation of the Scale Manager. For example, if the parent has no defined width or height, then actions + * like auto-centering will fail to achieve the required result. The Scale Manager works in tandem with the + * CSS you set-up on the page hosting your game, rather than taking control of it. + * + * #### Parent and Display canvas containment guidelines: + * + * - Style the Parent element (of the game canvas) to control the Parent size and thus the games size and layout. + * + * - The Parent element's CSS styles should _effectively_ apply maximum (and minimum) bounding behavior. + * + * - The Parent element should _not_ apply a padding as this is not accounted for. + * If a padding is required apply it to the Parent's parent or apply a margin to the Parent. + * If you need to add a border, margin or any other CSS around your game container, then use a parent element and + * apply the CSS to this instead, otherwise you'll be constantly resizing the shape of the game container. + * + * - The Display canvas layout CSS styles (i.e. margins, size) should not be altered / specified as + * they may be updated by the Scale Manager. + * + * #### Scale Modes + * + * The way the scaling is handled is determined by the `scaleMode` property. The default is `NONE`, + * which prevents Phaser from scaling or touching the canvas, or its parent, at all. In this mode, you are + * responsible for all scaling. The other scaling modes afford you automatic scaling. + * + * If you wish to scale your game so that it always fits into the available space within the parent, you + * should use the scale mode `FIT`. Look at the documentation for other scale modes to see what options are + * available. Here is a basic config showing how to set this scale mode: + * + * ```javascript + * scale: { + * parent: 'yourgamediv', + * mode: Phaser.Scale.FIT, + * width: 800, + * height: 600 + * } + * ``` + * + * Place the `scale` config object within your game config. + * + * If you wish for the canvas to be resized directly, so that the canvas itself fills the available space + * (i.e. it isn't scaled, it's resized) then use the `RESIZE` scale mode. This will give you a 1:1 mapping + * of canvas pixels to game size. In this mode CSS isn't used to scale the canvas, it's literally adjusted + * to fill all available space within the parent. You should be extremely careful about the size of the + * canvas you're creating when doing this, as the larger the area, the more work the GPU has to do and it's + * very easy to hit fill-rate limits quickly. + * + * For complex, custom-scaling requirements, you should probably consider using the `RESIZE` scale mode, + * with your own limitations in place re: canvas dimensions and managing the scaling with the game scenes + * yourself. For the vast majority of games, however, the `FIT` mode is likely to be the most used. + * + * Please appreciate that the Scale Manager cannot perform miracles. All it does is scale your game canvas + * as best it can, based on what it can infer from its surrounding area. There are all kinds of environments + * where it's up to you to guide and help the canvas position itself, especially when built into rendering + * frameworks like React and Vue. If your page requires meta tags to prevent user scaling gestures, or such + * like, then it's up to you to ensure they are present in the html. + * + * #### Centering + * + * You can also have the game canvas automatically centered. Again, this relies heavily on the parent being + * properly configured and styled, as the centering offsets are based entirely on the available space + * within the parent element. Centering is disabled by default, or can be applied horizontally, vertically, + * or both. Here's an example: + * + * ```javascript + * scale: { + * parent: 'yourgamediv', + * autoCenter: Phaser.Scale.CENTER_BOTH, + * width: 800, + * height: 600 + * } + * ``` + * + * #### Fullscreen API + * + * If the browser supports it, you can send your game into fullscreen mode. In this mode, the game will fill + * the entire display, removing all browser UI and anything else present on the screen. It will remain in this + * mode until your game either disables it, or until the user tabs out or presses ESCape if on desktop. It's a + * great way to achieve a desktop-game like experience from the browser, but it does require a modern browser + * to handle it. Some mobile browsers also support this. + * + * @class ScaleManager + * @memberof Phaser.Scale + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.16.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance. + */ +var ScaleManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function ScaleManager (game) + { + EventEmitter.call(this); + + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Scale.ScaleManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.15.0 + */ + this.game = game; + + /** + * A reference to the HTML Canvas Element that Phaser uses to render the game. + * + * @name Phaser.Scale.ScaleManager#canvas + * @type {HTMLCanvasElement} + * @since 3.16.0 + */ + this.canvas; + + /** + * The DOM bounds of the canvas element. + * + * @name Phaser.Scale.ScaleManager#canvasBounds + * @type {Phaser.Geom.Rectangle} + * @since 3.16.0 + */ + this.canvasBounds = new Rectangle(); + + /** + * The parent object of the Canvas. Often a div, or the browser window, or nothing in non-browser environments. + * + * This is set in the Game Config as the `parent` property. If undefined (or just not present), it will default + * to use the document body. If specifically set to `null` Phaser will ignore all parent operations. + * + * @name Phaser.Scale.ScaleManager#parent + * @type {?any} + * @since 3.16.0 + */ + this.parent = null; + + /** + * Is the parent element the browser window? + * + * @name Phaser.Scale.ScaleManager#parentIsWindow + * @type {boolean} + * @since 3.16.0 + */ + this.parentIsWindow = false; + + /** + * The Parent Size component. + * + * @name Phaser.Scale.ScaleManager#parentSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.parentSize = new Size(); + + /** + * The Game Size component. + * + * The un-modified game size, as requested in the game config (the raw width / height), + * as used for world bounds, cameras, etc + * + * @name Phaser.Scale.ScaleManager#gameSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.gameSize = new Size(); + + /** + * The Base Size component. + * + * The modified game size, which is the auto-rounded gameSize, used to set the canvas width and height + * (but not the CSS style) + * + * @name Phaser.Scale.ScaleManager#baseSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.baseSize = new Size(); + + /** + * The Display Size component. + * + * The size used for the canvas style, factoring in the scale mode, parent and other values. + * + * @name Phaser.Scale.ScaleManager#displaySize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.displaySize = new Size(); + + /** + * The game scale mode. + * + * @name Phaser.Scale.ScaleManager#scaleMode + * @type {Phaser.Scale.ScaleModeType} + * @since 3.16.0 + */ + this.scaleMode = CONST.SCALE_MODE.NONE; + + /** + * The game zoom factor. + * + * This value allows you to multiply your games base size by the given zoom factor. + * This is then used when calculating the display size, even in `NONE` situations. + * If you don't want Phaser to touch the canvas style at all, this value should be 1. + * + * Can also be set to `MAX_ZOOM` in which case the zoom value will be derived based + * on the game size and available space within the parent. + * + * @name Phaser.Scale.ScaleManager#zoom + * @type {number} + * @since 3.16.0 + */ + this.zoom = 1; + + /** + * Internal flag set when the game zoom factor is modified. + * + * @name Phaser.Scale.ScaleManager#_resetZoom + * @type {boolean} + * @readonly + * @since 3.19.0 + */ + this._resetZoom = false; + + /** + * The scale factor between the baseSize and the canvasBounds. + * + * @name Phaser.Scale.ScaleManager#displayScale + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ + this.displayScale = new Vector2(1, 1); + + /** + * If set, the canvas sizes will be automatically passed through Math.floor. + * This results in rounded pixel display values, which is important for performance on legacy + * and low powered devices, but at the cost of not achieving a 'perfect' fit in some browser windows. + * + * @name Phaser.Scale.ScaleManager#autoRound + * @type {boolean} + * @since 3.16.0 + */ + this.autoRound = false; + + /** + * Automatically center the canvas within the parent? The different centering modes are: + * + * 1. No centering. + * 2. Center both horizontally and vertically. + * 3. Center horizontally. + * 4. Center vertically. + * + * Please be aware that in order to center the game canvas, you must have specified a parent + * that has a size set, or the canvas parent is the document.body. + * + * @name Phaser.Scale.ScaleManager#autoCenter + * @type {Phaser.Scale.CenterType} + * @since 3.16.0 + */ + this.autoCenter = CONST.CENTER.NO_CENTER; + + /** + * The current device orientation. + * + * Orientation events are dispatched via the Device Orientation API, typically only on mobile browsers. + * + * @name Phaser.Scale.ScaleManager#orientation + * @type {Phaser.Scale.OrientationType} + * @since 3.16.0 + */ + this.orientation = CONST.ORIENTATION.LANDSCAPE; + + /** + * A reference to the Device.Fullscreen object. + * + * @name Phaser.Scale.ScaleManager#fullscreen + * @type {Phaser.Device.Fullscreen} + * @since 3.16.0 + */ + this.fullscreen; + + /** + * The DOM Element which is sent into fullscreen mode. + * + * @name Phaser.Scale.ScaleManager#fullscreenTarget + * @type {?any} + * @since 3.16.0 + */ + this.fullscreenTarget = null; + + /** + * Did Phaser create the fullscreen target div, or was it provided in the game config? + * + * @name Phaser.Scale.ScaleManager#_createdFullscreenTarget + * @type {boolean} + * @private + * @since 3.16.0 + */ + this._createdFullscreenTarget = false; + + /** + * The dirty state of the Scale Manager. + * Set if there is a change between the parent size and the current size. + * + * @name Phaser.Scale.ScaleManager#dirty + * @type {boolean} + * @since 3.16.0 + */ + this.dirty = false; + + /** + * How many milliseconds should elapse before checking if the browser size has changed? + * + * Most modern browsers dispatch a 'resize' event, which the Scale Manager will listen for. + * However, older browsers fail to do this, or do it consistently, so we fall back to a + * more traditional 'size check' based on a time interval. You can control how often it is + * checked here. + * + * @name Phaser.Scale.ScaleManager#resizeInterval + * @type {number} + * @since 3.16.0 + */ + this.resizeInterval = 500; + + /** + * Internal size interval tracker. + * + * @name Phaser.Scale.ScaleManager#_lastCheck + * @type {number} + * @private + * @since 3.16.0 + */ + this._lastCheck = 0; + + /** + * Internal flag to check orientation state. + * + * @name Phaser.Scale.ScaleManager#_checkOrientation + * @type {boolean} + * @private + * @since 3.16.0 + */ + this._checkOrientation = false; + + /** + * Internal object containing our defined event listeners. + * + * @name Phaser.Scale.ScaleManager#listeners + * @type {object} + * @private + * @since 3.16.0 + */ + this.listeners = { + + orientationChange: NOOP, + windowResize: NOOP, + fullScreenChange: NOOP, + fullScreenError: NOOP + + }; + }, + + /** + * Called _before_ the canvas object is created and added to the DOM. + * + * @method Phaser.Scale.ScaleManager#preBoot + * @protected + * @listens Phaser.Core.Events#BOOT + * @since 3.16.0 + */ + preBoot: function () + { + // Parse the config to get the scaling values we need + this.parseConfig(this.game.config); + + this.game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot handler is called by Phaser.Game when it first starts up. + * The renderer is available by now and the canvas has been added to the DOM. + * + * @method Phaser.Scale.ScaleManager#boot + * @protected + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + */ + boot: function () + { + var game = this.game; + + this.canvas = game.canvas; + + this.fullscreen = game.device.fullscreen; + + if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) + { + this.displaySize.setAspectMode(this.scaleMode); + } + + if (this.scaleMode === CONST.SCALE_MODE.NONE) + { + this.resize(this.width, this.height); + } + else + { + this.getParentBounds(); + + // Only set the parent bounds if the parent has an actual size + if (this.parentSize.width > 0 && this.parentSize.height > 0) + { + this.displaySize.setParent(this.parentSize); + } + + this.refresh(); + } + + game.events.on(GameEvents.PRE_STEP, this.step, this); + game.events.once(GameEvents.READY, this.refresh, this); + game.events.once(GameEvents.DESTROY, this.destroy, this); + + this.startListeners(); + }, + + /** + * Parses the game configuration to set-up the scale defaults. + * + * @method Phaser.Scale.ScaleManager#parseConfig + * @protected + * @since 3.16.0 + * + * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. + */ + parseConfig: function (config) + { + // Get the parent element, if any + this.getParent(config); + + // Get the size of the parent element + // This can often set a height of zero (especially for un-styled divs) + this.getParentBounds(); + + var width = config.width; + var height = config.height; + var scaleMode = config.scaleMode; + var zoom = config.zoom; + var autoRound = config.autoRound; + + // If width = '100%', or similar value + if (typeof width === 'string') + { + // If we have a parent with a height, we'll work it out from that + var parentWidth = this.parentSize.width; + + if (parentWidth === 0) + { + parentWidth = window.innerWidth; + } + + var parentScaleX = parseInt(width, 10) / 100; + + width = Math.floor(parentWidth * parentScaleX); + } + + // If height = '100%', or similar value + if (typeof height === 'string') + { + // If we have a parent with a height, we'll work it out from that + var parentHeight = this.parentSize.height; + + if (parentHeight === 0) + { + parentHeight = window.innerHeight; + } + + var parentScaleY = parseInt(height, 10) / 100; + + height = Math.floor(parentHeight * parentScaleY); + } + + this.scaleMode = scaleMode; + + this.autoRound = autoRound; + + this.autoCenter = config.autoCenter; + + this.resizeInterval = config.resizeInterval; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.setSize(width, height); + + if (zoom === CONST.ZOOM.MAX_ZOOM) + { + zoom = this.getMaxZoom(); + } + + this.zoom = zoom; + + if (zoom !== 1) + { + this._resetZoom = true; + } + + // The modified game size + this.baseSize.setSize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + if (config.minWidth > 0) + { + this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom); + } + + if (config.maxWidth > 0) + { + this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) + this.displaySize.setSize(width, height); + + this.orientation = GetScreenOrientation(width, height); + }, + + /** + * Determines the parent element of the game canvas, if any, based on the game configuration. + * + * @method Phaser.Scale.ScaleManager#getParent + * @since 3.16.0 + * + * @param {Phaser.Types.Core.GameConfig} config - The Game configuration object. + */ + getParent: function (config) + { + var parent = config.parent; + + if (parent === null) + { + // User is responsible for managing the parent + return; + } + + this.parent = GetTarget(parent); + this.parentIsWindow = (this.parent === document.body); + + if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) + { + var DOMRect = this.parent.getBoundingClientRect(); + + if (this.parentIsWindow || DOMRect.height === 0) + { + document.documentElement.style.height = '100%'; + document.body.style.height = '100%'; + + DOMRect = this.parent.getBoundingClientRect(); + + // The parent STILL has no height, clearly no CSS + // has been set on it even though we fixed the body :( + if (!this.parentIsWindow && DOMRect.height === 0) + { + this.parent.style.overflow = 'hidden'; + this.parent.style.width = '100%'; + this.parent.style.height = '100%'; + } + } + } + + // And now get the fullscreenTarget + if (config.fullscreenTarget && !this.fullscreenTarget) + { + this.fullscreenTarget = GetTarget(config.fullscreenTarget); + } + }, + + /** + * Calculates the size of the parent bounds and updates the `parentSize` component, if the canvas has a dom parent. + * + * @method Phaser.Scale.ScaleManager#getParentBounds + * @since 3.16.0 + * + * @return {boolean} `true` if the parent bounds have changed size, otherwise `false`. + */ + getParentBounds: function () + { + if (!this.parent) + { + return false; + } + + var parentSize = this.parentSize; + + // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect + + var DOMRect = this.parent.getBoundingClientRect(); + + if (this.parentIsWindow && this.game.device.os.iOS) + { + DOMRect.height = GetInnerHeight(true); + } + + var newWidth = DOMRect.width; + var newHeight = DOMRect.height; + + if (parentSize.width !== newWidth || parentSize.height !== newHeight) + { + parentSize.setSize(newWidth, newHeight); + + return true; + } + else + { + return false; + } + }, + + /** + * Attempts to lock the orientation of the web browser using the Screen Orientation API. + * + * This API is only available on modern mobile browsers. + * See https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation for details. + * + * @method Phaser.Scale.ScaleManager#lockOrientation + * @since 3.16.0 + * + * @param {string} orientation - The orientation you'd like to lock the browser in. Should be an API string such as 'landscape', 'landscape-primary', 'portrait', etc. + * + * @return {boolean} `true` if the orientation was successfully locked, otherwise `false`. + */ + lockOrientation: function (orientation) + { + var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation; + + if (lock) + { + return lock.call(screen, orientation); + } + + return false; + }, + + /** + * This method will set the size of the Parent Size component, which is used in scaling + * and centering calculations. You only need to call this method if you have explicitly + * disabled the use of a parent in your game config, but still wish to take advantage of + * other Scale Manager features. + * + * @method Phaser.Scale.ScaleManager#setParentSize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the parent. + * @param {number} height - The new height of the parent. + * + * @return {this} The Scale Manager instance. + */ + setParentSize: function (width, height) + { + this.parentSize.setSize(width, height); + + return this.refresh(); + }, + + /** + * This method will set a new size for your game. + * + * It should only be used if you're looking to change the base size of your game and are using + * one of the Scale Manager scaling modes, i.e. `FIT`. If you're using `NONE` and wish to + * change the game and canvas size directly, then please use the `resize` method instead. + * + * @method Phaser.Scale.ScaleManager#setGameSize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the game. + * @param {number} height - The new height of the game. + * + * @return {this} The Scale Manager instance. + */ + setGameSize: function (width, height) + { + var autoRound = this.autoRound; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + var previousWidth = this.width; + var previousHeight = this.height; + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.resize(width, height); + + // The modified game size + this.baseSize.resize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // Update the aspect ratio + this.displaySize.setAspectRatio(width / height); + + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; + + return this.refresh(previousWidth, previousHeight); + }, + + /** + * Call this to modify the size of the Phaser canvas element directly. + * You should only use this if you are using the `NONE` scale mode, + * it will update all internal components completely. + * + * If all you want to do is change the size of the parent, see the `setParentSize` method. + * + * If all you want is to change the base size of the game, but still have the Scale Manager + * manage all the scaling (i.e. you're **not** using `NONE`), then see the `setGameSize` method. + * + * This method will set the `gameSize`, `baseSize` and `displaySize` components to the given + * dimensions. It will then resize the canvas width and height to the values given, by + * directly setting the properties. Finally, if you have set the Scale Manager zoom value + * to anything other than 1 (the default), it will set the canvas CSS width and height to + * be the given size multiplied by the zoom factor (the canvas pixel size remains untouched). + * + * If you have enabled `autoCenter`, it is then passed to the `updateCenter` method and + * the margins are set, allowing the canvas to be centered based on its parent element + * alone. Finally, the `displayScale` is adjusted and the RESIZE event dispatched. + * + * @method Phaser.Scale.ScaleManager#resize + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} width - The new width of the game. + * @param {number} height - The new height of the game. + * + * @return {this} The Scale Manager instance. + */ + resize: function (width, height) + { + var zoom = this.zoom; + var autoRound = this.autoRound; + + if (autoRound) + { + width = Math.floor(width); + height = Math.floor(height); + } + + var previousWidth = this.width; + var previousHeight = this.height; + + // The un-modified game size, as requested in the game config (the raw width / height) as used for world bounds, etc + this.gameSize.resize(width, height); + + // The modified game size + this.baseSize.resize(width, height); + + if (autoRound) + { + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); + } + + // The size used for the canvas style, factoring in the scale mode and parent and zoom value + // We just use the w/h here as this is what sets the aspect ratio (which doesn't then change) + this.displaySize.setSize((width * zoom), (height * zoom)); + + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; + + var style = this.canvas.style; + + var styleWidth = width * zoom; + var styleHeight = height * zoom; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + if (styleWidth !== width || styleHeight !== height) + { + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + } + + return this.refresh(previousWidth, previousHeight); + }, + + /** + * Sets the zoom value of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#setZoom + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} value - The new zoom value of the game. + * + * @return {this} The Scale Manager instance. + */ + setZoom: function (value) + { + this.zoom = value; + this._resetZoom = true; + + return this.refresh(); + }, + + /** + * Sets the zoom to be the maximum possible based on the _current_ parent size. + * + * @method Phaser.Scale.ScaleManager#setMaxZoom + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @return {this} The Scale Manager instance. + */ + setMaxZoom: function () + { + this.zoom = this.getMaxZoom(); + this._resetZoom = true; + + return this.refresh(); + }, + + /** + * Refreshes the internal scale values, bounds sizes and orientation checks. + * + * Once finished, dispatches the resize event. + * + * This is called automatically by the Scale Manager when the browser window size changes, + * as long as it is using a Scale Mode other than 'NONE'. + * + * @method Phaser.Scale.ScaleManager#refresh + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {number} [previousWidth] - The previous width of the game. Only set if the gameSize has changed. + * @param {number} [previousHeight] - The previous height of the game. Only set if the gameSize has changed. + * + * @return {this} The Scale Manager instance. + */ + refresh: function (previousWidth, previousHeight) + { + if (previousWidth === undefined) { previousWidth = this.width; } + if (previousHeight === undefined) { previousHeight = this.height; } + + this.updateScale(); + this.updateBounds(); + this.updateOrientation(); + + this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); + + var domContainer = this.game.domContainer; + + if (domContainer) + { + this.baseSize.setCSS(domContainer); + + var canvasStyle = this.canvas.style; + var domStyle = domContainer.style; + + domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; + + domStyle.marginLeft = canvasStyle.marginLeft; + domStyle.marginTop = canvasStyle.marginTop; + } + + this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); + + return this; + }, + + /** + * Internal method that checks the current screen orientation, only if the internal check flag is set. + * + * If the orientation has changed it updates the orientation property and then dispatches the orientation change event. + * + * @method Phaser.Scale.ScaleManager#updateOrientation + * @fires Phaser.Scale.Events#ORIENTATION_CHANGE + * @since 3.16.0 + */ + updateOrientation: function () + { + if (this._checkOrientation) + { + this._checkOrientation = false; + + var newOrientation = GetScreenOrientation(this.width, this.height); + + if (newOrientation !== this.orientation) + { + this.orientation = newOrientation; + + this.emit(Events.ORIENTATION_CHANGE, newOrientation); + } + } + }, + + /** + * Internal method that manages updating the size components based on the scale mode. + * + * @method Phaser.Scale.ScaleManager#updateScale + * @since 3.16.0 + */ + updateScale: function () + { + var style = this.canvas.style; + + var width = this.gameSize.width; + var height = this.gameSize.height; + + var styleWidth; + var styleHeight; + + var zoom = this.zoom; + var autoRound = this.autoRound; + + if (this.scaleMode === CONST.SCALE_MODE.NONE) + { + // No scale + this.displaySize.setSize((width * zoom), (height * zoom)); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + if (this._resetZoom) + { + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + + this._resetZoom = false; + } + } + else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) + { + // Resize to match parent + + // This will constrain using min/max + this.displaySize.setSize(this.parentSize.width, this.parentSize.height); + + this.gameSize.setSize(this.displaySize.width, this.displaySize.height); + + this.baseSize.setSize(this.displaySize.width, this.displaySize.height); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + this.canvas.width = styleWidth; + this.canvas.height = styleHeight; + } + else + { + // All other scale modes + this.displaySize.setSize(this.parentSize.width, this.parentSize.height); + + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; + + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } + + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + } + + // Update the parentSize in case the canvas / style change modified it + this.getParentBounds(); + + // Finally, update the centering + this.updateCenter(); + }, + + /** + * Calculates and returns the largest possible zoom factor, based on the current + * parent and game sizes. If the parent has no dimensions (i.e. an unstyled div), + * or is smaller than the un-zoomed game, then this will return a value of 1 (no zoom) + * + * @method Phaser.Scale.ScaleManager#getMaxZoom + * @since 3.16.0 + * + * @return {number} The maximum possible zoom factor. At a minimum this value is always at least 1. + */ + getMaxZoom: function () + { + var zoomH = SnapFloor(this.parentSize.width, this.gameSize.width, 0, true); + var zoomV = SnapFloor(this.parentSize.height, this.gameSize.height, 0, true); + + return Math.max(Math.min(zoomH, zoomV), 1); + }, + + /** + * Calculates and updates the canvas CSS style in order to center it within the + * bounds of its parent. If you have explicitly set parent to be `null` in your + * game config then this method will likely give incorrect results unless you have called the + * `setParentSize` method first. + * + * It works by modifying the canvas CSS `marginLeft` and `marginTop` properties. + * + * If they have already been set by your own style sheet, or code, this will overwrite them. + * + * To prevent the Scale Manager from centering the canvas, either do not set the + * `autoCenter` property in your game config, or make sure it is set to `NO_CENTER`. + * + * @method Phaser.Scale.ScaleManager#updateCenter + * @since 3.16.0 + */ + updateCenter: function () + { + var autoCenter = this.autoCenter; + + if (autoCenter === CONST.CENTER.NO_CENTER) + { + return; + } + + var canvas = this.canvas; + + var style = canvas.style; + + var bounds = canvas.getBoundingClientRect(); + + // var width = parseInt(canvas.style.width, 10) || canvas.width; + // var height = parseInt(canvas.style.height, 10) || canvas.height; + + var width = bounds.width; + var height = bounds.height; + + var offsetX = Math.floor((this.parentSize.width - width) / 2); + var offsetY = Math.floor((this.parentSize.height - height) / 2); + + if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) + { + offsetY = 0; + } + else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) + { + offsetX = 0; + } + + style.marginLeft = offsetX + 'px'; + style.marginTop = offsetY + 'px'; + }, + + /** + * Updates the `canvasBounds` rectangle to match the bounding client rectangle of the + * canvas element being used to track input events. + * + * @method Phaser.Scale.ScaleManager#updateBounds + * @since 3.16.0 + */ + updateBounds: function () + { + var bounds = this.canvasBounds; + var clientRect = this.canvas.getBoundingClientRect(); + + bounds.x = clientRect.left + (window.pageXOffset || 0) - (document.documentElement.clientLeft || 0); + bounds.y = clientRect.top + (window.pageYOffset || 0) - (document.documentElement.clientTop || 0); + bounds.width = clientRect.width; + bounds.height = clientRect.height; + }, + + /** + * Transforms the pageX value into the scaled coordinate space of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#transformX + * @since 3.16.0 + * + * @param {number} pageX - The DOM pageX value. + * + * @return {number} The translated value. + */ + transformX: function (pageX) + { + return (pageX - this.canvasBounds.left) * this.displayScale.x; + }, + + /** + * Transforms the pageY value into the scaled coordinate space of the Scale Manager. + * + * @method Phaser.Scale.ScaleManager#transformY + * @since 3.16.0 + * + * @param {number} pageY - The DOM pageY value. + * + * @return {number} The translated value. + */ + transformY: function (pageY) + { + return (pageY - this.canvasBounds.top) * this.displayScale.y; + }, + + /** + * Sends a request to the browser to ask it to go in to full screen mode, using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API Fullscreen API}. + * + * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. + * + * This method _must_ be called from a `pointerup` user-input gesture (**not** `pointerdown`). You cannot launch + * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked + * from fullscreen unless the iframe has the `allowfullscreen` attribute. + * + * On touch devices, such as Android and iOS Safari, you should always use `pointerup` and NOT `pointerdown`, + * otherwise the request will fail unless the document in which your game is embedded has already received + * some form of touch input, which you cannot guarantee. Activating fullscreen via `pointerup` circumvents + * this issue. + * + * Performing an action that navigates to another page, or opens another tab, will automatically cancel + * fullscreen mode, as will the user pressing the ESC key. To cancel fullscreen mode directly from your game, + * i.e. by clicking an icon, call the `stopFullscreen` method. + * + * A browser can only send one DOM element into fullscreen. You can control which element this is by + * setting the `fullscreenTarget` property in your game config, or changing the property in the Scale Manager. + * Note that the game canvas _must_ be a child of the target. If you do not give a target, Phaser will + * automatically create a blank `
` element and move the canvas into it, before going fullscreen. + * When it leaves fullscreen, the div will be removed. + * + * @method Phaser.Scale.ScaleManager#startFullscreen + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_FAILED + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. + */ + startFullscreen: function (fullscreenOptions) + { + if (fullscreenOptions === undefined) { fullscreenOptions = { navigationUI: 'hide' }; } + + var fullscreen = this.fullscreen; + + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); + + return; + } + + if (!fullscreen.active) + { + var fsTarget = this.getFullscreenTarget(); + + if (fullscreen.keyboard) + { + fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); + } + else + { + fsTarget[fullscreen.request](fullscreenOptions); + } + } + }, + + /** + * The browser has successfully entered fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#fullscreenSuccessHandler + * @private + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#RESIZE + * @since 3.17.0 + */ + fullscreenSuccessHandler: function () + { + this.getParentBounds(); + + this.refresh(); + + this.emit(Events.ENTER_FULLSCREEN); + }, + + /** + * The browser failed to enter fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#fullscreenErrorHandler + * @private + * @fires Phaser.Scale.Events#FULLSCREEN_FAILED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.17.0 + * + * @param {any} error - The DOM error event. + */ + fullscreenErrorHandler: function (error) + { + this.removeFullscreenTarget(); + + this.emit(Events.FULLSCREEN_FAILED, error); + }, + + /** + * An internal method that gets the target element that is used when entering fullscreen mode. + * + * @method Phaser.Scale.ScaleManager#getFullscreenTarget + * @since 3.16.0 + * + * @return {object} The fullscreen target element. + */ + getFullscreenTarget: function () + { + if (!this.fullscreenTarget) + { + var fsTarget = document.createElement('div'); + + fsTarget.style.margin = '0'; + fsTarget.style.padding = '0'; + fsTarget.style.width = '100%'; + fsTarget.style.height = '100%'; + + this.fullscreenTarget = fsTarget; + + this._createdFullscreenTarget = true; + } + + if (this._createdFullscreenTarget) + { + var canvasParent = this.canvas.parentNode; + + canvasParent.insertBefore(this.fullscreenTarget, this.canvas); + + this.fullscreenTarget.appendChild(this.canvas); + } + + return this.fullscreenTarget; + }, + + /** + * Removes the fullscreen target that was added to the DOM. + * + * @method Phaser.Scale.ScaleManager#removeFullscreenTarget + * @since 3.17.0 + */ + removeFullscreenTarget: function () + { + if (this._createdFullscreenTarget) + { + var fsTarget = this.fullscreenTarget; + + if (fsTarget && fsTarget.parentNode) + { + var parent = fsTarget.parentNode; + + parent.insertBefore(this.canvas, fsTarget); + + parent.removeChild(fsTarget); + } + } + }, + + /** + * Calling this method will cancel fullscreen mode, if the browser has entered it. + * + * @method Phaser.Scale.ScaleManager#stopFullscreen + * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @since 3.16.0 + */ + stopFullscreen: function () + { + var fullscreen = this.fullscreen; + + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); + + return false; + } + + if (fullscreen.active) + { + document[fullscreen.cancel](); + } + + this.removeFullscreenTarget(); + + // Get the parent size again as it will have changed + this.getParentBounds(); + + this.emit(Events.LEAVE_FULLSCREEN); + + this.refresh(); + }, + + /** + * Toggles the fullscreen mode. If already in fullscreen, calling this will cancel it. + * If not in fullscreen, this will request the browser to enter fullscreen mode. + * + * If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted. + * + * This method _must_ be called from a user-input gesture, such as `pointerdown`. You cannot launch + * games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked + * from fullscreen unless the iframe has the `allowfullscreen` attribute. + * + * @method Phaser.Scale.ScaleManager#toggleFullscreen + * @fires Phaser.Scale.Events#ENTER_FULLSCREEN + * @fires Phaser.Scale.Events#LEAVE_FULLSCREEN + * @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @fires Phaser.Scale.Events#RESIZE + * @since 3.16.0 + * + * @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen. + */ + toggleFullscreen: function (fullscreenOptions) + { + if (this.fullscreen.active) + { + this.stopFullscreen(); + } + else + { + this.startFullscreen(fullscreenOptions); + } + }, + + /** + * An internal method that starts the different DOM event listeners running. + * + * @method Phaser.Scale.ScaleManager#startListeners + * @since 3.16.0 + */ + startListeners: function () + { + var _this = this; + var listeners = this.listeners; + + listeners.orientationChange = function () + { + _this.updateBounds(); + + _this._checkOrientation = true; + _this.dirty = true; + }; + + listeners.windowResize = function () + { + _this.updateBounds(); + + _this.dirty = true; + }; + + // Only dispatched on mobile devices + window.addEventListener('orientationchange', listeners.orientationChange, false); + + window.addEventListener('resize', listeners.windowResize, false); + + if (this.fullscreen.available) + { + listeners.fullScreenChange = function (event) + { + return _this.onFullScreenChange(event); + }; + + listeners.fullScreenError = function (event) + { + return _this.onFullScreenError(event); + }; + + var vendors = [ 'webkit', 'moz', '' ]; + + vendors.forEach(function (prefix) + { + document.addEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); + document.addEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); + }); + + // MS Specific + document.addEventListener('MSFullscreenChange', listeners.fullScreenChange, false); + document.addEventListener('MSFullscreenError', listeners.fullScreenError, false); + } + }, + + /** + * Triggered when a fullscreenchange event is dispatched by the DOM. + * + * @method Phaser.Scale.ScaleManager#onFullScreenChange + * @protected + * @since 3.16.0 + */ + onFullScreenChange: function () + { + if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) + { + this.fullscreenSuccessHandler(); + } + else + { + // They pressed ESC while in fullscreen mode + this.stopFullscreen(); + } + }, + + /** + * Triggered when a fullscreenerror event is dispatched by the DOM. + * + * @method Phaser.Scale.ScaleManager#onFullScreenError + * @since 3.16.0 + */ + onFullScreenError: function () + { + this.removeFullscreenTarget(); + }, + + /** + * Internal method, called automatically by the game step. + * Monitors the elapsed time and resize interval to see if a parent bounds check needs to take place. + * + * @method Phaser.Scale.ScaleManager#step + * @since 3.16.0 + * + * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). + * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. + */ + step: function (time, delta) + { + if (!this.parent) + { + return; + } + + this._lastCheck += delta; + + if (this.dirty || this._lastCheck > this.resizeInterval) + { + // Returns true if the parent bounds have changed size + if (this.getParentBounds()) + { + this.refresh(); + } + + this.dirty = false; + this._lastCheck = 0; + } + }, + + /** + * Stops all DOM event listeners. + * + * @method Phaser.Scale.ScaleManager#stopListeners + * @since 3.16.0 + */ + stopListeners: function () + { + var listeners = this.listeners; + + window.removeEventListener('orientationchange', listeners.orientationChange, false); + window.removeEventListener('resize', listeners.windowResize, false); + + var vendors = [ 'webkit', 'moz', '' ]; + + vendors.forEach(function (prefix) + { + document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); + document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); + }); + + // MS Specific + document.removeEventListener('MSFullscreenChange', listeners.fullScreenChange, false); + document.removeEventListener('MSFullscreenError', listeners.fullScreenError, false); + }, + + /** + * Destroys this Scale Manager, releasing all references to external resources. + * Once destroyed, the Scale Manager cannot be used again. + * + * @method Phaser.Scale.ScaleManager#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.stopListeners(); + + this.game = null; + this.canvas = null; + this.canvasBounds = null; + this.parent = null; + this.fullscreenTarget = null; + + this.parentSize.destroy(); + this.gameSize.destroy(); + this.baseSize.destroy(); + this.displaySize.destroy(); + }, + + /** + * Is the browser currently in fullscreen mode or not? + * + * @name Phaser.Scale.ScaleManager#isFullscreen + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isFullscreen: { + + get: function () + { + return this.fullscreen.active; + } + + }, + + /** + * The game width. + * + * This is typically the size given in the game configuration. + * + * @name Phaser.Scale.ScaleManager#width + * @type {number} + * @readonly + * @since 3.16.0 + */ + width: { + + get: function () + { + return this.gameSize.width; + } + + }, + + /** + * The game height. + * + * This is typically the size given in the game configuration. + * + * @name Phaser.Scale.ScaleManager#height + * @type {number} + * @readonly + * @since 3.16.0 + */ + height: { + + get: function () + { + return this.gameSize.height; + } + + }, + + /** + * Is the device in a portrait orientation as reported by the Orientation API? + * This value is usually only available on mobile devices. + * + * @name Phaser.Scale.ScaleManager#isPortrait + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isPortrait: { + + get: function () + { + return (this.orientation === CONST.ORIENTATION.PORTRAIT); + } + + }, + + /** + * Is the device in a landscape orientation as reported by the Orientation API? + * This value is usually only available on mobile devices. + * + * @name Phaser.Scale.ScaleManager#isLandscape + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isLandscape: { + + get: function () + { + return (this.orientation === CONST.ORIENTATION.LANDSCAPE); + } + + }, + + /** + * Are the game dimensions portrait? (i.e. taller than they are wide) + * + * This is different to the device itself being in a portrait orientation. + * + * @name Phaser.Scale.ScaleManager#isGamePortrait + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isGamePortrait: { + + get: function () + { + return (this.height > this.width); + } + + }, + + /** + * Are the game dimensions landscape? (i.e. wider than they are tall) + * + * This is different to the device itself being in a landscape orientation. + * + * @name Phaser.Scale.ScaleManager#isGameLandscape + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isGameLandscape: { + + get: function () + { + return (this.width > this.height); + } + + } + +}); + +module.exports = ScaleManager; + + +/***/ }), +/* 410 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(18); +var Class = __webpack_require__(0); +var SnapFloor = __webpack_require__(76); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * The Size component allows you to set `width` and `height` properties and define the relationship between them. + * + * The component can automatically maintain the aspect ratios between the two values, and clamp them + * to a defined min-max range. You can also control the dominant axis. When dimensions are given to the Size component + * that would cause it to exceed its min-max range, the dimensions are adjusted based on the dominant axis. + * + * @class Size + * @memberof Phaser.Structs + * @constructor + * @since 3.16.0 + * + * @param {number} [width=0] - The width of the Size component. + * @param {number} [height=width] - The height of the Size component. If not given, it will use the `width`. + * @param {number} [aspectMode=0] - The aspect mode of the Size component. Defaults to 0, no mode. + * @param {any} [parent=null] - The parent of this Size component. Can be any object with public `width` and `height` properties. Dimensions are clamped to keep them within the parent bounds where possible. + */ +var Size = new Class({ + + initialize: + + function Size (width, height, aspectMode, parent) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + if (aspectMode === undefined) { aspectMode = 0; } + if (parent === undefined) { parent = null; } + + /** + * Internal width value. + * + * @name Phaser.Structs.Size#_width + * @type {number} + * @private + * @since 3.16.0 + */ + this._width = width; + + /** + * Internal height value. + * + * @name Phaser.Structs.Size#_height + * @type {number} + * @private + * @since 3.16.0 + */ + this._height = height; + + /** + * Internal parent reference. + * + * @name Phaser.Structs.Size#_parent + * @type {any} + * @private + * @since 3.16.0 + */ + this._parent = parent; + + /** + * The aspect mode this Size component will use when calculating its dimensions. + * This property is read-only. To change it use the `setAspectMode` method. + * + * @name Phaser.Structs.Size#aspectMode + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.aspectMode = aspectMode; + + /** + * The proportional relationship between the width and height. + * + * This property is read-only and is updated automatically when either the `width` or `height` properties are changed, + * depending on the aspect mode. + * + * @name Phaser.Structs.Size#aspectRatio + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.aspectRatio = (height === 0) ? 1 : width / height; + + /** + * The minimum allowed width. + * Cannot be less than zero. + * This value is read-only. To change it see the `setMin` method. + * + * @name Phaser.Structs.Size#minWidth + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.minWidth = 0; + + /** + * The minimum allowed height. + * Cannot be less than zero. + * This value is read-only. To change it see the `setMin` method. + * + * @name Phaser.Structs.Size#minHeight + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.minHeight = 0; + + /** + * The maximum allowed width. + * This value is read-only. To change it see the `setMax` method. + * + * @name Phaser.Structs.Size#maxWidth + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.maxWidth = Number.MAX_VALUE; + + /** + * The maximum allowed height. + * This value is read-only. To change it see the `setMax` method. + * + * @name Phaser.Structs.Size#maxHeight + * @type {number} + * @readonly + * @since 3.16.0 + */ + this.maxHeight = Number.MAX_VALUE; + + /** + * A Vector2 containing the horizontal and vertical snap values, which the width and height are snapped to during resizing. + * + * By default this is disabled. + * + * This property is read-only. To change it see the `setSnap` method. + * + * @name Phaser.Structs.Size#snapTo + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.16.0 + */ + this.snapTo = new Vector2(); + }, + + /** + * Sets the aspect mode of this Size component. + * + * The aspect mode controls what happens when you modify the `width` or `height` properties, or call `setSize`. + * + * It can be a number from 0 to 4, or a Size constant: + * + * 0. NONE = Do not make the size fit the aspect ratio. Change the ratio when the size changes. + * 1. WIDTH_CONTROLS_HEIGHT = The height is automatically adjusted based on the width. + * 2. HEIGHT_CONTROLS_WIDTH = The width is automatically adjusted based on the height. + * 3. FIT = The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. + * 4. ENVELOP = The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. + * + * Calling this method automatically recalculates the `width` and the `height`, if required. + * + * @method Phaser.Structs.Size#setAspectMode + * @since 3.16.0 + * + * @param {number} [value=0] - The aspect mode value. + * + * @return {this} This Size component instance. + */ + setAspectMode: function (value) + { + if (value === undefined) { value = 0; } + + this.aspectMode = value; + + return this.setSize(this._width, this._height); + }, + + /** + * By setting a Snap To value when this Size component is modified its dimensions will automatically + * by snapped to the nearest grid slice, using floor. For example, if you have snap value of 16, + * and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored) + * + * Note that snapping takes place before adjustments by the parent, or the min / max settings. If these + * values are not multiples of the given snap values, then this can result in un-snapped dimensions. + * + * Call this method with no arguments to reset the snap values. + * + * Calling this method automatically recalculates the `width` and the `height`, if required. + * + * @method Phaser.Structs.Size#setSnap + * @since 3.16.0 + * + * @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero. + * @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero. + * + * @return {this} This Size component instance. + */ + setSnap: function (snapWidth, snapHeight) + { + if (snapWidth === undefined) { snapWidth = 0; } + if (snapHeight === undefined) { snapHeight = snapWidth; } + + this.snapTo.set(snapWidth, snapHeight); + + return this.setSize(this._width, this._height); + }, + + /** + * Sets, or clears, the parent of this Size component. + * + * To clear the parent call this method with no arguments. + * + * The parent influences the maximum extents to which this Size component can expand, + * based on the aspect mode: + * + * NONE - The parent clamps both the width and height. + * WIDTH_CONTROLS_HEIGHT - The parent clamps just the width. + * HEIGHT_CONTROLS_WIDTH - The parent clamps just the height. + * FIT - The parent clamps whichever axis is required to ensure the size fits within it. + * ENVELOP - The parent is used to ensure the size fully envelops the parent. + * + * Calling this method automatically calls `setSize`. + * + * @method Phaser.Structs.Size#setParent + * @since 3.16.0 + * + * @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent. + * + * @return {this} This Size component instance. + */ + setParent: function (parent) + { + this._parent = parent; + + return this.setSize(this._width, this._height); + }, + + /** + * Set the minimum width and height values this Size component will allow. + * + * The minimum values can never be below zero, or greater than the maximum values. + * + * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. + * + * Note that based on the aspect mode, and if this Size component has a parent set or not, the minimums set here + * _can_ be exceed in some situations. + * + * @method Phaser.Structs.Size#setMin + * @since 3.16.0 + * + * @param {number} [width=0] - The minimum allowed width of the Size component. + * @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setMin: function (width, height) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + + this.minWidth = Clamp(width, 0, this.maxWidth); + this.minHeight = Clamp(height, 0, this.maxHeight); + + return this.setSize(this._width, this._height); + }, + + /** + * Set the maximum width and height values this Size component will allow. + * + * Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range. + * + * Note that based on the aspect mode, and if this Size component has a parent set or not, the maximums set here + * _can_ be exceed in some situations. + * + * @method Phaser.Structs.Size#setMax + * @since 3.16.0 + * + * @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component. + * @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setMax: function (width, height) + { + if (width === undefined) { width = Number.MAX_VALUE; } + if (height === undefined) { height = width; } + + this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); + this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); + + return this.setSize(this._width, this._height); + }, + + /** + * Sets the width and height of this Size component based on the aspect mode. + * + * If the aspect mode is 'none' then calling this method will change the aspect ratio, otherwise the current + * aspect ratio is honored across all other modes. + * + * If snapTo values have been set then the given width and height are snapped first, prior to any further + * adjustment via min/max values, or a parent. + * + * If minimum and/or maximum dimensions have been specified, the values given to this method will be clamped into + * that range prior to adjustment, but may still exceed them depending on the aspect mode. + * + * If this Size component has a parent set, and the aspect mode is `fit` or `envelop`, then the given sizes will + * be clamped to the range specified by the parent. + * + * @method Phaser.Structs.Size#setSize + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + setSize: function (width, height) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + + switch (this.aspectMode) + { + case Size.NONE: + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; + break; + + case Size.WIDTH_CONTROLS_HEIGHT: + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(this._width * (1 / this.aspectRatio), false); + break; + + case Size.HEIGHT_CONTROLS_WIDTH: + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this._width = this.getNewWidth(this._height * this.aspectRatio, false); + break; + + case Size.FIT: + this.constrain(width, height, true); + break; + + case Size.ENVELOP: + this.constrain(width, height, false); + break; + } + + return this; + }, + + /** + * Sets a new aspect ratio, overriding what was there previously. + * + * It then calls `setSize` immediately using the current dimensions. + * + * @method Phaser.Structs.Size#setAspectRatio + * @since 3.16.0 + * + * @param {number} ratio - The new aspect ratio. + * + * @return {this} This Size component instance. + */ + setAspectRatio: function (ratio) + { + this.aspectRatio = ratio; + + return this.setSize(this._width, this._height); + }, + + /** + * Sets a new width and height for this Size component and updates the aspect ratio based on them. + * + * It _doesn't_ change the `aspectMode` and still factors in size limits such as the min max and parent bounds. + * + * @method Phaser.Structs.Size#resize + * @since 3.16.0 + * + * @param {number} width - The new width of the Size component. + * @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`. + * + * @return {this} This Size component instance. + */ + resize: function (width, height) + { + this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x)); + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this.aspectRatio = (this._height === 0) ? 1 : this._width / this._height; + + return this; + }, + + /** + * Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width. + * + * @method Phaser.Structs.Size#getNewWidth + * @since 3.16.0 + * + * @param {number} value - The value to clamp and check. + * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * + * @return {number} The modified width value. + */ + getNewWidth: function (value, checkParent) + { + if (checkParent === undefined) { checkParent = true; } + + value = Clamp(value, this.minWidth, this.maxWidth); + + if (checkParent && this._parent && value > this._parent.width) + { + value = Math.max(this.minWidth, this._parent.width); + } + + return value; + }, + + /** + * Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height. + * + * @method Phaser.Structs.Size#getNewHeight + * @since 3.16.0 + * + * @param {number} value - The value to clamp and check. + * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * + * @return {number} The modified height value. + */ + getNewHeight: function (value, checkParent) + { + if (checkParent === undefined) { checkParent = true; } + + value = Clamp(value, this.minHeight, this.maxHeight); + + if (checkParent && this._parent && value > this._parent.height) + { + value = Math.max(this.minHeight, this._parent.height); + } + + return value; + }, + + /** + * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. + * + * If `fit` is true there may be some space inside the target area which is not covered if its aspect ratio differs. + * If `fit` is false the size may extend further out than the target area if the aspect ratios differ. + * + * If this Size component has a parent set, then the width and height passed to this method will be clamped so + * it cannot exceed that of the parent. + * + * @method Phaser.Structs.Size#constrain + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * @param {boolean} [fit=true] - Perform a `fit` (true) constraint, or an `envelop` (false) constraint. + * + * @return {this} This Size component instance. + */ + constrain: function (width, height, fit) + { + if (width === undefined) { width = 0; } + if (height === undefined) { height = width; } + if (fit === undefined) { fit = true; } + + width = this.getNewWidth(width); + height = this.getNewHeight(height); + + var snap = this.snapTo; + var newRatio = (height === 0) ? 1 : width / height; + + if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) + { + // We need to change the height to fit the width + + width = SnapFloor(width, snap.x); + + height = width / this.aspectRatio; + + if (snap.y > 0) + { + height = SnapFloor(height, snap.y); + + // Reduce the width accordingly + width = height * this.aspectRatio; + } + } + else if ((fit && this.aspectRatio < newRatio) || (!fit && this.aspectRatio > newRatio)) + { + // We need to change the width to fit the height + + height = SnapFloor(height, snap.y); + + width = height * this.aspectRatio; + + if (snap.x > 0) + { + width = SnapFloor(width, snap.x); + + // Reduce the height accordingly + height = width * (1 / this.aspectRatio); + } + } + + this._width = width; + this._height = height; + + return this; + }, + + /** + * The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio. + * + * There may be some space inside the target area which is not covered if its aspect ratio differs. + * + * If this Size component has a parent set, then the width and height passed to this method will be clamped so + * it cannot exceed that of the parent. + * + * @method Phaser.Structs.Size#fitTo + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * + * @return {this} This Size component instance. + */ + fitTo: function (width, height) + { + return this.constrain(width, height, true); + }, + + /** + * The current `width` and `height` are adjusted so that they fully envelope the given dimensions, while keeping the aspect ratio. + * + * The size may extend further out than the target area if the aspect ratios differ. + * + * If this Size component has a parent set, then the values are clamped so that it never exceeds the parent + * on the longest axis. + * + * @method Phaser.Structs.Size#envelop + * @since 3.16.0 + * + * @param {number} [width=0] - The new width of the Size component. + * @param {number} [height] - The new height of the Size component. If not given, it will use the width value. + * + * @return {this} This Size component instance. + */ + envelop: function (width, height) + { + return this.constrain(width, height, false); + }, + + /** + * Sets the width of this Size component. + * + * Depending on the aspect mode, changing the width may also update the height and aspect ratio. + * + * @method Phaser.Structs.Size#setWidth + * @since 3.16.0 + * + * @param {number} width - The new width of the Size component. + * + * @return {this} This Size component instance. + */ + setWidth: function (value) + { + return this.setSize(value, this._height); + }, + + /** + * Sets the height of this Size component. + * + * Depending on the aspect mode, changing the height may also update the width and aspect ratio. + * + * @method Phaser.Structs.Size#setHeight + * @since 3.16.0 + * + * @param {number} height - The new height of the Size component. + * + * @return {this} This Size component instance. + */ + setHeight: function (value) + { + return this.setSize(this._width, value); + }, + + /** + * Returns a string representation of this Size component. + * + * @method Phaser.Structs.Size#toString + * @since 3.16.0 + * + * @return {string} A string representation of this Size component. + */ + toString: function () + { + return '[{ Size (width=' + this._width + ' height=' + this._height + ' aspectRatio=' + this.aspectRatio + ' aspectMode=' + this.aspectMode + ') }]'; + }, + + /** + * Sets the values of this Size component to the `element.style.width` and `height` + * properties of the given DOM Element. The properties are set as `px` values. + * + * @method Phaser.Structs.Size#setCSS + * @since 3.17.0 + * + * @param {HTMLElement} element - The DOM Element to set the CSS style on. + */ + setCSS: function (element) + { + if (element && element.style) + { + element.style.width = this._width + 'px'; + element.style.height = this._height + 'px'; + } + }, + + /** + * Copies the aspect mode, aspect ratio, width and height from this Size component + * to the given Size component. Note that the parent, if set, is not copied across. + * + * @method Phaser.Structs.Size#copy + * @since 3.16.0 + * + * @param {Phaser.Structs.Size} destination - The Size component to copy the values to. + * + * @return {Phaser.Structs.Size} The updated destination Size component. + */ + copy: function (destination) + { + destination.setAspectMode(this.aspectMode); + + destination.aspectRatio = this.aspectRatio; + + return destination.setSize(this.width, this.height); + }, + + /** + * Destroys this Size component. + * + * This clears the local properties and any parent object, if set. + * + * A destroyed Size component cannot be re-used. + * + * @method Phaser.Structs.Size#destroy + * @since 3.16.0 + */ + destroy: function () + { + this._parent = null; + this.snapTo = null; + }, + + /** + * The width of this Size component. + * + * This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled. + * + * A width can never be less than zero. + * + * Changing this value will automatically update the `height` if the aspect ratio lock is enabled. + * You can also use the `setWidth` and `getWidth` methods. + * + * @name Phaser.Structs.Size#width + * @type {number} + * @since 3.16.0 + */ + width: { + + get: function () + { + return this._width; + }, + + set: function (value) + { + this.setSize(value, this._height); + } + + }, + + /** + * The height of this Size component. + * + * This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled. + * + * A height can never be less than zero. + * + * Changing this value will automatically update the `width` if the aspect ratio lock is enabled. + * You can also use the `setHeight` and `getHeight` methods. + * + * @name Phaser.Structs.Size#height + * @type {number} + * @since 3.16.0 + */ + height: { + + get: function () + { + return this._height; + }, + + set: function (value) + { + this.setSize(this._width, value); + } + + } + +}); + +/** + * Do not make the size fit the aspect ratio. Change the ratio when the size changes. + * + * @name Phaser.Structs.Size.NONE + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.NONE = 0; + +/** + * The height is automatically adjusted based on the width. + * + * @name Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.WIDTH_CONTROLS_HEIGHT = 1; + +/** + * The width is automatically adjusted based on the height. + * + * @name Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.HEIGHT_CONTROLS_WIDTH = 2; + +/** + * The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered. + * + * @name Phaser.Structs.Size.FIT + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.FIT = 3; + +/** + * The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size. + * + * @name Phaser.Structs.Size.ENVELOP + * @constant + * @type {number} + * @since 3.16.0 + */ +Size.ENVELOP = 4; + +module.exports = Size; + + +/***/ }), +/* 411 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(142); +var Events = __webpack_require__(21); +var GameEvents = __webpack_require__(22); +var GetValue = __webpack_require__(6); +var LoaderEvents = __webpack_require__(91); +var NOOP = __webpack_require__(1); +var Scene = __webpack_require__(412); +var Systems = __webpack_require__(201); + +/** + * @classdesc + * The Scene Manager. + * + * The Scene Manager is a Game level system, responsible for creating, processing and updating all of the + * Scenes in a Game instance. +ó * + * + * @class SceneManager + * @memberof Phaser.Scenes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance this Scene Manager belongs to. + * @param {object} sceneConfig - Scene specific configuration settings. + */ +var SceneManager = new Class({ + + initialize: + + function SceneManager (game, sceneConfig) + { + /** + * The Game that this SceneManager belongs to. + * + * @name Phaser.Scenes.SceneManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * An object that maps the keys to the scene so we can quickly get a scene from a key without iteration. + * + * @name Phaser.Scenes.SceneManager#keys + * @type {object} + * @since 3.0.0 + */ + this.keys = {}; + + /** + * The array in which all of the scenes are kept. + * + * @name Phaser.Scenes.SceneManager#scenes + * @type {array} + * @since 3.0.0 + */ + this.scenes = []; + + /** + * Scenes pending to be added are stored in here until the manager has time to add it. + * + * @name Phaser.Scenes.SceneManager#_pending + * @type {array} + * @private + * @since 3.0.0 + */ + this._pending = []; + + /** + * An array of scenes waiting to be started once the game has booted. + * + * @name Phaser.Scenes.SceneManager#_start + * @type {array} + * @private + * @since 3.0.0 + */ + this._start = []; + + /** + * An operations queue, because we don't manipulate the scenes array during processing. + * + * @name Phaser.Scenes.SceneManager#_queue + * @type {array} + * @private + * @since 3.0.0 + */ + this._queue = []; + + /** + * Boot time data to merge. + * + * @name Phaser.Scenes.SceneManager#_data + * @type {object} + * @private + * @since 3.4.0 + */ + this._data = {}; + + /** + * Is the Scene Manager actively processing the Scenes list? + * + * @name Phaser.Scenes.SceneManager#isProcessing + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isProcessing = false; + + /** + * Has the Scene Manager properly started? + * + * @name Phaser.Scenes.SceneManager#isBooted + * @type {boolean} + * @default false + * @readonly + * @since 3.4.0 + */ + this.isBooted = false; + + /** + * Do any of the Cameras in any of the Scenes require a custom viewport? + * If not we can skip scissor tests. + * + * @name Phaser.Scenes.SceneManager#customViewports + * @type {number} + * @default 0 + * @since 3.12.0 + */ + this.customViewports = 0; + + if (sceneConfig) + { + if (!Array.isArray(sceneConfig)) + { + sceneConfig = [ sceneConfig ]; + } + + for (var i = 0; i < sceneConfig.length; i++) + { + // The i === 0 part just autostarts the first Scene given (unless it says otherwise in its config) + this._pending.push({ + key: 'default', + scene: sceneConfig[i], + autoStart: (i === 0), + data: {} + }); + } + } + + game.events.once(GameEvents.READY, this.bootQueue, this); + }, + + /** + * Internal first-time Scene boot handler. + * + * @method Phaser.Scenes.SceneManager#bootQueue + * @private + * @since 3.2.0 + */ + bootQueue: function () + { + if (this.isBooted) + { + return; + } + + var i; + var entry; + var key; + var sceneConfig; + + for (i = 0; i < this._pending.length; i++) + { + entry = this._pending[i]; + + key = entry.key; + sceneConfig = entry.scene; + + var newScene; + + if (sceneConfig instanceof Scene) + { + newScene = this.createSceneFromInstance(key, sceneConfig); + } + else if (typeof sceneConfig === 'object') + { + newScene = this.createSceneFromObject(key, sceneConfig); + } + else if (typeof sceneConfig === 'function') + { + newScene = this.createSceneFromFunction(key, sceneConfig); + } + + // Replace key in case the scene changed it + key = newScene.sys.settings.key; + + this.keys[key] = newScene; + + this.scenes.push(newScene); + + // Any data to inject? + if (this._data[key]) + { + newScene.sys.settings.data = this._data[key].data; + + if (this._data[key].autoStart) + { + entry.autoStart = true; + } + } + + if (entry.autoStart || newScene.sys.settings.active) + { + this._start.push(key); + } + } + + // Clear the pending lists + this._pending.length = 0; + + this._data = {}; + + this.isBooted = true; + + // _start might have been populated by the above + for (i = 0; i < this._start.length; i++) + { + entry = this._start[i]; + + this.start(entry); + } + + this._start.length = 0; + }, + + /** + * Process the Scene operations queue. + * + * @method Phaser.Scenes.SceneManager#processQueue + * @since 3.0.0 + */ + processQueue: function () + { + var pendingLength = this._pending.length; + var queueLength = this._queue.length; + + if (pendingLength === 0 && queueLength === 0) + { + return; + } + + var i; + var entry; + + if (pendingLength) + { + for (i = 0; i < pendingLength; i++) + { + entry = this._pending[i]; + + this.add(entry.key, entry.scene, entry.autoStart, entry.data); + } + + // _start might have been populated by this.add + for (i = 0; i < this._start.length; i++) + { + entry = this._start[i]; + + this.start(entry); + } + + // Clear the pending lists + this._start.length = 0; + this._pending.length = 0; + + return; + } + + for (i = 0; i < this._queue.length; i++) + { + entry = this._queue[i]; + + this[entry.op](entry.keyA, entry.keyB); + } + + this._queue.length = 0; + }, + + /** + * Adds a new Scene into the SceneManager. + * You must give each Scene a unique key by which you'll identify it. + * + * The `sceneConfig` can be: + * + * * A `Phaser.Scene` object, or an object that extends it. + * * A plain JavaScript object + * * A JavaScript ES6 Class that extends `Phaser.Scene` + * * A JavaScript ES5 prototype based Class + * * A JavaScript function + * + * If a function is given then a new Scene will be created by calling it. + * + * @method Phaser.Scenes.SceneManager#add + * @since 3.0.0 + * + * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. + * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig|function)} sceneConfig - The config for the Scene + * @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added. + * @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. + * + * @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`. + */ + add: function (key, sceneConfig, autoStart, data) + { + if (autoStart === undefined) { autoStart = false; } + if (data === undefined) { data = {}; } + + // If processing or not booted then put scene into a holding pattern + if (this.isProcessing || !this.isBooted) + { + this._pending.push({ + key: key, + scene: sceneConfig, + autoStart: autoStart, + data: data + }); + + if (!this.isBooted) + { + this._data[key] = { data: data }; + } + + return null; + } + + key = this.getKey(key, sceneConfig); + + var newScene; + + if (sceneConfig instanceof Scene) + { + newScene = this.createSceneFromInstance(key, sceneConfig); + } + else if (typeof sceneConfig === 'object') + { + sceneConfig.key = key; + + newScene = this.createSceneFromObject(key, sceneConfig); + } + else if (typeof sceneConfig === 'function') + { + newScene = this.createSceneFromFunction(key, sceneConfig); + } + + // Any data to inject? + newScene.sys.settings.data = data; + + // Replace key in case the scene changed it + key = newScene.sys.settings.key; + + this.keys[key] = newScene; + + this.scenes.push(newScene); + + if (autoStart || newScene.sys.settings.active) + { + if (this._pending.length) + { + this._start.push(key); + } + else + { + this.start(key); + } + } + + return newScene; + }, + + /** + * Removes a Scene from the SceneManager. + * + * The Scene is removed from the local scenes array, it's key is cleared from the keys + * cache and Scene.Systems.destroy is then called on it. + * + * If the SceneManager is processing the Scenes when this method is called it will + * queue the operation for the next update sequence. + * + * @method Phaser.Scenes.SceneManager#remove + * @since 3.2.0 + * + * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + remove: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'remove', keyA: key, keyB: null }); + } + else + { + var sceneToRemove = this.getScene(key); + + if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) + { + return this; + } + + var index = this.scenes.indexOf(sceneToRemove); + var sceneKey = sceneToRemove.sys.settings.key; + + if (index > -1) + { + delete this.keys[sceneKey]; + this.scenes.splice(index, 1); + + if (this._start.indexOf(sceneKey) > -1) + { + index = this._start.indexOf(sceneKey); + this._start.splice(index, 1); + } + + sceneToRemove.sys.destroy(); + } + } + + return this; + }, + + /** + * Boot the given Scene. + * + * @method Phaser.Scenes.SceneManager#bootScene + * @private + * @fires Phaser.Scenes.Events#TRANSITION_INIT + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to boot. + */ + bootScene: function (scene) + { + var sys = scene.sys; + var settings = sys.settings; + + sys.sceneUpdate = NOOP; + + if (scene.init) + { + scene.init.call(scene, settings.data); + + settings.status = CONST.INIT; + + if (settings.isTransition) + { + sys.events.emit(Events.TRANSITION_INIT, settings.transitionFrom, settings.transitionDuration); + } + } + + var loader; + + if (sys.load) + { + loader = sys.load; + + loader.reset(); + } + + if (loader && scene.preload) + { + scene.preload.call(scene); + + // Is the loader empty? + if (loader.list.size === 0) + { + this.create(scene); + } + else + { + settings.status = CONST.LOADING; + + // Start the loader going as we have something in the queue + loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); + + loader.start(); + } + } + else + { + // No preload? Then there was nothing to load either + this.create(scene); + } + }, + + /** + * Handles load completion for a Scene's Loader. + * + * Starts the Scene that the Loader belongs to. + * + * @method Phaser.Scenes.SceneManager#loadComplete + * @private + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading. + */ + loadComplete: function (loader) + { + var scene = loader.scene; + + // TODO - Remove. This should *not* be handled here + // Try to unlock HTML5 sounds every time any loader completes + if (this.game.sound && this.game.sound.onBlurPausedSounds) + { + this.game.sound.unlock(); + } + + this.create(scene); + }, + + /** + * Handle payload completion for a Scene. + * + * @method Phaser.Scenes.SceneManager#payloadComplete + * @private + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading its Scene's payload. + */ + payloadComplete: function (loader) + { + this.bootScene(loader.scene); + }, + + /** + * Updates the Scenes. + * + * @method Phaser.Scenes.SceneManager#update + * @since 3.0.0 + * + * @param {number} time - Time elapsed. + * @param {number} delta - Delta time from the last update. + */ + update: function (time, delta) + { + this.processQueue(); + + this.isProcessing = true; + + // Loop through the active scenes in reverse order + for (var i = this.scenes.length - 1; i >= 0; i--) + { + var sys = this.scenes[i].sys; + + if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) + { + sys.step(time, delta); + } + } + }, + + /** + * Renders the Scenes. + * + * @method Phaser.Scenes.SceneManager#render + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer to use. + */ + render: function (renderer) + { + // Loop through the scenes in forward order + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) + { + sys.render(renderer); + } + } + + this.isProcessing = false; + }, + + /** + * Calls the given Scene's {@link Phaser.Scene#create} method and updates its status. + * + * @method Phaser.Scenes.SceneManager#create + * @private + * @fires Phaser.Scenes.Events#CREATE + * @fires Phaser.Scenes.Events#TRANSITION_INIT + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to create. + */ + create: function (scene) + { + var sys = scene.sys; + var settings = sys.settings; + + if (scene.create) + { + settings.status = CONST.CREATING; + + scene.create.call(scene, settings.data); + + if (settings.status === CONST.DESTROYED) + { + return; + } + } + + if (settings.isTransition) + { + sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration); + } + + // If the Scene has an update function we'll set it now, otherwise it'll remain as NOOP + if (scene.update) + { + sys.sceneUpdate = scene.update; + } + + settings.status = CONST.RUNNING; + + sys.events.emit(Events.CREATE, scene); + }, + + /** + * Creates and initializes a Scene from a function. + * + * @method Phaser.Scenes.SceneManager#createSceneFromFunction + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {function} scene - The function to create the Scene from. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromFunction: function (key, scene) + { + var newScene = new scene(); + + if (newScene instanceof Scene) + { + var configKey = newScene.sys.settings.key; + + if (configKey !== '') + { + key = configKey; + } + + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } + + return this.createSceneFromInstance(key, newScene); + } + else + { + newScene.sys = new Systems(newScene); + + newScene.sys.settings.key = key; + + newScene.sys.init(this.game); + + return newScene; + } + }, + + /** + * Creates and initializes a Scene instance. + * + * @method Phaser.Scenes.SceneManager#createSceneFromInstance + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {Phaser.Scene} newScene - The Scene instance. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromInstance: function (key, newScene) + { + var configKey = newScene.sys.settings.key; + + if (configKey === '') + { + newScene.sys.settings.key = key; + } + + newScene.sys.init(this.game); + + return newScene; + }, + + /** + * Creates and initializes a Scene from an Object definition. + * + * @method Phaser.Scenes.SceneManager#createSceneFromObject + * @private + * @since 3.0.0 + * + * @param {string} key - The key of the Scene. + * @param {(string|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig)} sceneConfig - The Scene config. + * + * @return {Phaser.Scene} The created Scene. + */ + createSceneFromObject: function (key, sceneConfig) + { + var newScene = new Scene(sceneConfig); + + var configKey = newScene.sys.settings.key; + + if (configKey !== '') + { + key = configKey; + } + else + { + newScene.sys.settings.key = key; + } + + newScene.sys.init(this.game); + + // Extract callbacks + + var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; + + for (var i = 0; i < defaults.length; i++) + { + var sceneCallback = GetValue(sceneConfig, defaults[i], null); + + if (sceneCallback) + { + newScene[defaults[i]] = sceneCallback; + } + } + + // Now let's move across any other functions or properties that may exist in the extend object: + + /* + scene: { + preload: preload, + create: create, + extend: { + hello: 1, + test: 'atari', + addImage: addImage + } + } + */ + + if (sceneConfig.hasOwnProperty('extend')) + { + for (var propertyKey in sceneConfig.extend) + { + if (!sceneConfig.extend.hasOwnProperty(propertyKey)) + { + continue; + } + + var value = sceneConfig.extend[propertyKey]; + + if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') + { + // Populate the DataManager + newScene.data.merge(value); + } + else if (propertyKey !== 'sys') + { + newScene[propertyKey] = value; + } + } + } + + return newScene; + }, + + /** + * Retrieves the key of a Scene from a Scene config. + * + * @method Phaser.Scenes.SceneManager#getKey + * @private + * @since 3.0.0 + * + * @param {string} key - The key to check in the Scene config. + * @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|function)} sceneConfig - The Scene config. + * + * @return {string} The Scene key. + */ + getKey: function (key, sceneConfig) + { + if (!key) { key = 'default'; } + + if (typeof sceneConfig === 'function') + { + return key; + } + else if (sceneConfig instanceof Scene) + { + key = sceneConfig.sys.settings.key; + } + else if (typeof sceneConfig === 'object' && sceneConfig.hasOwnProperty('key')) + { + key = sceneConfig.key; + } + + // By this point it's either 'default' or extracted from the Scene + + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } + else + { + return key; + } + }, + + /** + * Returns an array of all the current Scenes being managed by this Scene Manager. + * + * You can filter the output by the active state of the Scene and choose to have + * the array returned in normal or reversed order. + * + * @method Phaser.Scenes.SceneManager#getScenes + * @since 3.16.0 + * + * @param {boolean} [isActive=true] - Only include Scene's that are currently active? + * @param {boolean} [inReverse=false] - Return the array of Scenes in reverse? + * + * @return {Phaser.Scene[]} An array containing all of the Scenes in the Scene Manager. + */ + getScenes: function (isActive, inReverse) + { + if (isActive === undefined) { isActive = true; } + if (inReverse === undefined) { inReverse = false; } + + var out = []; + var scenes = this.scenes; + + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; + + if (scene && (!isActive || (isActive && scene.sys.isActive()))) + { + out.push(scene); + } + } + + return (inReverse) ? out.reverse() : out; + }, + + /** + * Retrieves a Scene. + * + * @method Phaser.Scenes.SceneManager#getScene + * @since 3.0.0 + * + * @param {string|Phaser.Scene} key - The Scene to retrieve. + * + * @return {?Phaser.Scene} The Scene. + */ + getScene: function (key) + { + if (typeof key === 'string') + { + if (this.keys[key]) + { + return this.keys[key]; + } + } + else + { + for (var i = 0; i < this.scenes.length; i++) + { + if (key === this.scenes[i]) + { + return key; + } + } + } + + return null; + }, + + /** + * Determines whether a Scene is running. + * + * @method Phaser.Scenes.SceneManager#isActive + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is running. + */ + isActive: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isActive(); + } + + return null; + }, + + /** + * Determines whether a Scene is paused. + * + * @method Phaser.Scenes.SceneManager#isPaused + * @since 3.17.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is paused. + */ + isPaused: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isPaused(); + } + + return null; + }, + + /** + * Determines whether a Scene is visible. + * + * @method Phaser.Scenes.SceneManager#isVisible + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is visible. + */ + isVisible: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isVisible(); + } + + return null; + }, + + /** + * Determines whether a Scene is sleeping. + * + * @method Phaser.Scenes.SceneManager#isSleeping + * @since 3.0.0 + * + * @param {string} key - The Scene to check. + * + * @return {boolean} Whether the Scene is sleeping. + */ + isSleeping: function (key) + { + var scene = this.getScene(key); + + if (scene) + { + return scene.sys.isSleeping(); + } + + return null; + }, + + /** + * Pauses the given Scene. + * + * @method Phaser.Scenes.SceneManager#pause + * @since 3.0.0 + * + * @param {string} key - The Scene to pause. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its pause event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + pause: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.pause(data); + } + + return this; + }, + + /** + * Resumes the given Scene. + * + * @method Phaser.Scenes.SceneManager#resume + * @since 3.0.0 + * + * @param {string} key - The Scene to resume. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its resume event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + resume: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.resume(data); + } + + return this; + }, + + /** + * Puts the given Scene to sleep. + * + * @method Phaser.Scenes.SceneManager#sleep + * @since 3.0.0 + * + * @param {string} key - The Scene to put to sleep. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its sleep event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + sleep: function (key, data) + { + var scene = this.getScene(key); + + if (scene && !scene.sys.isTransitioning()) + { + scene.sys.sleep(data); + } + + return this; + }, + + /** + * Awakens the given Scene. + * + * @method Phaser.Scenes.SceneManager#wake + * @since 3.0.0 + * + * @param {string} key - The Scene to wake up. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its wake event. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + wake: function (key, data) + { + var scene = this.getScene(key); + + if (scene) + { + scene.sys.wake(data); + } + + return this; + }, + + /** + * Runs the given Scene. + * + * If the given Scene is paused, it will resume it. If sleeping, it will wake it. + * If not running at all, it will be started. + * + * Use this if you wish to open a modal Scene by calling `pause` on the current + * Scene, then `run` on the modal Scene. + * + * @method Phaser.Scenes.SceneManager#run + * @since 3.10.0 + * + * @param {string} key - The Scene to run. + * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. + * + * @return {Phaser.Scenes.SceneManager} This Scene Manager. + */ + run: function (key, data) + { + var scene = this.getScene(key); + + if (!scene) + { + for (var i = 0; i < this._pending.length; i++) + { + if (this._pending[i].key === key) + { + this.queueOp('start', key, data); + break; + } + } + return this; + } + + if (scene.sys.isSleeping()) + { + // Sleeping? + scene.sys.wake(data); + } + else if (scene.sys.isPaused()) + { + // Paused? + scene.sys.resume(data); + } + else + { + // Not actually running? + this.start(key, data); + } + }, + + /** + * Starts the given Scene. + * + * @method Phaser.Scenes.SceneManager#start + * @since 3.0.0 + * + * @param {string} key - The Scene to start. + * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + start: function (key, data) + { + // If the Scene Manager is not running, then put the Scene into a holding pattern + if (!this.isBooted) + { + this._data[key] = { + autoStart: true, + data: data + }; + + return this; + } + + var scene = this.getScene(key); + + if (scene) + { + var sys = scene.sys; + + // If the Scene is already running (perhaps they called start from a launched sub-Scene?) + // then we close it down before starting it again. + if (sys.isActive() || sys.isPaused()) + { + sys.shutdown(); + + sys.sceneUpdate = NOOP; + + sys.start(data); + } + else + { + sys.sceneUpdate = NOOP; + + sys.start(data); + + var loader; + + if (sys.load) + { + loader = sys.load; + } + + // Files payload? + if (loader && sys.settings.hasOwnProperty('pack')) + { + loader.reset(); + + if (loader.addPack({ payload: sys.settings.pack })) + { + sys.settings.status = CONST.LOADING; + + loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); + + loader.start(); + + return this; + } + } + } + + this.bootScene(scene); + } + + return this; + }, + + /** + * Stops the given Scene. + * + * @method Phaser.Scenes.SceneManager#stop + * @since 3.0.0 + * + * @param {string} key - The Scene to stop. + * @param {object} [data] - Optional data object to pass to Scene.shutdown. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + stop: function (key, data) + { + var scene = this.getScene(key); + + if (scene && !scene.sys.isTransitioning()) + { + scene.sys.shutdown(data); + } + + return this; + }, + + /** + * Sleeps one one Scene and starts the other. + * + * @method Phaser.Scenes.SceneManager#switch + * @since 3.0.0 + * + * @param {string} from - The Scene to sleep. + * @param {string} to - The Scene to start. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + switch: function (from, to) + { + var sceneA = this.getScene(from); + var sceneB = this.getScene(to); + + if (sceneA && sceneB && sceneA !== sceneB) + { + this.sleep(from); + + if (this.isSleeping(to)) + { + this.wake(to); + } + else + { + this.start(to); + } + } + + return this; + }, + + /** + * Retrieves a Scene by numeric index. + * + * @method Phaser.Scenes.SceneManager#getAt + * @since 3.0.0 + * + * @param {number} index - The index of the Scene to retrieve. + * + * @return {(Phaser.Scene|undefined)} The Scene. + */ + getAt: function (index) + { + return this.scenes[index]; + }, + + /** + * Retrieves the numeric index of a Scene. + * + * @method Phaser.Scenes.SceneManager#getIndex + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The key of the Scene. + * + * @return {number} The index of the Scene. + */ + getIndex: function (key) + { + var scene = this.getScene(key); + + return this.scenes.indexOf(scene); + }, + + /** + * Brings a Scene to the top of the Scenes list. + * + * This means it will render above all other Scenes. + * + * @method Phaser.Scenes.SceneManager#bringToTop + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + bringToTop: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'bringToTop', keyA: key, keyB: null }); + } + else + { + var index = this.getIndex(key); + + if (index !== -1 && index < this.scenes.length) + { + var scene = this.getScene(key); + + this.scenes.splice(index, 1); + this.scenes.push(scene); + } + } + + return this; + }, + + /** + * Sends a Scene to the back of the Scenes list. + * + * This means it will render below all other Scenes. + * + * @method Phaser.Scenes.SceneManager#sendToBack + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + sendToBack: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); + } + else + { + var index = this.getIndex(key); + + if (index !== -1 && index > 0) + { + var scene = this.getScene(key); + + this.scenes.splice(index, 1); + this.scenes.unshift(scene); + } + } + + return this; + }, + + /** + * Moves a Scene down one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveDown + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveDown: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'moveDown', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); + + if (indexA > 0) + { + var indexB = indexA - 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); + + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } + + return this; + }, + + /** + * Moves a Scene up one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveUp + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveUp: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); + + if (indexA < this.scenes.length - 1) + { + var indexB = indexA + 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); + + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } + + return this; + }, + + /** + * Moves a Scene so it is immediately above another Scene in the Scenes list. + * + * This means it will render over the top of the other Scene. + * + * @method Phaser.Scenes.SceneManager#moveAbove + * @since 3.2.0 + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. + * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveAbove: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexB); + + // Remove + this.scenes.splice(indexB, 1); + + // Add in new location + this.scenes.splice(indexA + 1, 0, tempScene); + } + } + + return this; + }, + + /** + * Moves a Scene so it is immediately below another Scene in the Scenes list. + * + * This means it will render behind the other Scene. + * + * @method Phaser.Scenes.SceneManager#moveBelow + * @since 3.2.0 + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above. + * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + moveBelow: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'moveBelow', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexB); + + // Remove + this.scenes.splice(indexB, 1); + + if (indexA === 0) + { + this.scenes.unshift(tempScene); + } + else + { + // Add in new location + this.scenes.splice(indexA, 0, tempScene); + } + } + } + + return this; + }, + + /** + * Queue a Scene operation for the next update. + * + * @method Phaser.Scenes.SceneManager#queueOp + * @private + * @since 3.0.0 + * + * @param {string} op - The operation to perform. + * @param {(string|Phaser.Scene)} keyA - Scene A. + * @param {(any|string|Phaser.Scene)} [keyB] - Scene B, or a data object. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + queueOp: function (op, keyA, keyB) + { + this._queue.push({ op: op, keyA: keyA, keyB: keyB }); + + return this; + }, + + /** + * Swaps the positions of two Scenes in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#swapPosition + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. + * @param {(string|Phaser.Scene)} keyB - The second Scene to swap. + * + * @return {Phaser.Scenes.SceneManager} This SceneManager. + */ + swapPosition: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } + + if (this.isProcessing) + { + this._queue.push({ op: 'swapPosition', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); + + if (indexA !== indexB && indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexA); + + this.scenes[indexA] = this.scenes[indexB]; + this.scenes[indexB] = tempScene; + } + } + + return this; + }, + + /** + * Dumps debug information about each Scene to the developer console. + * + * @method Phaser.Scenes.SceneManager#dump + * @since 3.2.0 + */ + dump: function () + { + var out = []; + var map = [ 'pending', 'init', 'start', 'loading', 'creating', 'running', 'paused', 'sleeping', 'shutdown', 'destroyed' ]; + + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + var key = (sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED)) ? '[*] ' : '[-] '; + key += sys.settings.key + ' (' + map[sys.settings.status] + ')'; + + out.push(key); + } + + console.log(out.join('\n')); + }, + + /** + * Destroy the SceneManager and all of its Scene's systems. + * + * @method Phaser.Scenes.SceneManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; + + sys.destroy(); + } + + this.update = NOOP; + + this.scenes = []; + + this._pending = []; + this._start = []; + this._queue = []; + + this.game = null; + } + +}); + +module.exports = SceneManager; + + +/***/ }), +/* 412 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Systems = __webpack_require__(201); + +/** + * @classdesc + * A base Phaser.Scene class which can be extended for your own use. + * + * You can also define the optional methods {@link Phaser.Types.Scenes.SceneInitCallback init()}, {@link Phaser.Types.Scenes.ScenePreloadCallback preload()}, and {@link Phaser.Types.Scenes.SceneCreateCallback create()}. + * + * @class Scene + * @memberof Phaser + * @constructor + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. + */ +var Scene = new Class({ + + initialize: + + function Scene (config) + { + /** + * The Scene Systems. You must never overwrite this property, or all hell will break lose. + * + * @name Phaser.Scene#sys + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.sys = new Systems(this, config); + + /** + * A reference to the Phaser.Game instance. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game; + + /** + * A reference to the global Animation Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#anims + * @type {Phaser.Animations.AnimationManager} + * @since 3.0.0 + */ + this.anims; + + /** + * A reference to the global Cache. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#cache + * @type {Phaser.Cache.CacheManager} + * @since 3.0.0 + */ + this.cache; + + /** + * A reference to the game level Data Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#registry + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.registry; + + /** + * A reference to the Sound Manager. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#sound + * @type {Phaser.Sound.BaseSoundManager} + * @since 3.0.0 + */ + this.sound; + + /** + * A reference to the Texture Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#textures + * @type {Phaser.Textures.TextureManager} + * @since 3.0.0 + */ + this.textures; + + /** + * A scene level Event Emitter. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events; + + /** + * A scene level Camera System. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#cameras + * @type {Phaser.Cameras.Scene2D.CameraManager} + * @since 3.0.0 + */ + this.cameras; + + /** + * A scene level Game Object Factory. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#add + * @type {Phaser.GameObjects.GameObjectFactory} + * @since 3.0.0 + */ + this.add; + + /** + * A scene level Game Object Creator. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#make + * @type {Phaser.GameObjects.GameObjectCreator} + * @since 3.0.0 + */ + this.make; + + /** + * A reference to the Scene Manager Plugin. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#scene + * @type {Phaser.Scenes.ScenePlugin} + * @since 3.0.0 + */ + this.scene; + + /** + * A scene level Game Object Display List. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#children + * @type {Phaser.GameObjects.DisplayList} + * @since 3.0.0 + */ + this.children; + + /** + * A scene level Lights Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#lights + * @type {Phaser.GameObjects.LightsManager} + * @since 3.0.0 + */ + this.lights; + + /** + * A scene level Data Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#data + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.data; + + /** + * A scene level Input Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#input + * @type {Phaser.Input.InputPlugin} + * @since 3.0.0 + */ + this.input; + + /** + * A scene level Loader Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#load + * @type {Phaser.Loader.LoaderPlugin} + * @since 3.0.0 + */ + this.load; + + /** + * A scene level Time and Clock Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#time + * @type {Phaser.Time.Clock} + * @since 3.0.0 + */ + this.time; + + /** + * A scene level Tween Manager Plugin. + * This property will only be available if defined in the Scene Injection Map and the plugin is installed. + * + * @name Phaser.Scene#tweens + * @type {Phaser.Tweens.TweenManager} + * @since 3.0.0 + */ + this.tweens; + + /** + * A scene level Arcade Physics Plugin. + * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. + * + * @name Phaser.Scene#physics + * @type {Phaser.Physics.Arcade.ArcadePhysics} + * @since 3.0.0 + */ + this.physics; + + /** + * A scene level Matter Physics Plugin. + * This property will only be available if defined in the Scene Injection Map, the plugin is installed and configured. + * + * @name Phaser.Scene#matter + * @type {Phaser.Physics.Matter.MatterPhysics} + * @since 3.0.0 + */ + this.matter; + + if (false) + {} + + /** + * A reference to the global Scale Manager. + * This property will only be available if defined in the Scene Injection Map. + * + * @name Phaser.Scene#scale + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.2 + */ + this.scale; + + /** + * A reference to the Plugin Manager. + * + * The Plugin Manager is a global system that allows plugins to register themselves with it, and can then install + * those plugins into Scenes as required. + * + * @name Phaser.Scene#plugins + * @type {Phaser.Plugins.PluginManager} + * @since 3.0.0 + */ + this.plugins; + + /** + * A reference to the renderer instance Phaser is using, either Canvas or WebGL. + * + * @name Phaser.Scene#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.50.0 + */ + this.renderer; + }, + + /** + * Should be overridden by your own Scenes. + * This method is called once per game step while the scene is running. + * + * @method Phaser.Scene#update + * @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. + */ + update: function () + { + } + +}); + +module.exports = Scene; + + +/***/ }), +/* 413 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var UppercaseFirst = __webpack_require__(202); + +/** + * Builds an array of which physics plugins should be activated for the given Scene. + * + * @function Phaser.Scenes.GetPhysicsPlugins + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - The scene system to get the physics systems of. + * + * @return {array} An array of Physics systems to start for this Scene. + */ +var GetPhysicsPlugins = function (sys) +{ + var defaultSystem = sys.game.config.defaultPhysicsSystem; + var sceneSystems = GetFastValue(sys.settings, 'physics', false); + + if (!defaultSystem && !sceneSystems) + { + // No default physics system or systems in this scene + return; + } + + // Let's build the systems array + var output = []; + + if (defaultSystem) + { + output.push(UppercaseFirst(defaultSystem + 'Physics')); + } + + if (sceneSystems) + { + for (var key in sceneSystems) + { + key = UppercaseFirst(key.concat('Physics')); + + if (output.indexOf(key) === -1) + { + output.push(key); + } + } + } + + // An array of Physics systems to start for this Scene + return output; +}; + +module.exports = GetPhysicsPlugins; + + +/***/ }), +/* 414 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); + +/** + * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. + * + * @function Phaser.Scenes.GetScenePlugins + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems object to check for plugins. + * + * @return {array} An array of all plugins which should be activated, either the default ones or the ones configured in the Scene Systems object. + */ +var GetScenePlugins = function (sys) +{ + var defaultPlugins = sys.plugins.getDefaultScenePlugins(); + + var scenePlugins = GetFastValue(sys.settings, 'plugins', false); + + // Scene Plugins always override Default Plugins + if (Array.isArray(scenePlugins)) + { + return scenePlugins; + } + else if (defaultPlugins) + { + return defaultPlugins; + } + else + { + // No default plugins or plugins in this scene + return []; + } +}; + +module.exports = GetScenePlugins; + + +/***/ }), +/* 415 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(142); +var GetValue = __webpack_require__(6); +var Merge = __webpack_require__(143); +var InjectionMap = __webpack_require__(974); + +/** + * @namespace Phaser.Scenes.Settings + */ + +var Settings = { + + /** + * Takes a Scene configuration object and returns a fully formed System Settings object. + * + * @function Phaser.Scenes.Settings.create + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - The Scene configuration object used to create this Scene Settings. + * + * @return {Phaser.Types.Scenes.SettingsObject} The Scene Settings object created as a result of the config and default settings. + */ + create: function (config) + { + if (typeof config === 'string') + { + config = { key: config }; + } + else if (config === undefined) + { + // Pass the 'hasOwnProperty' checks + config = {}; + } + + return { + + status: CONST.PENDING, + + key: GetValue(config, 'key', ''), + active: GetValue(config, 'active', false), + visible: GetValue(config, 'visible', true), + + isBooted: false, + + isTransition: false, + transitionFrom: null, + transitionDuration: 0, + transitionAllowInput: true, + + // Loader payload array + + data: {}, + + pack: GetValue(config, 'pack', false), + + // Cameras + + cameras: GetValue(config, 'cameras', null), + + // Scene Property Injection Map + + map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), + + // Physics + + physics: GetValue(config, 'physics', {}), + + // Loader + + loader: GetValue(config, 'loader', {}), + + // Plugins + + plugins: GetValue(config, 'plugins', false), + + // Input + + input: GetValue(config, 'input', {}) + + }; + } + +}; + +module.exports = Settings; + + +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); +var CanvasTexture = __webpack_require__(417); +var Class = __webpack_require__(0); +var Color = __webpack_require__(36); +var CONST = __webpack_require__(39); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(103); +var GameEvents = __webpack_require__(22); +var GenerateTexture = __webpack_require__(382); +var GetValue = __webpack_require__(6); +var Parser = __webpack_require__(419); +var Texture = __webpack_require__(203); + +/** + * @callback EachTextureCallback + * + * @param {Phaser.Textures.Texture} texture - Each texture in Texture Manager. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ + +/** + * @classdesc + * Textures are managed by the global TextureManager. This is a singleton class that is + * responsible for creating and delivering Textures and their corresponding Frames to Game Objects. + * + * Sprites and other Game Objects get the texture data they need from the TextureManager. + * + * Access it via `scene.textures`. + * + * @class TextureManager + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Textures + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. + */ +var TextureManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function TextureManager (game) + { + EventEmitter.call(this); + + /** + * The Game that this TextureManager belongs to. + * + * @name Phaser.Textures.TextureManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + + /** + * The name of this manager. + * + * @name Phaser.Textures.TextureManager#name + * @type {string} + * @since 3.0.0 + */ + this.name = 'TextureManager'; + + /** + * An object that has all of textures that Texture Manager creates. + * Textures are assigned to keys so we can access to any texture that this object has directly by key value without iteration. + * + * @name Phaser.Textures.TextureManager#list + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.list = {}; + + /** + * The temporary canvas element to save an pixel data of an arbitrary texture in getPixel() and getPixelAlpha() method. + * + * @name Phaser.Textures.TextureManager#_tempCanvas + * @type {HTMLCanvasElement} + * @private + * @since 3.0.0 + */ + this._tempCanvas = CanvasPool.create2D(this, 1, 1); + + /** + * The context of the temporary canvas element made to save an pixel data in getPixel() and getPixelAlpha() method. + * + * @name Phaser.Textures.TextureManager#_tempContext + * @type {CanvasRenderingContext2D} + * @private + * @since 3.0.0 + */ + this._tempContext = this._tempCanvas.getContext('2d'); + + /** + * An counting value used for emitting 'ready' event after all of managers in game is loaded. + * + * @name Phaser.Textures.TextureManager#_pending + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._pending = 0; + + game.events.once(GameEvents.BOOT, this.boot, this); + }, + + /** + * The Boot Handler called by Phaser.Game when it first starts up. + * + * @method Phaser.Textures.TextureManager#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + this.on(Events.LOAD, this.updatePending, this); + this.on(Events.ERROR, this.updatePending, this); + + var config = this.game.config; + + this.addBase64('__DEFAULT', config.defaultImage); + this.addBase64('__MISSING', config.missingImage); + this.addBase64('__WHITE', config.whiteImage); + + this._pending = 3; + + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, + + /** + * After 'onload' or 'onerror' invoked twice, emit 'ready' event. + * + * @method Phaser.Textures.TextureManager#updatePending + * @private + * @since 3.0.0 + */ + updatePending: function () + { + this._pending--; + + if (this._pending === 0) + { + this.off(Events.LOAD); + this.off(Events.ERROR); + + this.emit(Events.READY); + } + }, + + /** + * Checks the given texture key and throws a console.warn if the key is already in use, then returns false. + * If you wish to avoid the console.warn then use `TextureManager.exists` instead. + * + * @method Phaser.Textures.TextureManager#checkKey + * @since 3.7.0 + * + * @param {string} key - The texture key to check. + * + * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. + */ + checkKey: function (key) + { + if (this.exists(key)) + { + // eslint-disable-next-line no-console + console.error('Texture key already in use: ' + key); + + return false; + } + + return true; + }, + + /** + * Removes a Texture from the Texture Manager and destroys it. This will immediately + * clear all references to it from the Texture Manager, and if it has one, destroy its + * WebGLTexture. This will emit a `removetexture` event. + * + * Note: If you have any Game Objects still using this texture they will start throwing + * errors the next time they try to render. Make sure that removing the texture is the final + * step when clearing down to avoid this. + * + * @method Phaser.Textures.TextureManager#remove + * @fires Phaser.Textures.Events#REMOVE + * @since 3.7.0 + * + * @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it. + * + * @return {Phaser.Textures.TextureManager} The Texture Manager. + */ + remove: function (key) + { + if (typeof key === 'string') + { + if (this.exists(key)) + { + key = this.get(key); + } + else + { + console.warn('No texture found matching key: ' + key); + return this; + } + } + + // By this point key should be a Texture, if not, the following fails anyway + if (this.list.hasOwnProperty(key.key)) + { + key.destroy(); + + this.emit(Events.REMOVE, key.key); + } + + return this; + }, + + /** + * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. + * + * @method Phaser.Textures.TextureManager#removeKey + * @since 3.17.0 + * + * @param {string} key - The key to remove from the texture list. + * + * @return {Phaser.Textures.TextureManager} The Texture Manager. + */ + removeKey: function (key) + { + if (this.list.hasOwnProperty(key)) + { + delete this.list[key]; + } + + return this; + }, + + /** + * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. + * + * It works by creating an `Image` DOM object, then setting the `src` attribute to + * the given base64 encoded data. As a result, the process is asynchronous by its nature, + * so be sure to listen for the events this method dispatches before using the texture. + * + * @method Phaser.Textures.TextureManager#addBase64 + * @fires Phaser.Textures.Events#ADD + * @fires Phaser.Textures.Events#ERROR + * @fires Phaser.Textures.Events#LOAD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {*} data - The Base64 encoded data. + * + * @return {this} This Texture Manager instance. + */ + addBase64: function (key, data) + { + if (this.checkKey(key)) + { + var _this = this; + + var image = new Image(); + + image.onerror = function () + { + _this.emit(Events.ERROR, key); + }; + + image.onload = function () + { + var texture = _this.create(key, image); + + Parser.Image(texture, 0); + + _this.emit(Events.ADD, key, texture); + + _this.emit(Events.LOAD, key, texture); + }; + + image.src = data; + } + + return this; + }, + + /** + * Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data. + * + * You can also provide the image type and encoder options. + * + * This will only work with bitmap based texture frames, such as those created from Texture Atlases. + * It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please + * see the WebGL Snapshot function instead. + * + * @method Phaser.Textures.TextureManager#getBase64 + * @since 3.12.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png. + * @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored. + * + * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. + */ + getBase64: function (key, frame, type, encoderOptions) + { + if (type === undefined) { type = 'image/png'; } + if (encoderOptions === undefined) { encoderOptions = 0.92; } + + var data = ''; + + var textureFrame = this.getFrame(key, frame); + + if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) + { + console.warn('Cannot getBase64 from WebGL Texture'); + } + else if (textureFrame) + { + var cd = textureFrame.canvasData; + + var canvas = CanvasPool.create2D(this, cd.width, cd.height); + var ctx = canvas.getContext('2d'); + + ctx.drawImage( + textureFrame.source.image, + cd.x, + cd.y, + cd.width, + cd.height, + 0, + 0, + cd.width, + cd.height + ); + + data = canvas.toDataURL(type, encoderOptions); + + CanvasPool.remove(canvas); + } + + return data; + }, + + /** + * Adds a new Texture to the Texture Manager created from the given Image element. + * + * @method Phaser.Textures.TextureManager#addImage + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addImage: function (key, source, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.Image(texture, 0); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Takes a WebGL Texture and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. + * + * This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites. + * + * If the `width` and `height` arguments are omitted, but the WebGL Texture was created by Phaser's WebGL Renderer + * and has `glTexture.width` and `glTexture.height` properties, these values will be used instead. + * + * This is a WebGL only feature. + * + * @method Phaser.Textures.TextureManager#addGLTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.19.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {WebGLTexture} glTexture - The source Render Texture. + * @param {number} [width] - The new width of the Texture. Read from `glTexture.width` if omitted. + * @param {number} [height] - The new height of the Texture. Read from `glTexture.height` if omitted. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addGLTexture: function (key, glTexture, width, height) + { + var texture = null; + + if (this.checkKey(key)) + { + if (width === undefined) { width = glTexture.width; } + if (height === undefined) { height = glTexture.height; } + + texture = this.create(key, glTexture, width, height); + + texture.add('__BASE', 0, 0, 0, width, height); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Render Texture to the Texture Manager using the given key. + * This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites. + * + * @method Phaser.Textures.TextureManager#addRenderTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.12.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addRenderTexture: function (key, renderTexture) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, renderTexture); + + texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Creates a new Texture using the given config values. + * + * Generated textures consist of a Canvas element to which the texture data is drawn. + * + * Generates a texture based on the given Create configuration object. + * + * The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the + * data cells map to a single color. For example, if the texture config looked like this: + * + * ```javascript + * var star = [ + * '.....828.....', + * '....72227....', + * '....82228....', + * '...7222227...', + * '2222222222222', + * '8222222222228', + * '.72222222227.', + * '..787777787..', + * '..877777778..', + * '.78778887787.', + * '.27887.78872.', + * '.787.....787.' + * ]; + * + * this.textures.generate('star', { data: star, pixelWidth: 4 }); + * ``` + * + * Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array + * represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color + * number 8 in the palette. If a cell contains a period character `.` then it is transparent. + * + * The default palette is Arne16, but you can specify your own using the `palette` property. + * + * @method Phaser.Textures.TextureManager#generate + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.Types.Create.GenerateTextureConfig} config - The configuration object needed to generate the texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + generate: function (key, config) + { + if (this.checkKey(key)) + { + var canvas = CanvasPool.create(this, 1, 1); + + config.canvas = canvas; + + GenerateTexture(config); + + return this.addCanvas(key, canvas); + } + else + { + return null; + } + }, + + /** + * Creates a new Texture using a blank Canvas element of the size given. + * + * Canvas elements are automatically pooled and calling this method will + * extract a free canvas from the CanvasPool, or create one if none are available. + * + * @method Phaser.Textures.TextureManager#createCanvas + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {number} [width=256] - The width of the Canvas element. + * @param {number} [height=256] - The height of the Canvas element. + * + * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. + */ + createCanvas: function (key, width, height) + { + if (width === undefined) { width = 256; } + if (height === undefined) { height = 256; } + + if (this.checkKey(key)) + { + var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); + + return this.addCanvas(key, canvas); + } + + return null; + }, + + /** + * Creates a new Canvas Texture object from an existing Canvas element + * and adds it to this Texture Manager, unless `skipCache` is true. + * + * @method Phaser.Textures.TextureManager#addCanvas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture. + * @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache? + * + * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. + */ + addCanvas: function (key, source, skipCache) + { + if (skipCache === undefined) { skipCache = false; } + + var texture = null; + + if (skipCache) + { + texture = new CanvasTexture(this, key, source, source.width, source.height); + } + else if (this.checkKey(key)) + { + texture = new CanvasTexture(this, key, source, source.width, source.height); + + this.list[key] = texture; + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a new Texture Atlas to this Texture Manager. + * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. + * + * @method Phaser.Textures.TextureManager#addAtlas + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlas: function (key, source, data, dataSource) + { + // New Texture Packer format? + if (Array.isArray(data.textures) || Array.isArray(data.frames)) + { + return this.addAtlasJSONArray(key, source, data, dataSource); + } + else + { + return this.addAtlasJSONHash(key, source, data, dataSource); + } + }, + + /** + * Adds a Texture Atlas to this Texture Manager. + * The frame data of the atlas must be stored in an Array within the JSON. + * This is known as a JSON Array in software such as Texture Packer. + * + * @method Phaser.Textures.TextureManager#addAtlasJSONArray + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|HTMLImageElement[])} source - The source Image element/s. + * @param {(object|object[])} data - The Texture Atlas data/s. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasJSONArray: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + // Multi-Atlas? + if (Array.isArray(data)) + { + var singleAtlasFile = (data.length === 1); // multi-pack with one atlas file for all images + + // !! Assumes the textures are in the same order in the source array as in the json data !! + for (var i = 0; i < texture.source.length; i++) + { + var atlasData = singleAtlasFile ? data[0] : data[i]; + + Parser.JSONArray(texture, i, atlasData); + } + } + else + { + Parser.JSONArray(texture, 0, data); + } + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Texture Atlas to this Texture Manager. + * The frame data of the atlas must be stored in an Object within the JSON. + * This is known as a JSON Hash in software such as Texture Packer. + * + * @method Phaser.Textures.TextureManager#addAtlasJSONHash + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasJSONHash: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + if (Array.isArray(data)) + { + for (var i = 0; i < data.length; i++) + { + Parser.JSONHash(texture, i, data[i]); + } + } + else + { + Parser.JSONHash(texture, 0, data); + } + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Texture Atlas to this Texture Manager, where the atlas data is given + * in the XML format. + * + * @method Phaser.Textures.TextureManager#addAtlasXML + * @fires Phaser.Textures.Events#ADD + * @since 3.7.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas XML data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addAtlasXML: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.AtlasXML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Unity Texture Atlas to this Texture Manager. + * The data must be in the form of a Unity YAML file. + * + * @method Phaser.Textures.TextureManager#addUnityAtlas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {object} data - The Texture Atlas data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addUnityAtlas: function (key, source, data, dataSource) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + Parser.UnityYAML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Sprite Sheet to this Texture Manager. + * + * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact + * same size and cannot be trimmed or rotated. + * + * @method Phaser.Textures.TextureManager#addSpriteSheet + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addSpriteSheet: function (key, source, config) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = this.create(key, source); + + var width = texture.source[0].width; + var height = texture.source[0].height; + + Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); + + this.emit(Events.ADD, key, texture); + } + + return texture; + }, + + /** + * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. + * + * In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact + * same size and cannot be trimmed or rotated. + * + * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addSpriteSheetFromAtlas: function (key, config) + { + if (!this.checkKey(key)) + { + return null; + } + + var atlasKey = GetValue(config, 'atlas', null); + var atlasFrame = GetValue(config, 'frame', null); + + if (!atlasKey || !atlasFrame) + { + return; + } + + var atlas = this.get(atlasKey); + var sheet = atlas.get(atlasFrame); + + if (sheet) + { + var texture = this.create(key, sheet.source.image); + + if (sheet.trimmed) + { + // If trimmed we need to help the parser adjust + Parser.SpriteSheetFromAtlas(texture, sheet, config); + } + else + { + Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); + } + + this.emit(Events.ADD, key, texture); + + return texture; + } + }, + + /** + * Creates a new Texture using the given source and dimensions. + * + * @method Phaser.Textures.TextureManager#create + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {HTMLImageElement} source - The source Image element. + * @param {number} width - The width of the Texture. + * @param {number} height - The height of the Texture. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + create: function (key, source, width, height) + { + var texture = null; + + if (this.checkKey(key)) + { + texture = new Texture(this, key, source, width, height); + + this.list[key] = texture; + } + + return texture; + }, + + /** + * Checks the given key to see if a Texture using it exists within this Texture Manager. + * + * @method Phaser.Textures.TextureManager#exists + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * + * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. + */ + exists: function (key) + { + return (this.list.hasOwnProperty(key)); + }, + + /** + * Returns a Texture from the Texture Manager that matches the given key. + * + * If the key is `undefined` it will return the `__DEFAULT` Texture. + * + * If the key is an instance of a Texture, it will return the key directly. + * + * Finally. if the key is given, but not found and not a Texture instance, it will return the `__MISSING` Texture. + * + * @method Phaser.Textures.TextureManager#get + * @since 3.0.0 + * + * @param {(string|Phaser.Textures.Texture)} key - The unique string-based key of the Texture, or a Texture instance. + * + * @return {Phaser.Textures.Texture} The Texture that was created. + */ + get: function (key) + { + if (key === undefined) { key = '__DEFAULT'; } + + if (this.list[key]) + { + return this.list[key]; + } + else if (key instanceof Texture) + { + return key; + } + else + { + return this.list['__MISSING']; + } + }, + + /** + * Takes a Texture key and Frame name and returns a clone of that Frame if found. + * + * @method Phaser.Textures.TextureManager#cloneFrame + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} frame - The string or index of the Frame to be cloned. + * + * @return {Phaser.Textures.Frame} A Clone of the given Frame. + */ + cloneFrame: function (key, frame) + { + if (this.list[key]) + { + return this.list[key].get(frame).clone(); + } + }, + + /** + * Takes a Texture key and Frame name and returns a reference to that Frame, if found. + * + * @method Phaser.Textures.TextureManager#getFrame + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * + * @return {Phaser.Textures.Frame} A Texture Frame object. + */ + getFrame: function (key, frame) + { + if (this.list[key]) + { + return this.list[key].get(frame); + } + }, + + /** + * Returns an array with all of the keys of all Textures in this Texture Manager. + * The output array will exclude the `__DEFAULT` and `__MISSING` keys. + * + * @method Phaser.Textures.TextureManager#getTextureKeys + * @since 3.0.0 + * + * @return {string[]} An array containing all of the Texture keys stored in this Texture Manager. + */ + getTextureKeys: function () + { + var output = []; + + for (var key in this.list) + { + if (key !== '__DEFAULT' && key !== '__MISSING') + { + output.push(key); + } + } + + return output; + }, + + /** + * Given a Texture and an `x` and `y` coordinate this method will return a new + * Color object that has been populated with the color and alpha values of the pixel + * at that location in the Texture. + * + * @method Phaser.Textures.TextureManager#getPixel + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the pixel within the Texture. + * @param {number} y - The y coordinate of the pixel within the Texture. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {?Phaser.Display.Color} A Color object populated with the color values of the requested pixel, + * or `null` if the coordinates were out of bounds. + */ + getPixel: function (x, y, key, frame) + { + var textureFrame = this.getFrame(key, frame); + + if (textureFrame) + { + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; + + var data = textureFrame.data.cut; + + x += data.x; + y += data.y; + + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; + + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); + + var rgb = ctx.getImageData(0, 0, 1, 1); + + return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); + } + } + + return null; + }, + + /** + * Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255 + * corresponding to the alpha value of the pixel at that location in the Texture. If the coordinate + * is out of bounds it will return null. + * + * @method Phaser.Textures.TextureManager#getPixelAlpha + * @since 3.10.0 + * + * @param {number} x - The x coordinate of the pixel within the Texture. + * @param {number} y - The y coordinate of the pixel within the Texture. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds. + */ + getPixelAlpha: function (x, y, key, frame) + { + var textureFrame = this.getFrame(key, frame); + + if (textureFrame) + { + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; + + var data = textureFrame.data.cut; + + x += data.x; + y += data.y; + + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; + + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); + + var rgb = ctx.getImageData(0, 0, 1, 1); + + return rgb.data[3]; + } + } + + return null; + }, + + /** + * Sets the given Game Objects `texture` and `frame` properties so that it uses + * the Texture and Frame specified in the `key` and `frame` arguments to this method. + * + * @method Phaser.Textures.TextureManager#setTexture + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the texture would be set on. + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string or index of the Frame. + * + * @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on. + */ + setTexture: function (gameObject, key, frame) + { + if (this.list[key]) + { + gameObject.texture = this.list[key]; + gameObject.frame = gameObject.texture.get(frame); + } + + return gameObject; + }, + + /** + * Changes the key being used by a Texture to the new key provided. + * + * The old key is removed, allowing it to be re-used. + * + * Game Objects are linked to Textures by a reference to the Texture object, so + * all existing references will be retained. + * + * @method Phaser.Textures.TextureManager#renameTexture + * @since 3.12.0 + * + * @param {string} currentKey - The current string-based key of the Texture you wish to rename. + * @param {string} newKey - The new unique string-based key to use for the Texture. + * + * @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`. + */ + renameTexture: function (currentKey, newKey) + { + var texture = this.get(currentKey); + + if (texture && currentKey !== newKey) + { + texture.key = newKey; + + this.list[newKey] = texture; + + delete this.list[currentKey]; + + return true; + } + + return false; + }, + + /** + * Passes all Textures to the given callback. + * + * @method Phaser.Textures.TextureManager#each + * @since 3.0.0 + * + * @param {EachTextureCallback} callback - The callback function to be sent the Textures. + * @param {object} scope - The value to use as `this` when executing the callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ + each: function (callback, scope) + { + var args = [ null ]; + + for (var i = 1; i < arguments.length; i++) + { + args.push(arguments[i]); + } + + for (var texture in this.list) + { + args[0] = this.list[texture]; + + callback.apply(scope, args); + } + }, + + /** + * Destroys the Texture Manager and all Textures stored within it. + * + * @method Phaser.Textures.TextureManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var texture in this.list) + { + this.list[texture].destroy(); + } + + this.list = {}; + + this.game = null; + + CanvasPool.remove(this._tempCanvas); + } + +}); + +module.exports = TextureManager; + + +/***/ }), +/* 417 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Clamp = __webpack_require__(18); +var Color = __webpack_require__(36); +var CONST = __webpack_require__(39); +var IsSizePowerOfTwo = __webpack_require__(136); +var Texture = __webpack_require__(203); + +/** + * @classdesc + * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. + * + * You can use the properties of this texture to draw to the canvas element directly, using all of the standard + * canvas operations available in the browser. Any Game Object can be given this texture and will render with it. + * + * Note: When running under WebGL the Canvas Texture needs to re-generate its base WebGLTexture and reupload it to + * the GPU every time you modify it, otherwise the changes you make to this texture will not be visible. To do this + * you should call `CanvasTexture.refresh()` once you are finished with your changes to the canvas. Try and keep + * this to a minimum, especially on large canvas sizes, or you may inadvertently thrash the GPU by constantly uploading + * texture data to it. This restriction does not apply if using the Canvas Renderer. + * + * It starts with only one frame that covers the whole of the canvas. You can add further frames, that specify + * sections of the canvas using the `add` method. + * + * Should you need to resize the canvas use the `setSize` method so that it accurately updates all of the underlying + * texture data as well. Forgetting to do this (i.e. by changing the canvas size directly from your code) could cause + * graphical errors. + * + * @class CanvasTexture + * @extends Phaser.Textures.Texture + * @memberof Phaser.Textures + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Textures.TextureManager} manager - A reference to the Texture Manager this Texture belongs to. + * @param {string} key - The unique string-based key of this Texture. + * @param {HTMLCanvasElement} source - The canvas element that is used as the base of this texture. + * @param {number} width - The width of the canvas. + * @param {number} height - The height of the canvas. + */ +var CanvasTexture = new Class({ + + Extends: Texture, + + initialize: + + function CanvasTexture (manager, key, source, width, height) + { + Texture.call(this, manager, key, source, width, height); + + this.add('__BASE', 0, 0, 0, width, height); + + /** + * A reference to the Texture Source of this Canvas. + * + * @name Phaser.Textures.CanvasTexture#_source + * @type {Phaser.Textures.TextureSource} + * @private + * @since 3.7.0 + */ + this._source = this.frames['__BASE'].source; + + /** + * The source Canvas Element. + * + * @name Phaser.Textures.CanvasTexture#canvas + * @readonly + * @type {HTMLCanvasElement} + * @since 3.7.0 + */ + this.canvas = this._source.image; + + /** + * The 2D Canvas Rendering Context. + * + * @name Phaser.Textures.CanvasTexture#context + * @readonly + * @type {CanvasRenderingContext2D} + * @since 3.7.0 + */ + this.context = this.canvas.getContext('2d'); + + /** + * The width of the Canvas. + * This property is read-only, if you wish to change it use the `setSize` method. + * + * @name Phaser.Textures.CanvasTexture#width + * @readonly + * @type {number} + * @since 3.7.0 + */ + this.width = width; + + /** + * The height of the Canvas. + * This property is read-only, if you wish to change it use the `setSize` method. + * + * @name Phaser.Textures.CanvasTexture#height + * @readonly + * @type {number} + * @since 3.7.0 + */ + this.height = height; + + /** + * The context image data. + * Use the `update` method to populate this when the canvas changes. + * + * @name Phaser.Textures.CanvasTexture#imageData + * @type {ImageData} + * @since 3.13.0 + */ + this.imageData = this.context.getImageData(0, 0, width, height); + + /** + * A Uint8ClampedArray view into the `buffer`. + * Use the `update` method to populate this when the canvas changes. + * Note that this is unavailable in some browsers, such as Epic Browser, due to their security restrictions. + * + * @name Phaser.Textures.CanvasTexture#data + * @type {Uint8ClampedArray} + * @since 3.13.0 + */ + this.data = null; + + if (this.imageData) + { + this.data = this.imageData.data; + } + + /** + * An Uint32Array view into the `buffer`. + * + * @name Phaser.Textures.CanvasTexture#pixels + * @type {Uint32Array} + * @since 3.13.0 + */ + this.pixels = null; + + /** + * An ArrayBuffer the same size as the context ImageData. + * + * @name Phaser.Textures.CanvasTexture#buffer + * @type {ArrayBuffer} + * @since 3.13.0 + */ + this.buffer; + + if (this.data) + { + if (this.imageData.data.buffer) + { + this.buffer = this.imageData.data.buffer; + this.pixels = new Uint32Array(this.buffer); + } + else if (window.ArrayBuffer) + { + this.buffer = new ArrayBuffer(this.imageData.data.length); + this.pixels = new Uint32Array(this.buffer); + } + else + { + this.pixels = this.imageData.data; + } + } + }, + + /** + * This re-creates the `imageData` from the current context. + * It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array. + * + * Warning: This is a very expensive operation, so use it sparingly. + * + * @method Phaser.Textures.CanvasTexture#update + * @since 3.13.0 + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + update: function () + { + this.imageData = this.context.getImageData(0, 0, this.width, this.height); + + this.data = this.imageData.data; + + if (this.imageData.data.buffer) + { + this.buffer = this.imageData.data.buffer; + this.pixels = new Uint32Array(this.buffer); + } + else if (window.ArrayBuffer) + { + this.buffer = new ArrayBuffer(this.imageData.data.length); + this.pixels = new Uint32Array(this.buffer); + } + else + { + this.pixels = this.imageData.data; + } + + if (this.manager.game.config.renderType === CONST.WEBGL) + { + this.refresh(); + } + + return this; + }, + + /** + * Draws the given Image or Canvas element to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. + * + * @method Phaser.Textures.CanvasTexture#draw + * @since 3.13.0 + * + * @param {number} x - The x coordinate to draw the source at. + * @param {number} y - The y coordinate to draw the source at. + * @param {(HTMLImageElement|HTMLCanvasElement)} source - The element to draw to this canvas. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + draw: function (x, y, source) + { + this.context.drawImage(source, x, y); + + return this.update(); + }, + + /** + * Draws the given texture frame to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. + * + * @method Phaser.Textures.CanvasTexture#drawFrame + * @since 3.16.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture. + * @param {number} [x=0] - The x coordinate to draw the source at. + * @param {number} [y=0] - The y coordinate to draw the source at. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + drawFrame: function (key, frame, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + var textureFrame = this.manager.getFrame(key, frame); + + if (textureFrame) + { + var cd = textureFrame.canvasData; + + var width = textureFrame.cutWidth; + var height = textureFrame.cutHeight; + var res = textureFrame.source.resolution; + + this.context.drawImage( + textureFrame.source.image, + cd.x, cd.y, + width, + height, + x, y, + width / res, + height / res + ); + + return this.update(); + } + else + { + return this; + } + }, + + /** + * Sets a pixel in the CanvasTexture to the given color and alpha values. + * + * This is an expensive operation to run in large quantities, so use sparingly. + * + * @method Phaser.Textures.CanvasTexture#setPixel + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} red - The red color value. A number between 0 and 255. + * @param {number} green - The green color value. A number between 0 and 255. + * @param {number} blue - The blue color value. A number between 0 and 255. + * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. + * + * @return {this} This CanvasTexture. + */ + setPixel: function (x, y, red, green, blue, alpha) + { + if (alpha === undefined) { alpha = 255; } + + x = Math.abs(Math.floor(x)); + y = Math.abs(Math.floor(y)); + + var index = this.getIndex(x, y); + + if (index > -1) + { + var imageData = this.context.getImageData(x, y, 1, 1); + + imageData.data[0] = red; + imageData.data[1] = green; + imageData.data[2] = blue; + imageData.data[3] = alpha; + + this.context.putImageData(imageData, x, y); + } + + return this; + }, + + /** + * Puts the ImageData into the context of this CanvasTexture at the given coordinates. + * + * @method Phaser.Textures.CanvasTexture#putData + * @since 3.16.0 + * + * @param {ImageData} imageData - The ImageData to put at the given location. + * @param {number} x - The x coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [dirtyX=0] - Horizontal position (x coordinate) of the top-left corner from which the image data will be extracted. + * @param {number} [dirtyY=0] - Vertical position (x coordinate) of the top-left corner from which the image data will be extracted. + * @param {number} [dirtyWidth] - Width of the rectangle to be painted. Defaults to the width of the image data. + * @param {number} [dirtyHeight] - Height of the rectangle to be painted. Defaults to the height of the image data. + * + * @return {this} This CanvasTexture. + */ + putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + { + if (dirtyX === undefined) { dirtyX = 0; } + if (dirtyY === undefined) { dirtyY = 0; } + if (dirtyWidth === undefined) { dirtyWidth = imageData.width; } + if (dirtyHeight === undefined) { dirtyHeight = imageData.height; } + + this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight); + + return this; + }, + + /** + * Gets an ImageData region from this CanvasTexture from the position and size specified. + * You can write this back using `CanvasTexture.putData`, or manipulate it. + * + * @method Phaser.Textures.CanvasTexture#getData + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} width - The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left. + * @param {number} height - The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up. + * + * @return {ImageData} The ImageData extracted from this CanvasTexture. + */ + getData: function (x, y, width, height) + { + x = Clamp(Math.floor(x), 0, this.width - 1); + y = Clamp(Math.floor(y), 0, this.height - 1); + width = Clamp(width, 1, this.width - x); + height = Clamp(height, 1, this.height - y); + + var imageData = this.context.getImageData(x, y, width, height); + + return imageData; + }, + + /** + * Get the color of a specific pixel from this texture and store it in a Color object. + * + * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, + * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. + * + * @method Phaser.Textures.CanvasTexture#getPixel + * @since 3.13.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {Phaser.Display.Color} [out] - A Color object to store the pixel values in. If not provided a new Color object will be created. + * + * @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties. + */ + getPixel: function (x, y, out) + { + if (!out) + { + out = new Color(); + } + + var index = this.getIndex(x, y); + + if (index > -1) + { + var data = this.data; + + var r = data[index + 0]; + var g = data[index + 1]; + var b = data[index + 2]; + var a = data[index + 3]; + + out.setTo(r, g, b, a); + } + + return out; + }, + + /** + * Returns an array containing all of the pixels in the given region. + * + * If the requested region extends outside the bounds of this CanvasTexture, + * the region is truncated to fit. + * + * If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer, + * otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist. + * + * @method Phaser.Textures.CanvasTexture#getPixels + * @since 3.16.0 + * + * @param {number} [x=0] - The x coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [y=0] - The y coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} [width] - The width of the region to get. Must be an integer. Defaults to the canvas width if not given. + * @param {number} [height] - The height of the region to get. Must be an integer. If not given will be set to the `width`. + * + * @return {Phaser.Types.Textures.PixelConfig[][]} A 2d array of Pixel objects. + */ + getPixels: function (x, y, width, height) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = width; } + + x = Math.abs(Math.round(x)); + y = Math.abs(Math.round(y)); + + var left = Clamp(x, 0, this.width); + var right = Clamp(x + width, 0, this.width); + var top = Clamp(y, 0, this.height); + var bottom = Clamp(y + height, 0, this.height); + + var pixel = new Color(); + + var out = []; + + for (var py = top; py < bottom; py++) + { + var row = []; + + for (var px = left; px < right; px++) + { + pixel = this.getPixel(px, py, pixel); + + row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); + } + + out.push(row); + } + + return out; + }, + + /** + * Returns the Image Data index for the given pixel in this CanvasTexture. + * + * The index can be used to read directly from the `this.data` array. + * + * The index points to the red value in the array. The subsequent 3 indexes + * point to green, blue and alpha respectively. + * + * @method Phaser.Textures.CanvasTexture#getIndex + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer. + * + * @return {number} + */ + getIndex: function (x, y) + { + x = Math.abs(Math.round(x)); + y = Math.abs(Math.round(y)); + + if (x < this.width && y < this.height) + { + return (x + y * this.width) * 4; + } + else + { + return -1; + } + }, + + /** + * This should be called manually if you are running under WebGL. + * It will refresh the WebGLTexture from the Canvas source. Only call this if you know that the + * canvas has changed, as there is a significant GPU texture allocation cost involved in doing so. + * + * @method Phaser.Textures.CanvasTexture#refresh + * @since 3.7.0 + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + */ + refresh: function () + { + this._source.update(); + + return this; + }, + + /** + * Gets the Canvas Element. + * + * @method Phaser.Textures.CanvasTexture#getCanvas + * @since 3.7.0 + * + * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. + */ + getCanvas: function () + { + return this.canvas; + }, + + /** + * Gets the 2D Canvas Rendering Context. + * + * @method Phaser.Textures.CanvasTexture#getContext + * @since 3.7.0 + * + * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. + */ + getContext: function () + { + return this.context; + }, + + /** + * Clears the given region of this Canvas Texture, resetting it back to transparent. + * If no region is given, the whole Canvas Texture is cleared. + * + * @method Phaser.Textures.CanvasTexture#clear + * @since 3.7.0 + * + * @param {number} [x=0] - The x coordinate of the top-left of the region to clear. + * @param {number} [y=0] - The y coordinate of the top-left of the region to clear. + * @param {number} [width] - The width of the region. + * @param {number} [height] - The height of the region. + * + * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + */ + clear: function (x, y, width, height) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + + this.context.clearRect(x, y, width, height); + + return this.update(); + }, + + /** + * Changes the size of this Canvas Texture. + * + * @method Phaser.Textures.CanvasTexture#setSize + * @since 3.7.0 + * + * @param {number} width - The new width of the Canvas. + * @param {number} [height] - The new height of the Canvas. If not given it will use the width as the height. + * + * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + */ + setSize: function (width, height) + { + if (height === undefined) { height = width; } + + if (width !== this.width || height !== this.height) + { + // Update the Canvas + this.canvas.width = width; + this.canvas.height = height; + + // Update the Texture Source + this._source.width = width; + this._source.height = height; + this._source.isPowerOf2 = IsSizePowerOfTwo(width, height); + + // Update the Frame + this.frames['__BASE'].setSize(width, height, 0, 0); + + // Update this + this.width = width; + this.height = height; + + this.refresh(); + } + + return this; + }, + + /** + * Destroys this Texture and releases references to its sources and frames. + * + * @method Phaser.Textures.CanvasTexture#destroy + * @since 3.16.0 + */ + destroy: function () + { + Texture.prototype.destroy.call(this); + + this._source = null; + this.canvas = null; + this.context = null; + this.imageData = null; + this.data = null; + this.pixels = null; + this.buffer = null; + } + +}); + +module.exports = CanvasTexture; + + +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); +var Class = __webpack_require__(0); +var IsSizePowerOfTwo = __webpack_require__(136); +var ScaleModes = __webpack_require__(164); + +/** + * @classdesc + * A Texture Source is the encapsulation of the actual source data for a Texture. + * + * This is typically an Image Element, loaded from the file system or network, a Canvas Element or a Video Element. + * + * A Texture can contain multiple Texture Sources, which only happens when a multi-atlas is loaded. + * + * @class TextureSource + * @memberof Phaser.Textures + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Textures.Texture} texture - The Texture this TextureSource belongs to. + * @param {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} source - The source image data. + * @param {number} [width] - Optional width of the source image. If not given it's derived from the source itself. + * @param {number} [height] - Optional height of the source image. If not given it's derived from the source itself. + * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + */ +var TextureSource = new Class({ + + initialize: + + function TextureSource (texture, source, width, height, flipY) + { + if (flipY === undefined) { flipY = false; } + + var game = texture.manager.game; + + /** + * The Texture this TextureSource belongs to. + * + * @name Phaser.Textures.TextureSource#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.7.0 + */ + this.renderer = game.renderer; + + /** + * The Texture this TextureSource belongs to. + * + * @name Phaser.Textures.TextureSource#texture + * @type {Phaser.Textures.Texture} + * @since 3.0.0 + */ + this.texture = texture; + + /** + * The source of the image data. + * + * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. + * + * @name Phaser.Textures.TextureSource#source + * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} + * @since 3.12.0 + */ + this.source = source; + + /** + * The image data. + * + * This is either an Image element, Canvas element or a Video Element. + * + * @name Phaser.Textures.TextureSource#image + * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} + * @since 3.0.0 + */ + this.image = source; + + /** + * Currently un-used. + * + * @name Phaser.Textures.TextureSource#compressionAlgorithm + * @type {number} + * @default null + * @since 3.0.0 + */ + this.compressionAlgorithm = null; + + /** + * The resolution of the source image. + * + * @name Phaser.Textures.TextureSource#resolution + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.resolution = 1; + + /** + * The width of the source image. If not specified in the constructor it will check + * the `naturalWidth` and then `width` properties of the source image. + * + * @name Phaser.Textures.TextureSource#width + * @type {number} + * @since 3.0.0 + */ + this.width = width || source.naturalWidth || source.videoWidth || source.width || 0; + + /** + * The height of the source image. If not specified in the constructor it will check + * the `naturalHeight` and then `height` properties of the source image. + * + * @name Phaser.Textures.TextureSource#height + * @type {number} + * @since 3.0.0 + */ + this.height = height || source.naturalHeight || source.videoHeight || source.height || 0; + + /** + * The Scale Mode the image will use when rendering. + * Either Linear or Nearest. + * + * @name Phaser.Textures.TextureSource#scaleMode + * @type {number} + * @since 3.0.0 + */ + this.scaleMode = ScaleModes.DEFAULT; + + /** + * Is the source image a Canvas Element? + * + * @name Phaser.Textures.TextureSource#isCanvas + * @type {boolean} + * @since 3.0.0 + */ + this.isCanvas = (source instanceof HTMLCanvasElement); + + /** + * Is the source image a Video Element? + * + * @name Phaser.Textures.TextureSource#isVideo + * @type {boolean} + * @since 3.20.0 + */ + this.isVideo = (window.hasOwnProperty('HTMLVideoElement') && source instanceof HTMLVideoElement); + + /** + * Is the source image a Render Texture? + * + * @name Phaser.Textures.TextureSource#isRenderTexture + * @type {boolean} + * @since 3.12.0 + */ + this.isRenderTexture = (source.type === 'RenderTexture'); + + /** + * Is the source image a WebGLTexture? + * + * @name Phaser.Textures.TextureSource#isGLTexture + * @type {boolean} + * @since 3.19.0 + */ + this.isGLTexture = (window.hasOwnProperty('WebGLTexture') && source instanceof WebGLTexture); + + /** + * Are the source image dimensions a power of two? + * + * @name Phaser.Textures.TextureSource#isPowerOf2 + * @type {boolean} + * @since 3.0.0 + */ + this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height); + + /** + * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture + * already, then this is a reference to that WebGLTexture. + * + * @name Phaser.Textures.TextureSource#glTexture + * @type {?WebGLTexture} + * @default null + * @since 3.0.0 + */ + this.glTexture = null; + + /** + * The current texture unit index as assigned by the WebGL Renderer. + * Un-used in canvas. Should be treated as read-only. + * + * @name Phaser.Textures.TextureSource#glIndex + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.glIndex = 0; + + /** + * The counter value when this texture was last assigned an index by the WebGL Renderer. + * Un-used in canvas. Should be treated as read-only. + * + * @name Phaser.Textures.TextureSource#glIndexCounter + * @type {number} + * @default -1 + * @since 3.50.0 + */ + this.glIndexCounter = -1; + + /** + * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + * + * @name Phaser.Textures.TextureSource#flipY + * @type {boolean} + * @since 3.20.0 + */ + this.flipY = flipY; + + this.init(game); + }, + + /** + * Creates a WebGL Texture, if required, and sets the Texture filter mode. + * + * @method Phaser.Textures.TextureSource#init + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. + */ + init: function (game) + { + var renderer = this.renderer; + + if (renderer) + { + if (renderer.gl) + { + if (this.isCanvas) + { + this.glTexture = renderer.createCanvasTexture(this.image, false, this.flipY); + } + else if (this.isVideo) + { + this.glTexture = renderer.createVideoTexture(this.image, false, this.flipY); + } + else if (this.isRenderTexture) + { + this.image = this.source.canvas; + + this.glTexture = renderer.createTextureFromSource(null, this.width, this.height, this.scaleMode); + } + else if (this.isGLTexture) + { + this.glTexture = this.source; + } + else + { + this.glTexture = renderer.createTextureFromSource(this.image, this.width, this.height, this.scaleMode); + } + } + else if (this.isRenderTexture) + { + this.image = this.source.canvas; + } + } + + if (!game.config.antialias) + { + this.setFilter(1); + } + }, + + /** + * Sets the Filter Mode for this Texture. + * + * The mode can be either Linear, the default, or Nearest. + * + * For pixel-art you should use Nearest. + * + * @method Phaser.Textures.TextureSource#setFilter + * @since 3.0.0 + * + * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. + */ + setFilter: function (filterMode) + { + if (this.renderer.gl) + { + this.renderer.setTextureFilter(this.glTexture, filterMode); + } + + this.scaleMode = filterMode; + }, + + /** + * Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload. + * + * @method Phaser.Textures.TextureSource#setFlipY + * @since 3.20.0 + * + * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? + */ + setFlipY: function (value) + { + if (value === undefined) { value = true; } + + this.flipY = value; + + return this; + }, + + /** + * If this TextureSource is backed by a Canvas and is running under WebGL, + * it updates the WebGLTexture using the canvas data. + * + * @method Phaser.Textures.TextureSource#update + * @since 3.7.0 + */ + update: function () + { + var gl = this.renderer.gl; + + if (gl && this.isCanvas) + { + this.glTexture = this.renderer.updateCanvasTexture(this.image, this.glTexture, this.flipY); + } + else if (gl && this.isVideo) + { + this.glTexture = this.renderer.updateVideoTexture(this.image, this.glTexture, this.flipY); + } + }, + + /** + * Destroys this Texture Source and nulls the references. + * + * @method Phaser.Textures.TextureSource#destroy + * @since 3.0.0 + */ + destroy: function () + { + if (this.glTexture) + { + this.renderer.deleteTexture(this.glTexture, false); + } + + if (this.isCanvas) + { + CanvasPool.remove(this.image); + } + + this.renderer = null; + this.texture = null; + this.source = null; + this.image = null; + this.glTexture = null; + } + +}); + +module.exports = TextureSource; + + +/***/ }), +/* 419 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Textures.Parsers + */ + +module.exports = { + + AtlasXML: __webpack_require__(975), + Canvas: __webpack_require__(976), + Image: __webpack_require__(977), + JSONArray: __webpack_require__(978), + JSONHash: __webpack_require__(979), + SpriteSheet: __webpack_require__(980), + SpriteSheetFromAtlas: __webpack_require__(981), + UnityYAML: __webpack_require__(982) + +}; + + +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var HTML5AudioSoundManager = __webpack_require__(421); +var NoAudioSoundManager = __webpack_require__(424); +var WebAudioSoundManager = __webpack_require__(426); + +/** + * Creates a Web Audio, HTML5 Audio or No Audio Sound Manager based on config and device settings. + * + * Be aware of https://developers.google.com/web/updates/2017/09/autoplay-policy-changes + * + * @function Phaser.Sound.SoundManagerCreator + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + * + * @return {(Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager|Phaser.Sound.NoAudioSoundManager)} The Sound Manager instance that was created. + */ +var SoundManagerCreator = { + + create: function (game) + { + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + return new NoAudioSoundManager(game); + } + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + return new WebAudioSoundManager(game); + } + + return new HTML5AudioSoundManager(game); + } + +}; + +module.exports = SoundManagerCreator; + + +/***/ }), +/* 421 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var HTML5AudioSound = __webpack_require__(423); + +/** + * HTML5 Audio implementation of the Sound Manager. + * + * To play multiple instances of the same HTML5 Audio sound, you need to provide an `instances` value when + * loading the sound with the Loader: + * + * ```javascript + * this.load.audio('explosion', 'explosion.mp3', { + * instances: 2 + * }); + * ``` + * + * Not all browsers can play all audio formats. + * + * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). + * + * @class HTML5AudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var HTML5AudioSoundManager = new Class({ + + Extends: BaseSoundManager, + + initialize: + + function HTML5AudioSoundManager (game) + { + /** + * Flag indicating whether if there are no idle instances of HTML5 Audio tag, + * for any particular sound, if one of the used tags should be hijacked and used + * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play + * call should be ignored. + * + * @name Phaser.Sound.HTML5AudioSoundManager#override + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.override = true; + + /** + * Value representing time difference, in seconds, between calling + * play method on an audio tag and when it actually starts playing. + * It is used to achieve more accurate delayed sound playback. + * + * You might need to tweak this value to get the desired results + * since audio play delay varies depending on the browser/platform. + * + * @name Phaser.Sound.HTML5AudioSoundManager#audioPlayDelay + * @type {number} + * @default 0.1 + * @since 3.0.0 + */ + this.audioPlayDelay = 0.1; + + /** + * A value by which we should offset the loop end marker of the + * looping sound to compensate for lag, caused by changing audio + * tag playback position, in order to achieve gapless looping. + * + * You might need to tweak this value to get the desired results + * since loop lag varies depending on the browser/platform. + * + * @name Phaser.Sound.HTML5AudioSoundManager#loopEndOffset + * @type {number} + * @default 0.05 + * @since 3.0.0 + */ + this.loopEndOffset = 0.05; + + /** + * An array for keeping track of all the sounds + * that were paused when game lost focus. + * + * @name Phaser.Sound.HTML5AudioSoundManager#onBlurPausedSounds + * @type {Phaser.Sound.HTML5AudioSound[]} + * @private + * @default [] + * @since 3.0.0 + */ + this.onBlurPausedSounds = []; + + this.locked = 'ontouchstart' in window; + + /** + * A queue of all actions performed on sound objects while audio was locked. + * Once the audio gets unlocked, after an explicit user interaction, + * all actions will be performed in chronological order. + * Array of object types: { sound: Phaser.Sound.HTML5AudioSound, name: string, value?: * } + * + * @name Phaser.Sound.HTML5AudioSoundManager#lockedActionsQueue + * @type {array} + * @private + * @since 3.0.0 + */ + this.lockedActionsQueue = this.locked ? [] : null; + + /** + * Property that actually holds the value of global mute + * for HTML5 Audio sound manager implementation. + * + * @name Phaser.Sound.HTML5AudioSoundManager#_mute + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._mute = false; + + /** + * Property that actually holds the value of global volume + * for HTML5 Audio sound manager implementation. + * + * @name Phaser.Sound.HTML5AudioSoundManager#_volume + * @type {boolean} + * @private + * @default 1 + * @since 3.0.0 + */ + this._volume = 1; + + BaseSoundManager.call(this, game); + }, + + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#add + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {Phaser.Sound.HTML5AudioSound} The new sound instance. + */ + add: function (key, config) + { + var sound = new HTML5AudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + /** + * Unlocks HTML5 Audio loading and playback on mobile + * devices on the initial explicit user interaction. + * + * @method Phaser.Sound.HTML5AudioSoundManager#unlock + * @since 3.0.0 + */ + unlock: function () + { + this.locked = false; + + var _this = this; + + this.game.cache.audio.entries.each(function (key, tags) + { + for (var i = 0; i < tags.length; i++) + { + if (tags[i].dataset.locked === 'true') + { + _this.locked = true; + + return false; + } + } + + return true; + }); + + if (!this.locked) + { + return; + } + + var moved = false; + + var detectMove = function () + { + moved = true; + }; + + var unlock = function () + { + if (moved) + { + moved = false; + return; + } + + document.body.removeEventListener('touchmove', detectMove); + document.body.removeEventListener('touchend', unlock); + + var lockedTags = []; + + _this.game.cache.audio.entries.each(function (key, tags) + { + for (var i = 0; i < tags.length; i++) + { + var tag = tags[i]; + + if (tag.dataset.locked === 'true') + { + lockedTags.push(tag); + } + } + + return true; + }); + + if (lockedTags.length === 0) + { + return; + } + + var lastTag = lockedTags[lockedTags.length - 1]; + + lastTag.oncanplaythrough = function () + { + lastTag.oncanplaythrough = null; + + lockedTags.forEach(function (tag) + { + tag.dataset.locked = 'false'; + }); + + _this.unlocked = true; + }; + + lockedTags.forEach(function (tag) + { + tag.load(); + }); + }; + + this.once(Events.UNLOCKED, function () + { + this.forEachActiveSound(function (sound) + { + if (sound.currentMarker === null && sound.duration === 0) + { + sound.duration = sound.tags[0].duration; + } + + sound.totalDuration = sound.tags[0].duration; + }); + + while (this.lockedActionsQueue.length) + { + var lockedAction = this.lockedActionsQueue.shift(); + + if (lockedAction.sound[lockedAction.prop].apply) + { + lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); + } + else + { + lockedAction.sound[lockedAction.prop] = lockedAction.value; + } + } + + }, this); + + document.body.addEventListener('touchmove', detectMove, false); + document.body.addEventListener('touchend', unlock, false); + }, + + /** + * Method used internally for pausing sound manager if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onBlur + * @protected + * @since 3.0.0 + */ + onBlur: function () + { + this.forEachActiveSound(function (sound) + { + if (sound.isPlaying) + { + this.onBlurPausedSounds.push(sound); + sound.onBlur(); + } + }); + }, + + /** + * Method used internally for resuming sound manager if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onFocus + * @protected + * @since 3.0.0 + */ + onFocus: function () + { + this.onBlurPausedSounds.forEach(function (sound) + { + sound.onFocus(); + }); + + this.onBlurPausedSounds.length = 0; + }, + + /** + * Calls Phaser.Sound.BaseSoundManager#destroy method + * and cleans up all HTML5 Audio related stuff. + * + * @method Phaser.Sound.HTML5AudioSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSoundManager.prototype.destroy.call(this); + + this.onBlurPausedSounds.length = 0; + this.onBlurPausedSounds = null; + }, + + /** + * Method used internally by Phaser.Sound.HTML5AudioSound class methods and property setters + * to check if sound manager is locked and then either perform action immediately or queue it + * to be performed once the sound manager gets unlocked. + * + * @method Phaser.Sound.HTML5AudioSoundManager#isLocked + * @protected + * @since 3.0.0 + * + * @param {Phaser.Sound.HTML5AudioSound} sound - Sound object on which to perform queued action. + * @param {string} prop - Name of the method to be called or property to be assigned a value to. + * @param {*} [value] - An optional parameter that either holds an array of arguments to be passed to the method call or value to be set to the property. + * + * @return {boolean} Whether the sound manager is locked. + */ + isLocked: function (sound, prop, value) + { + if (sound.tags[0].dataset.locked === 'true') + { + this.lockedActionsQueue.push({ + sound: sound, + prop: prop, + value: value + }); + + return true; + } + + return false; + }, + + /** + * Sets the muted state of all this Sound Manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#setMute + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.3.0 + * + * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * + * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * @name Phaser.Sound.HTML5AudioSoundManager#mute + * @type {boolean} + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return this._mute; + }, + + set: function (value) + { + this._mute = value; + + this.forEachActiveSound(function (sound) + { + sound.updateMute(); + }); + + this.emit(Events.GLOBAL_MUTE, this, value); + } + + }, + + /** + * Sets the volume of this Sound Manager. + * + * @method Phaser.Sound.HTML5AudioSoundManager#setVolume + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.3.0 + * + * @param {number} value - The global volume of this Sound Manager. + * + * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * @name Phaser.Sound.HTML5AudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this._volume; + }, + + set: function (value) + { + this._volume = value; + + this.forEachActiveSound(function (sound) + { + sound.updateVolume(); + }); + + this.emit(Events.GLOBAL_VOLUME, this, value); + } + + } + +}); + +module.exports = HTML5AudioSoundManager; + + +/***/ }), +/* 422 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SafeRange = __webpack_require__(78); + +/** + * 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 {number} [startIndex=0] - An optional start index to search from. + * @param {number} [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; + + +/***/ }), +/* 423 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var Clamp = __webpack_require__(18); + +/** + * @classdesc + * HTML5 Audio implementation of the sound. + * + * @class HTML5AudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.HTML5AudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var HTML5AudioSound = new Class({ + + Extends: BaseSound, + + initialize: + + function HTML5AudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } + + /** + * An array containing all HTML5 Audio tags that could be used for individual + * sound's playback. Number of instances depends on the config value passed + * to the Loader#audio method call, default is 1. + * + * @name Phaser.Sound.HTML5AudioSound#tags + * @type {HTMLAudioElement[]} + * @private + * @since 3.0.0 + */ + this.tags = manager.game.cache.audio.get(key); + + if (!this.tags) + { + throw new Error('There is no audio asset with key "' + key + '" in the audio cache'); + } + + /** + * Reference to an HTML5 Audio tag used for playing sound. + * + * @name Phaser.Sound.HTML5AudioSound#audio + * @type {HTMLAudioElement} + * @private + * @default null + * @since 3.0.0 + */ + this.audio = null; + + /** + * Timestamp as generated by the Request Animation Frame or SetTimeout + * representing the time at which the delayed sound playback should start. + * Set to 0 if sound playback is not delayed. + * + * @name Phaser.Sound.HTML5AudioSound#startTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * Audio tag's playback position recorded on previous + * update method call. Set to 0 if sound is not playing. + * + * @name Phaser.Sound.HTML5AudioSound#previousTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.previousTime = 0; + + this.duration = this.tags[0].duration; + + this.totalDuration = this.tags[0].duration; + + BaseSound.call(this, manager, key, config); + }, + + /** + * Play this sound, or a marked section of it. + * It always plays the sound from the start. If you want to start playback from a specific time + * you can set 'seek' setting of the config object, provided to this call, to that value. + * + * @method Phaser.Sound.HTML5AudioSound#play + * @fires Phaser.Sound.Events#PLAY + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} Whether the sound started playing successfully. + */ + play: function (markerName, config) + { + if (this.manager.isLocked(this, 'play', [ markerName, config ])) + { + return false; + } + + if (!BaseSound.prototype.play.call(this, markerName, config)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) + { + return false; + } + + this.emit(Events.PLAY, this); + + return true; + }, + + /** + * Pauses the sound. + * + * @method Phaser.Sound.HTML5AudioSound#pause + * @fires Phaser.Sound.Events#PAUSE + * @since 3.0.0 + * + * @return {boolean} Whether the sound was paused successfully. + */ + pause: function () + { + if (this.manager.isLocked(this, 'pause')) + { + return false; + } + + if (this.startTime > 0) + { + return false; + } + + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + + this.stopAndReleaseAudioTag(); + + this.emit(Events.PAUSE, this); + + return true; + }, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.HTML5AudioSound#resume + * @fires Phaser.Sound.Events#RESUME + * @since 3.0.0 + * + * @return {boolean} Whether the sound was resumed successfully. + */ + resume: function () + { + if (this.manager.isLocked(this, 'resume')) + { + return false; + } + + if (this.startTime > 0) + { + return false; + } + + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) + { + return false; + } + + this.emit(Events.RESUME, this); + + return true; + }, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.HTML5AudioSound#stop + * @fires Phaser.Sound.Events#STOP + * @since 3.0.0 + * + * @return {boolean} Whether the sound was stopped successfully. + */ + stop: function () + { + if (this.manager.isLocked(this, 'stop')) + { + return false; + } + + if (!BaseSound.prototype.stop.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = false \/\/\/ + this.stopAndReleaseAudioTag(); + + this.emit(Events.STOP, this); + + return true; + }, + + /** + * Used internally to do what the name says. + * + * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag + * @private + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAndPlayAudioTag: function () + { + if (!this.pickAudioTag()) + { + this.reset(); + return false; + } + + var seek = this.currentConfig.seek; + var delay = this.currentConfig.delay; + var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; + + this.previousTime = offset; + this.audio.currentTime = offset; + this.applyConfig(); + + if (delay === 0) + { + this.startTime = 0; + + if (this.audio.paused) + { + this.playCatchPromise(); + } + } + else + { + this.startTime = window.performance.now() + delay * 1000; + + if (!this.audio.paused) + { + this.audio.pause(); + } + } + + this.resetConfig(); + + return true; + }, + + /** + * This method performs the audio tag pooling logic. It first looks for + * unused audio tag to assign to this sound object. If there are no unused + * audio tags, based on HTML5AudioSoundManager#override property value, it + * looks for sound with most advanced playback and hijacks its audio tag or + * does nothing. + * + * @method Phaser.Sound.HTML5AudioSound#pickAudioTag + * @private + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAudioTag: function () + { + if (this.audio) + { + return true; + } + + for (var i = 0; i < this.tags.length; i++) + { + var audio = this.tags[i]; + + if (audio.dataset.used === 'false') + { + audio.dataset.used = 'true'; + this.audio = audio; + return true; + } + } + + if (!this.manager.override) + { + return false; + } + + var otherSounds = []; + + this.manager.forEachActiveSound(function (sound) + { + if (sound.key === this.key && sound.audio) + { + otherSounds.push(sound); + } + }, this); + + otherSounds.sort(function (a1, a2) + { + if (a1.loop === a2.loop) + { + // sort by progress + return (a2.seek / a2.duration) - (a1.seek / a1.duration); + } + return a1.loop ? 1 : -1; + }); + + var selectedSound = otherSounds[0]; + + this.audio = selectedSound.audio; + + selectedSound.reset(); + selectedSound.audio = null; + selectedSound.startTime = 0; + selectedSound.previousTime = 0; + + return true; + }, + + /** + * Method used for playing audio tag and catching possible exceptions + * thrown from rejected Promise returned from play method call. + * + * @method Phaser.Sound.HTML5AudioSound#playCatchPromise + * @private + * @since 3.0.0 + */ + playCatchPromise: function () + { + var playPromise = this.audio.play(); + + if (playPromise) + { + // eslint-disable-next-line no-unused-vars + playPromise.catch(function (reason) + { + console.warn(reason); + }); + } + }, + + /** + * Used internally to do what the name says. + * + * @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag + * @private + * @since 3.0.0 + */ + stopAndReleaseAudioTag: function () + { + this.startTime = 0; + this.previousTime = 0; + + if (this.audio) + { + this.audio.pause(); + this.audio.dataset.used = 'false'; + this.audio = null; + } + }, + + /** + * Method used internally to reset sound state, usually when stopping sound + * or when hijacking audio tag from another sound. + * + * @method Phaser.Sound.HTML5AudioSound#reset + * @private + * @since 3.0.0 + */ + reset: function () + { + BaseSound.prototype.stop.call(this); + }, + + /** + * Method used internally by sound manager for pausing sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSoundManager#onBlur + * @private + * @since 3.0.0 + */ + onBlur: function () + { + this.isPlaying = false; + this.isPaused = true; + + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + + this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); + + this.stopAndReleaseAudioTag(); + }, + + /** + * Method used internally by sound manager for resuming sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSound#onFocus + * @private + * @since 3.0.0 + */ + onFocus: function () + { + this.isPlaying = true; + this.isPaused = false; + this.pickAndPlayAudioTag(); + }, + + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.HTML5AudioSound#update + * @fires Phaser.Sound.Events#COMPLETE + * @fires Phaser.Sound.Events#LOOPED + * @protected + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + */ + update: function (time) + { + if (!this.isPlaying) + { + return; + } + + // handling delayed playback + if (this.startTime > 0) + { + if (this.startTime < time - this.manager.audioPlayDelay) + { + this.audio.currentTime += Math.max(0, time - this.startTime) / 1000; + this.startTime = 0; + this.previousTime = this.audio.currentTime; + this.playCatchPromise(); + } + + return; + } + + // handle looping and ending + var startTime = this.currentMarker ? this.currentMarker.start : 0; + var endTime = startTime + this.duration; + var currentTime = this.audio.currentTime; + + if (this.currentConfig.loop) + { + if (currentTime >= endTime - this.manager.loopEndOffset) + { + this.audio.currentTime = startTime + Math.max(0, currentTime - endTime); + currentTime = this.audio.currentTime; + } + else if (currentTime < startTime) + { + this.audio.currentTime += startTime; + currentTime = this.audio.currentTime; + } + + if (currentTime < this.previousTime) + { + this.emit(Events.LOOPED, this); + } + } + else if (currentTime >= endTime) + { + this.reset(); + + this.stopAndReleaseAudioTag(); + + this.emit(Events.COMPLETE, this); + + return; + } + + this.previousTime = currentTime; + }, + + /** + * Calls Phaser.Sound.BaseSound#destroy method + * and cleans up all HTML5 Audio related stuff. + * + * @method Phaser.Sound.HTML5AudioSound#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + + this.tags = null; + + if (this.audio) + { + this.stopAndReleaseAudioTag(); + } + }, + + /** + * Method used internally to determine mute setting of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateMute + * @private + * @since 3.0.0 + */ + updateMute: function () + { + if (this.audio) + { + this.audio.muted = this.currentConfig.mute || this.manager.mute; + } + }, + + /** + * Method used internally to calculate total volume of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateVolume + * @private + * @since 3.0.0 + */ + updateVolume: function () + { + if (this.audio) + { + this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1); + } + }, + + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.HTML5AudioSound#calculateRate + * @protected + * @since 3.0.0 + */ + calculateRate: function () + { + BaseSound.prototype.calculateRate.call(this); + + if (this.audio) + { + this.audio.playbackRate = this.totalRate; + } + }, + + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + * + * @name Phaser.Sound.HTML5AudioSound#mute + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return this.currentConfig.mute; + }, + + set: function (value) + { + this.currentConfig.mute = value; + + if (this.manager.isLocked(this, 'mute', value)) + { + return; + } + + this.updateMute(); + + this.emit(Events.MUTE, this, value); + } + }, + + /** + * Sets the muted state of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setMute + * @fires Phaser.Sound.Events#MUTE + * @since 3.4.0 + * + * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * + * @return {this} This Sound instance. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * + * @name Phaser.Sound.HTML5AudioSound#volume + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.currentConfig.volume; + }, + + set: function (value) + { + this.currentConfig.volume = value; + + if (this.manager.isLocked(this, 'volume', value)) + { + return; + } + + this.updateVolume(); + + this.emit(Events.VOLUME, this, value); + } + }, + + /** + * Sets the volume of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setVolume + * @fires Phaser.Sound.Events#VOLUME + * @since 3.4.0 + * + * @param {number} value - The volume of the sound. + * + * @return {this} This Sound instance. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * Rate at which this Sound will be played. + * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @name Phaser.Sound.HTML5AudioSound#rate + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#RATE + * @since 3.0.0 + */ + rate: { + + get: function () + { + return this.currentConfig.rate; + }, + + set: function (value) + { + this.currentConfig.rate = value; + + if (this.manager.isLocked(this, Events.RATE, value)) + { + return; + } + else + { + this.calculateRate(); + + this.emit(Events.RATE, this, value); + } + } + + }, + + /** + * Sets the playback rate of this Sound. + * + * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @method Phaser.Sound.HTML5AudioSound#setRate + * @fires Phaser.Sound.Events#RATE + * @since 3.3.0 + * + * @param {number} value - The playback rate at of this Sound. + * + * @return {this} This Sound instance. + */ + setRate: function (value) + { + this.rate = value; + + return this; + }, + + /** + * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @name Phaser.Sound.HTML5AudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE + * @since 3.0.0 + */ + detune: { + + get: function () + { + return this.currentConfig.detune; + }, + + set: function (value) + { + this.currentConfig.detune = value; + + if (this.manager.isLocked(this, Events.DETUNE, value)) + { + return; + } + else + { + this.calculateRate(); + + this.emit(Events.DETUNE, this, value); + } + } + + }, + + /** + * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @method Phaser.Sound.HTML5AudioSound#setDetune + * @fires Phaser.Sound.Events#DETUNE + * @since 3.3.0 + * + * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @return {this} This Sound instance. + */ + setDetune: function (value) + { + this.detune = value; + + return this; + }, + + /** + * Property representing the position of playback for this sound, in seconds. + * Setting it to a specific value moves current playback to that position. + * The value given is clamped to the range 0 to current marker duration. + * Setting seek of a stopped sound has no effect. + * + * @name Phaser.Sound.HTML5AudioSound#seek + * @type {number} + * @fires Phaser.Sound.Events#SEEK + * @since 3.0.0 + */ + seek: { + + get: function () + { + if (this.isPlaying) + { + return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + } + else if (this.isPaused) + { + return this.currentConfig.seek; + } + else + { + return 0; + } + }, + + set: function (value) + { + if (this.manager.isLocked(this, 'seek', value)) + { + return; + } + + if (this.startTime > 0) + { + return; + } + + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); + + if (this.isPlaying) + { + this.previousTime = value; + this.audio.currentTime = value; + } + else if (this.isPaused) + { + this.currentConfig.seek = value; + } + + this.emit(Events.SEEK, this, value); + } + } + }, + + /** + * Seeks to a specific point in this sound. + * + * @method Phaser.Sound.HTML5AudioSound#setSeek + * @fires Phaser.Sound.Events#SEEK + * @since 3.4.0 + * + * @param {number} value - The point in the sound to seek to. + * + * @return {this} This Sound instance. + */ + setSeek: function (value) + { + this.seek = value; + + return this; + }, + + /** + * Flag indicating whether or not the sound or current sound marker will loop. + * + * @name Phaser.Sound.HTML5AudioSound#loop + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#LOOP + * @since 3.0.0 + */ + loop: { + + get: function () + { + return this.currentConfig.loop; + }, + + set: function (value) + { + this.currentConfig.loop = value; + + if (this.manager.isLocked(this, 'loop', value)) + { + return; + } + + if (this.audio) + { + this.audio.loop = value; + } + + this.emit(Events.LOOP, this, value); + } + + }, + + /** + * Sets the loop state of this Sound. + * + * @method Phaser.Sound.HTML5AudioSound#setLoop + * @fires Phaser.Sound.Events#LOOP + * @since 3.4.0 + * + * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * + * @return {Phaser.Sound.HTML5AudioSound} This Sound instance. + */ + setLoop: function (value) + { + this.loop = value; + + return this; + }, + + /** + * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * + * @name Phaser.Sound.HTML5AudioSound#pan + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + */ + pan: { + + get: function () + { + return this.currentConfig.pan; + }, + + set: function (value) + { + this.currentConfig.pan = value; + + this.emit(Events.PAN, this, value); + } + }, + + /** + * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * + * @method Phaser.Sound.HTML5AudioSound#setPan + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + * + * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + * + * @return {this} This Sound instance. + */ + setPan: function (value) + { + this.pan = value; + + return this; + } + +}); + +module.exports = HTML5AudioSound; + + +/***/ }), +/* 424 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var NoAudioSound = __webpack_require__(425); +var NOOP = __webpack_require__(1); + +/** + * @classdesc + * No-audio implementation of the Sound Manager. It is used if audio has been + * disabled in the game config or the device doesn't support any audio. + * + * It represents a graceful degradation of Sound Manager logic that provides + * minimal functionality and prevents Phaser projects that use audio from + * breaking on devices that don't support any audio playback technologies. + * + * @class NoAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var NoAudioSoundManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function NoAudioSoundManager (game) + { + EventEmitter.call(this); + + this.game = game; + this.sounds = []; + this.mute = false; + this.volume = 1; + this.rate = 1; + this.detune = 0; + this.pauseOnBlur = true; + this.locked = false; + }, + + add: function (key, config) + { + var sound = new NoAudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + addAudioSprite: function (key, config) + { + var sound = this.add(key, config); + + sound.spritemap = {}; + + return sound; + }, + + // eslint-disable-next-line no-unused-vars + play: function (key, extra) + { + return false; + }, + + // eslint-disable-next-line no-unused-vars + playAudioSprite: function (key, spriteName, config) + { + return false; + }, + + remove: function (sound) + { + return BaseSoundManager.prototype.remove.call(this, sound); + }, + + removeByKey: function (key) + { + return BaseSoundManager.prototype.removeByKey.call(this, key); + }, + + pauseAll: NOOP, + resumeAll: NOOP, + stopAll: NOOP, + update: NOOP, + setRate: NOOP, + setDetune: NOOP, + setMute: NOOP, + setVolume: NOOP, + + forEachActiveSound: function (callbackfn, scope) + { + BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); + }, + + destroy: function () + { + BaseSoundManager.prototype.destroy.call(this); + } + +}); + +module.exports = NoAudioSoundManager; + + +/***/ }), +/* 425 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Extend = __webpack_require__(17); + +var returnFalse = function () +{ + return false; +}; + +var returnNull = function () +{ + return null; +}; + +var returnThis = function () +{ + return this; +}; + +/** + * @classdesc + * No audio implementation of the sound. It is used if audio has been + * disabled in the game config or the device doesn't support any audio. + * + * It represents a graceful degradation of sound logic that provides + * minimal functionality and prevents Phaser projects that use audio from + * breaking on devices that don't support any audio playback technologies. + * + * @class NoAudioSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.NoAudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var NoAudioSound = new Class({ + + Extends: EventEmitter, + + initialize: + + function NoAudioSound (manager, key, config) + { + if (config === void 0) { config = {}; } + + EventEmitter.call(this); + + this.manager = manager; + this.key = key; + this.isPlaying = false; + this.isPaused = false; + this.totalRate = 1; + this.duration = 0; + this.totalDuration = 0; + + this.config = Extend({ + mute: false, + volume: 1, + rate: 1, + detune: 0, + seek: 0, + loop: false, + delay: 0, + pan: 0 + }, config); + + this.currentConfig = this.config; + this.mute = false; + this.volume = 1; + this.rate = 1; + this.detune = 0; + this.seek = 0; + this.loop = false; + this.pan = 0; + this.markers = {}; + this.currentMarker = null; + this.pendingRemove = false; + }, + + /** + * @method Phaser.Sound.NoAudioSound#addMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * + * @return {boolean} false + */ + addMarker: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#updateMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. + * + * @return {boolean} false + */ + updateMarker: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#removeMarker + * @since 3.0.0 + * + * @param {string} markerName - The name of the marker to remove. + * + * @return {null} null + */ + removeMarker: returnNull, + + /** + * @method Phaser.Sound.NoAudioSound#play + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} false + */ + play: returnFalse, + + /** + * @method Phaser.Sound.NoAudioSound#pause + * @since 3.0.0 + * + * @return {boolean} false + */ + pause: returnFalse, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.NoAudioSound#resume + * @since 3.0.0 + * + * @return {boolean} false + */ + resume: returnFalse, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.NoAudioSound#stop + * @since 3.0.0 + * + * @return {boolean} false + */ + stop: returnFalse, + + /** + * Destroys this sound and all associated events and marks it for removal from the sound manager. + * + * @method Phaser.Sound.NoAudioSound#destroy + * @fires Phaser.Sound.Events#DESTROY + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + }, + + setMute: returnThis, + + setVolume: returnThis, + + setRate: returnThis, + + setDetune: returnThis, + + setSeek: returnThis, + + setLoop: returnThis, + + setPan: returnThis + +}); + +module.exports = NoAudioSound; + + +/***/ }), +/* 426 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Base64ToArrayBuffer = __webpack_require__(427); +var BaseSoundManager = __webpack_require__(144); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); +var GameEvents = __webpack_require__(22); +var WebAudioSound = __webpack_require__(428); + +/** + * @classdesc + * Web Audio API implementation of the Sound Manager. + * + * Not all browsers can play all audio formats. + * + * There is a good guide to what's supported: [Cross-browser audio basics: Audio codec support](https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics#Audio_Codec_Support). + * + * @class WebAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + */ +var WebAudioSoundManager = new Class({ + + Extends: BaseSoundManager, + + initialize: + + function WebAudioSoundManager (game) + { + /** + * The AudioContext being used for playback. + * + * @name Phaser.Sound.WebAudioSoundManager#context + * @type {AudioContext} + * @private + * @since 3.0.0 + */ + this.context = this.createAudioContext(game); + + /** + * Gain node responsible for controlling global muting. + * + * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.masterMuteNode = this.context.createGain(); + + /** + * Gain node responsible for controlling global volume. + * + * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.masterVolumeNode = this.context.createGain(); + + this.masterMuteNode.connect(this.masterVolumeNode); + + this.masterVolumeNode.connect(this.context.destination); + + /** + * Destination node for connecting individual sounds to. + * + * @name Phaser.Sound.WebAudioSoundManager#destination + * @type {AudioNode} + * @private + * @since 3.0.0 + */ + this.destination = this.masterMuteNode; + + this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); + + BaseSoundManager.call(this, game); + + if (this.locked && game.isBooted) + { + this.unlock(); + } + else + { + game.events.once(GameEvents.BOOT, this.unlock, this); + } + }, + + /** + * Method responsible for instantiating and returning AudioContext instance. + * If an instance of an AudioContext class was provided through the game config, + * that instance will be returned instead. This can come in handy if you are reloading + * a Phaser game on a page that never properly refreshes (such as in an SPA project) + * and you want to reuse already instantiated AudioContext. + * + * @method Phaser.Sound.WebAudioSoundManager#createAudioContext + * @private + * @since 3.0.0 + * + * @param {Phaser.Game} game - Reference to the current game instance. + * + * @return {AudioContext} The AudioContext instance to be used for playback. + */ + createAudioContext: function (game) + { + var audioConfig = game.config.audio; + + if (audioConfig.context) + { + audioConfig.context.resume(); + + return audioConfig.context; + } + + return new AudioContext(); + }, + + /** + * This method takes a new AudioContext reference and then sets + * this Sound Manager to use that context for all playback. + * + * As part of this call it also disconnects the master mute and volume + * nodes and then re-creates them on the new given context. + * + * @method Phaser.Sound.WebAudioSoundManager#setAudioContext + * @since 3.21.0 + * + * @param {AudioContext} context - Reference to an already created AudioContext instance. + * + * @return {this} The WebAudioSoundManager instance. + */ + setAudioContext: function (context) + { + if (this.context) + { + this.context.close(); + } + + if (this.masterMuteNode) + { + this.masterMuteNode.disconnect(); + } + + if (this.masterVolumeNode) + { + this.masterVolumeNode.disconnect(); + } + + this.context = context; + + this.masterMuteNode = context.createGain(); + this.masterVolumeNode = context.createGain(); + + this.masterMuteNode.connect(this.masterVolumeNode); + this.masterVolumeNode.connect(context.destination); + + this.destination = this.masterMuteNode; + + return this; + }, + + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.WebAudioSoundManager#add + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {Phaser.Sound.WebAudioSound} The new sound instance. + */ + add: function (key, config) + { + var sound = new WebAudioSound(this, key, config); + + this.sounds.push(sound); + + return sound; + }, + + /** + * Decode audio data into a format ready for playback via Web Audio. + * + * The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + * + * The `audioKey` is the key that will be used to save the decoded audio to the audio cache. + * + * Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig` + * objects as the first and only argument. + * + * Decoding is an async process, so be sure to listen for the events to know when decoding has completed. + * + * Once the audio has decoded it can be added to the Sound Manager or played via its key. + * + * @method Phaser.Sound.WebAudioSoundManager#decodeAudio + * @fires Phaser.Sound.Events#DECODED + * @fires Phaser.Sound.Events#DECODED_ALL + * @since 3.18.0 + * + * @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects. + * @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + */ + decodeAudio: function (audioKey, audioData) + { + var audioFiles; + + if (!Array.isArray(audioKey)) + { + audioFiles = [ { key: audioKey, data: audioData } ]; + } + else + { + audioFiles = audioKey; + } + + var cache = this.game.cache.audio; + var remaining = audioFiles.length; + + for (var i = 0; i < audioFiles.length; i++) + { + var entry = audioFiles[i]; + + var key = entry.key; + var data = entry.data; + + if (typeof data === 'string') + { + data = Base64ToArrayBuffer(data); + } + + var success = function (key, audioBuffer) + { + cache.add(key, audioBuffer); + + this.emit(Events.DECODED, key); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + var failure = function (key, error) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + this.context.decodeAudioData(data, success, failure); + } + }, + + /** + * Unlocks Web Audio API on the initial input event. + * + * Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09). + * + * @method Phaser.Sound.WebAudioSoundManager#unlock + * @since 3.0.0 + */ + unlock: function () + { + var _this = this; + + var body = document.body; + + var unlockHandler = function unlockHandler () + { + if (_this.context) + { + _this.context.resume().then(function () + { + body.removeEventListener('touchstart', unlockHandler); + body.removeEventListener('touchend', unlockHandler); + body.removeEventListener('click', unlockHandler); + body.removeEventListener('keydown', unlockHandler); + + _this.unlocked = true; + }, function () + { + body.removeEventListener('touchstart', unlockHandler); + body.removeEventListener('touchend', unlockHandler); + body.removeEventListener('click', unlockHandler); + body.removeEventListener('keydown', unlockHandler); + }); + } + }; + + if (body) + { + body.addEventListener('touchstart', unlockHandler, false); + body.addEventListener('touchend', unlockHandler, false); + body.addEventListener('click', unlockHandler, false); + body.addEventListener('keydown', unlockHandler, false); + } + }, + + /** + * Method used internally for pausing sound manager if + * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.WebAudioSoundManager#onBlur + * @protected + * @since 3.0.0 + */ + onBlur: function () + { + if (!this.locked) + { + this.context.suspend(); + } + }, + + /** + * Method used internally for resuming sound manager if + * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.WebAudioSoundManager#onFocus + * @protected + * @since 3.0.0 + */ + onFocus: function () + { + if (!this.locked) + { + this.context.resume(); + } + }, + + /** + * Calls Phaser.Sound.BaseSoundManager#destroy method + * and cleans up all Web Audio API related stuff. + * + * @method Phaser.Sound.WebAudioSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.destination = null; + this.masterVolumeNode.disconnect(); + this.masterVolumeNode = null; + this.masterMuteNode.disconnect(); + this.masterMuteNode = null; + + if (this.game.config.audio.context) + { + this.context.suspend(); + } + else + { + var _this = this; + + this.context.close().then(function () + { + _this.context = null; + }); + } + + BaseSoundManager.prototype.destroy.call(this); + }, + + /** + * Sets the muted state of all this Sound Manager. + * + * @method Phaser.Sound.WebAudioSoundManager#setMute + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.3.0 + * + * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * + * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * @name Phaser.Sound.WebAudioSoundManager#mute + * @type {boolean} + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return (this.masterMuteNode.gain.value === 0); + }, + + set: function (value) + { + this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0); + + this.emit(Events.GLOBAL_MUTE, this, value); + } + + }, + + /** + * Sets the volume of this Sound Manager. + * + * @method Phaser.Sound.WebAudioSoundManager#setVolume + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.3.0 + * + * @param {number} value - The global volume of this Sound Manager. + * + * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * @name Phaser.Sound.WebAudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.masterVolumeNode.gain.value; + }, + + set: function (value) + { + this.masterVolumeNode.gain.setValueAtTime(value, 0); + + this.emit(Events.GLOBAL_VOLUME, this, value); + } + + } + +}); + +module.exports = WebAudioSoundManager; + + +/***/ }), +/* 427 */ +/***/ (function(module, exports) { + +/** + * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +// Use a lookup table to find the index. +var lookup = new Uint8Array(256); + +for (var i = 0; i < chars.length; i++) +{ + lookup[chars.charCodeAt(i)] = i; +} + +/** + * Converts a base64 string, either with or without a data uri, into an Array Buffer. + * + * @function Phaser.Utils.Base64.Base64ToArrayBuffer + * @since 3.18.0 + * + * @param {string} base64 - The base64 string to be decoded. Can optionally contain a data URI header, which will be stripped out prior to decoding. + * + * @return {ArrayBuffer} An ArrayBuffer decoded from the base64 data. + */ +var Base64ToArrayBuffer = function (base64) +{ + // Is it a data uri? if so, strip the header away + base64 = base64.substr(base64.indexOf(',') + 1); + + var len = base64.length; + var bufferLength = len * 0.75; + var p = 0; + var encoded1; + var encoded2; + var encoded3; + var encoded4; + + if (base64[len - 1] === '=') + { + bufferLength--; + + if (base64[len - 2] === '=') + { + bufferLength--; + } + } + + var arrayBuffer = new ArrayBuffer(bufferLength); + var bytes = new Uint8Array(arrayBuffer); + + for (var i = 0; i < len; i += 4) + { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; + + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } + + return arrayBuffer; +}; + +module.exports = Base64ToArrayBuffer; + + +/***/ }), +/* 428 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BaseSound = __webpack_require__(145); +var Class = __webpack_require__(0); +var Events = __webpack_require__(69); + +/** + * @classdesc + * Web Audio API implementation of the sound. + * + * @class WebAudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Sound.WebAudioSoundManager} manager - Reference to the current sound manager instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. + */ +var WebAudioSound = new Class({ + + Extends: BaseSound, + + initialize: + + function WebAudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } + + /** + * Audio buffer containing decoded data of the audio asset to be played. + * + * @name Phaser.Sound.WebAudioSound#audioBuffer + * @type {AudioBuffer} + * @private + * @since 3.0.0 + */ + this.audioBuffer = manager.game.cache.audio.get(key); + + if (!this.audioBuffer) + { + throw new Error('Audio key "' + key + '" missing from cache'); + } + + /** + * A reference to an audio source node used for playing back audio from + * audio data stored in Phaser.Sound.WebAudioSound#audioBuffer. + * + * @name Phaser.Sound.WebAudioSound#source + * @type {AudioBufferSourceNode} + * @private + * @default null + * @since 3.0.0 + */ + this.source = null; + + /** + * A reference to a second audio source used for gapless looped playback. + * + * @name Phaser.Sound.WebAudioSound#loopSource + * @type {AudioBufferSourceNode} + * @private + * @default null + * @since 3.0.0 + */ + this.loopSource = null; + + /** + * Gain node responsible for controlling this sound's muting. + * + * @name Phaser.Sound.WebAudioSound#muteNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.muteNode = manager.context.createGain(); + + /** + * Gain node responsible for controlling this sound's volume. + * + * @name Phaser.Sound.WebAudioSound#volumeNode + * @type {GainNode} + * @private + * @since 3.0.0 + */ + this.volumeNode = manager.context.createGain(); + + /** + * Panner node responsible for controlling this sound's pan. + * + * Doesn't work on iOS / Safari. + * + * @name Phaser.Sound.WebAudioSound#pannerNode + * @type {StereoPannerNode} + * @private + * @since 3.50.0 + */ + this.pannerNode = null; + + /** + * The time at which the sound should have started playback from the beginning. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#playTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.playTime = 0; + + /** + * The time at which the sound source should have actually started playback. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#startTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; + + /** + * The time at which the sound loop source should actually start playback. + * Based on BaseAudioContext.currentTime value. + * + * @name Phaser.Sound.WebAudioSound#loopTime + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.loopTime = 0; + + /** + * An array where we keep track of all rate updates during playback. + * Array of object types: { time: number, rate: number } + * + * @name Phaser.Sound.WebAudioSound#rateUpdates + * @type {array} + * @private + * @default [] + * @since 3.0.0 + */ + this.rateUpdates = []; + + /** + * Used for keeping track when sound source playback has ended + * so its state can be updated accordingly. + * + * @name Phaser.Sound.WebAudioSound#hasEnded + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this.hasEnded = false; + + /** + * Used for keeping track when sound source has looped + * so its state can be updated accordingly. + * + * @name Phaser.Sound.WebAudioSound#hasLooped + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this.hasLooped = false; + + this.muteNode.connect(this.volumeNode); + + if (manager.context.createStereoPanner) + { + this.pannerNode = manager.context.createStereoPanner(); + + this.volumeNode.connect(this.pannerNode); + + this.pannerNode.connect(manager.destination); + } + else + { + this.volumeNode.connect(manager.destination); + } + + this.duration = this.audioBuffer.duration; + + this.totalDuration = this.audioBuffer.duration; + + BaseSound.call(this, manager, key, config); + }, + + /** + * Play this sound, or a marked section of it. + * + * It always plays the sound from the start. If you want to start playback from a specific time + * you can set 'seek' setting of the config object, provided to this call, to that value. + * + * @method Phaser.Sound.WebAudioSound#play + * @fires Phaser.Sound.Events#PLAY + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. + * @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound. + * + * @return {boolean} Whether the sound started playing successfully. + */ + play: function (markerName, config) + { + if (!BaseSound.prototype.play.call(this, markerName, config)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + + this.emit(Events.PLAY, this); + + return true; + }, + + /** + * Pauses the sound. + * + * @method Phaser.Sound.WebAudioSound#pause + * @fires Phaser.Sound.Events#PAUSE + * @since 3.0.0 + * + * @return {boolean} Whether the sound was paused successfully. + */ + pause: function () + { + if (this.manager.context.currentTime < this.startTime) + { + return false; + } + + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time + this.stopAndRemoveBufferSource(); + + this.emit(Events.PAUSE, this); + + return true; + }, + + /** + * Resumes the sound. + * + * @method Phaser.Sound.WebAudioSound#resume + * @fires Phaser.Sound.Events#RESUME + * @since 3.0.0 + * + * @return {boolean} Whether the sound was resumed successfully. + */ + resume: function () + { + if (this.manager.context.currentTime < this.startTime) + { + return false; + } + + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.createAndStartBufferSource(); + + this.emit(Events.RESUME, this); + + return true; + }, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.WebAudioSound#stop + * @fires Phaser.Sound.Events#STOP + * @since 3.0.0 + * + * @return {boolean} Whether the sound was stopped successfully. + */ + stop: function () + { + if (!BaseSound.prototype.stop.call(this)) + { + return false; + } + + // \/\/\/ isPlaying = false, isPaused = false \/\/\/ + this.stopAndRemoveBufferSource(); + + this.emit(Events.STOP, this); + + return true; + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createAndStartBufferSource + * @private + * @since 3.0.0 + */ + createAndStartBufferSource: function () + { + var seek = this.currentConfig.seek; + var delay = this.currentConfig.delay; + var when = this.manager.context.currentTime + delay; + var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; + var duration = this.duration - seek; + + this.playTime = when - seek; + this.startTime = when; + this.source = this.createBufferSource(); + + this.applyConfig(); + + this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); + + this.resetConfig(); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource + * @private + * @since 3.0.0 + */ + createAndStartLoopBufferSource: function () + { + var when = this.getLoopTime(); + var offset = this.currentMarker ? this.currentMarker.start : 0; + var duration = this.duration; + + this.loopTime = when; + this.loopSource = this.createBufferSource(); + this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0); + this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#createBufferSource + * @private + * @since 3.0.0 + * + * @return {AudioBufferSourceNode} + */ + createBufferSource: function () + { + var _this = this; + var source = this.manager.context.createBufferSource(); + + source.buffer = this.audioBuffer; + + source.connect(this.muteNode); + + source.onended = function (ev) + { + if (ev.target === _this.source) + { + // sound ended + if (_this.currentConfig.loop) + { + _this.hasLooped = true; + } + else + { + _this.hasEnded = true; + } + } + + // else was stopped + }; + + return source; + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource + * @private + * @since 3.0.0 + */ + stopAndRemoveBufferSource: function () + { + if (this.source) + { + this.source.stop(); + this.source.disconnect(); + this.source = null; + } + + this.playTime = 0; + this.startTime = 0; + + this.stopAndRemoveLoopBufferSource(); + }, + + /** + * Used internally. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource + * @private + * @since 3.0.0 + */ + stopAndRemoveLoopBufferSource: function () + { + if (this.loopSource) + { + this.loopSource.stop(); + this.loopSource.disconnect(); + this.loopSource = null; + } + + this.loopTime = 0; + }, + + /** + * Method used internally for applying config values to some of the sound properties. + * + * @method Phaser.Sound.WebAudioSound#applyConfig + * @protected + * @since 3.0.0 + */ + applyConfig: function () + { + this.rateUpdates.length = 0; + + this.rateUpdates.push({ + time: 0, + rate: 1 + }); + + BaseSound.prototype.applyConfig.call(this); + }, + + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.WebAudioSound#update + * @fires Phaser.Sound.Events#COMPLETE + * @fires Phaser.Sound.Events#LOOPED + * @protected + * @since 3.0.0 + */ + update: function () + { + if (this.hasEnded) + { + this.hasEnded = false; + + BaseSound.prototype.stop.call(this); + + this.stopAndRemoveBufferSource(); + + this.emit(Events.COMPLETE, this); + } + else if (this.hasLooped) + { + this.hasLooped = false; + this.source = this.loopSource; + this.loopSource = null; + this.playTime = this.startTime = this.loopTime; + this.rateUpdates.length = 0; + + this.rateUpdates.push({ + time: 0, + rate: this.totalRate + }); + + this.createAndStartLoopBufferSource(); + + this.emit(Events.LOOPED, this); + } + }, + + /** + * Calls Phaser.Sound.BaseSound#destroy method + * and cleans up all Web Audio API related stuff. + * + * @method Phaser.Sound.WebAudioSound#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSound.prototype.destroy.call(this); + + this.audioBuffer = null; + this.stopAndRemoveBufferSource(); + this.muteNode.disconnect(); + this.muteNode = null; + this.volumeNode.disconnect(); + this.volumeNode = null; + this.pannerNode.disconnect(); + this.pannerNode = null; + this.rateUpdates.length = 0; + this.rateUpdates = null; + }, + + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.WebAudioSound#calculateRate + * @protected + * @since 3.0.0 + */ + calculateRate: function () + { + BaseSound.prototype.calculateRate.call(this); + + var now = this.manager.context.currentTime; + + if (this.source && typeof this.totalRate === 'number') + { + this.source.playbackRate.setValueAtTime(this.totalRate, now); + } + + if (this.isPlaying) + { + this.rateUpdates.push({ + time: Math.max(this.startTime, now) - this.playTime, + rate: this.totalRate + }); + + if (this.loopSource) + { + this.stopAndRemoveLoopBufferSource(); + this.createAndStartLoopBufferSource(); + } + } + }, + + /** + * Method used internally for calculating current playback time of a playing sound. + * + * @method Phaser.Sound.WebAudioSound#getCurrentTime + * @private + * @since 3.0.0 + */ + getCurrentTime: function () + { + var currentTime = 0; + + for (var i = 0; i < this.rateUpdates.length; i++) + { + var nextTime = 0; + + if (i < this.rateUpdates.length - 1) + { + nextTime = this.rateUpdates[i + 1].time; + } + else + { + nextTime = this.manager.context.currentTime - this.playTime; + } + + currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } + + return currentTime; + }, + + /** + * Method used internally for calculating the time + * at witch the loop source should start playing. + * + * @method Phaser.Sound.WebAudioSound#getLoopTime + * @private + * @since 3.0.0 + */ + getLoopTime: function () + { + var lastRateUpdateCurrentTime = 0; + + for (var i = 0; i < this.rateUpdates.length - 1; i++) + { + lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } + + var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1]; + + return this.playTime + lastRateUpdate.time + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate; + }, + + /** + * Rate at which this Sound will be played. + * Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @name Phaser.Sound.WebAudioSound#rate + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#RATE + * @since 3.0.0 + */ + rate: { + + get: function () + { + return this.currentConfig.rate; + }, + + set: function (value) + { + this.currentConfig.rate = value; + + this.calculateRate(); + + this.emit(Events.RATE, this, value); + } + + }, + + /** + * Sets the playback rate of this Sound. + * + * For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed + * and 2.0 doubles the audios playback speed. + * + * @method Phaser.Sound.WebAudioSound#setRate + * @fires Phaser.Sound.Events#RATE + * @since 3.3.0 + * + * @param {number} value - The playback rate at of this Sound. + * + * @return {this} This Sound instance. + */ + setRate: function (value) + { + this.rate = value; + + return this; + }, + + /** + * The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @name Phaser.Sound.WebAudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE + * @since 3.0.0 + */ + detune: { + + get: function () + { + return this.currentConfig.detune; + }, + + set: function (value) + { + this.currentConfig.detune = value; + + this.calculateRate(); + + this.emit(Events.DETUNE, this, value); + } + + }, + + /** + * Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). + * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @method Phaser.Sound.WebAudioSound#setDetune + * @fires Phaser.Sound.Events#DETUNE + * @since 3.3.0 + * + * @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + * + * @return {this} This Sound instance. + */ + setDetune: function (value) + { + this.detune = value; + + return this; + }, + + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + * + * @name Phaser.Sound.WebAudioSound#mute + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#MUTE + * @since 3.0.0 + */ + mute: { + + get: function () + { + return (this.muteNode.gain.value === 0); + }, + + set: function (value) + { + this.currentConfig.mute = value; + this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0); + + this.emit(Events.MUTE, this, value); + } + + }, + + /** + * Sets the muted state of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setMute + * @fires Phaser.Sound.Events#MUTE + * @since 3.4.0 + * + * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * + * @return {this} This Sound instance. + */ + setMute: function (value) + { + this.mute = value; + + return this; + }, + + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * + * @name Phaser.Sound.WebAudioSound#volume + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#VOLUME + * @since 3.0.0 + */ + volume: { + + get: function () + { + return this.volumeNode.gain.value; + }, + + set: function (value) + { + this.currentConfig.volume = value; + this.volumeNode.gain.setValueAtTime(value, 0); + + this.emit(Events.VOLUME, this, value); + } + }, + + /** + * Sets the volume of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setVolume + * @fires Phaser.Sound.Events#VOLUME + * @since 3.4.0 + * + * @param {number} value - The volume of the sound. + * + * @return {this} This Sound instance. + */ + setVolume: function (value) + { + this.volume = value; + + return this; + }, + + /** + * Property representing the position of playback for this sound, in seconds. + * Setting it to a specific value moves current playback to that position. + * The value given is clamped to the range 0 to current marker duration. + * Setting seek of a stopped sound has no effect. + * + * @name Phaser.Sound.WebAudioSound#seek + * @type {number} + * @fires Phaser.Sound.Events#SEEK + * @since 3.0.0 + */ + seek: { + + get: function () + { + if (this.isPlaying) + { + if (this.manager.context.currentTime < this.startTime) + { + return this.startTime - this.playTime; + } + + return this.getCurrentTime(); + } + else if (this.isPaused) + { + return this.currentConfig.seek; + } + else + { + return 0; + } + }, + + set: function (value) + { + if (this.manager.context.currentTime < this.startTime) + { + return; + } + + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); + + this.currentConfig.seek = value; + + if (this.isPlaying) + { + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + } + + this.emit(Events.SEEK, this, value); + } + } + }, + + /** + * Seeks to a specific point in this sound. + * + * @method Phaser.Sound.WebAudioSound#setSeek + * @fires Phaser.Sound.Events#SEEK + * @since 3.4.0 + * + * @param {number} value - The point in the sound to seek to. + * + * @return {this} This Sound instance. + */ + setSeek: function (value) + { + this.seek = value; + + return this; + }, + + /** + * Flag indicating whether or not the sound or current sound marker will loop. + * + * @name Phaser.Sound.WebAudioSound#loop + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#LOOP + * @since 3.0.0 + */ + loop: { + + get: function () + { + return this.currentConfig.loop; + }, + + set: function (value) + { + this.currentConfig.loop = value; + + if (this.isPlaying) + { + this.stopAndRemoveLoopBufferSource(); + + if (value) + { + this.createAndStartLoopBufferSource(); + } + } + + this.emit(Events.LOOP, this, value); + } + }, + + /** + * Sets the loop state of this Sound. + * + * @method Phaser.Sound.WebAudioSound#setLoop + * @fires Phaser.Sound.Events#LOOP + * @since 3.4.0 + * + * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * + * @return {this} This Sound instance. + */ + setLoop: function (value) + { + this.loop = value; + + return this; + }, + + /** + * Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Always returns zero on iOS / Safari as it doesn't support the stereo panner node. + * + * @name Phaser.Sound.WebAudioSound#pan + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + */ + pan: { + + get: function () + { + if (this.pannerNode) + { + return this.pannerNode.pan.value; + } + else + { + return 0; + } + }, + + set: function (value) + { + this.currentConfig.pan = value; + + if (this.pannerNode) + { + this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime); + } + + this.emit(Events.PAN, this, value); + } + }, + + /** + * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * + * Note: iOS / Safari doesn't support the stereo panner node. + * + * @method Phaser.Sound.WebAudioSound#setPan + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + * + * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + * + * @return {this} This Sound instance. + */ + setPan: function (value) + { + this.pan = value; + + return this; + } + +}); + +module.exports = WebAudioSound; + + +/***/ }), +/* 429 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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; + + +/***/ }), +/* 430 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @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 {number} k - The k-th element index. + * @param {number} [left=0] - The index of the left part of the range. + * @param {number} [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; + + +/***/ }), +/* 431 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetValue = __webpack_require__(6); +var Shuffle = __webpack_require__(129); + +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; + + +/***/ }), +/* 432 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Structs.Events + */ + +module.exports = { + + PROCESS_QUEUE_ADD: __webpack_require__(1035), + PROCESS_QUEUE_REMOVE: __webpack_require__(1036) + +}; + + +/***/ }), +/* 433 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetAdvancedValue = __webpack_require__(13); + +/** + * Adds an Animation component to a Sprite and populates it based on the given config. + * + * @function Phaser.GameObjects.BuildGameObjectAnimation + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. + * @param {object} config - The animation config. + * + * @return {Phaser.GameObjects.Sprite} The updated Sprite. + */ +var BuildGameObjectAnimation = function (sprite, config) +{ + var animConfig = GetAdvancedValue(config, 'anims', null); + + if (animConfig === null) + { + return sprite; + } + + if (typeof animConfig === 'string') + { + // { anims: 'key' } + sprite.anims.play(animConfig); + } + else if (typeof animConfig === 'object') + { + // { anims: { + // key: string + // startFrame: [string|number] + // delay: [float] + // repeat: [integer] + // repeatDelay: [float] + // yoyo: [boolean] + // play: [boolean] + // delayedPlay: [boolean] + // } + // } + + var anims = sprite.anims; + + var key = GetAdvancedValue(animConfig, 'key', undefined); + + if (key) + { + var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); + + var delay = GetAdvancedValue(animConfig, 'delay', 0); + var repeat = GetAdvancedValue(animConfig, 'repeat', 0); + var repeatDelay = GetAdvancedValue(animConfig, 'repeatDelay', 0); + var yoyo = GetAdvancedValue(animConfig, 'yoyo', false); + + var play = GetAdvancedValue(animConfig, 'play', false); + var delayedPlay = GetAdvancedValue(animConfig, 'delayedPlay', 0); + + var playConfig = { + key: key, + delay: delay, + repeat: repeat, + repeatDelay: repeatDelay, + yoyo: yoyo, + startFrame: startFrame + }; + + if (play) + { + anims.play(playConfig); + } + else if (delayedPlay > 0) + { + anims.playAfterDelay(playConfig, delayedPlay); + } + else + { + anims.load(playConfig); + } + } + } + + return sprite; +}; + +module.exports = BuildGameObjectAnimation; + + +/***/ }), +/* 434 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Frame = __webpack_require__(106); + +/** + * @classdesc + * A Bob Game Object. + * + * A Bob belongs to a Blitter Game Object. The Blitter is responsible for managing and rendering this object. + * + * A Bob has a position, alpha value and a frame from a texture that it uses to render with. You can also toggle + * the flipped and visible state of the Bob. The Frame the Bob uses to render can be changed dynamically, but it + * must be a Frame within the Texture used by the parent Blitter. + * + * Bob positions are relative to the Blitter parent. So if you move the Blitter parent, all Bob children will + * have their positions impacted by this change as well. + * + * You can manipulate Bob objects directly from your game code, but the creation and destruction of them should be + * handled via the Blitter parent. + * + * @class Bob + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Blitter} blitter - The parent Blitter object is responsible for updating this Bob. + * @param {number} x - The horizontal position of this Game Object in the world, relative to the parent Blitter position. + * @param {number} y - The vertical position of this Game Object in the world, relative to the parent Blitter position. + * @param {(string|number)} frame - The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. + * @param {boolean} visible - Should the Bob render visible or not to start with? + */ +var Bob = new Class({ + + initialize: + + function Bob (blitter, x, y, frame, visible) + { + /** + * The Blitter object that this Bob belongs to. + * + * @name Phaser.GameObjects.Bob#parent + * @type {Phaser.GameObjects.Blitter} + * @since 3.0.0 + */ + this.parent = blitter; + + /** + * The x position of this Bob, relative to the x position of the Blitter. + * + * @name Phaser.GameObjects.Bob#x + * @type {number} + * @since 3.0.0 + */ + this.x = x; + + /** + * The y position of this Bob, relative to the y position of the Blitter. + * + * @name Phaser.GameObjects.Bob#y + * @type {number} + * @since 3.0.0 + */ + this.y = y; + + /** + * The frame that the Bob uses to render with. + * To change the frame use the `Bob.setFrame` method. + * + * @name Phaser.GameObjects.Bob#frame + * @type {Phaser.Textures.Frame} + * @protected + * @since 3.0.0 + */ + this.frame = frame; + + /** + * A blank object which can be used to store data related to this Bob in. + * + * @name Phaser.GameObjects.Bob#data + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.data = {}; + + /** + * The tint value of this Bob. + * + * @name Phaser.GameObjects.Bob#tint + * @type {number} + * @default 0xffffff + * @since 3.20.0 + */ + this.tint = 0xffffff; + + /** + * The visible state of this Bob. + * + * @name Phaser.GameObjects.Bob#_visible + * @type {boolean} + * @private + * @since 3.0.0 + */ + this._visible = visible; + + /** + * The alpha value of this Bob. + * + * @name Phaser.GameObjects.Bob#_alpha + * @type {number} + * @private + * @default 1 + * @since 3.0.0 + */ + this._alpha = 1; + + /** + * The horizontally flipped state of the Bob. + * A Bob that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture. + * + * @name Phaser.GameObjects.Bob#flipX + * @type {boolean} + * @since 3.0.0 + */ + this.flipX = false; + + /** + * The vertically flipped state of the Bob. + * A Bob 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. + * + * @name Phaser.GameObjects.Bob#flipY + * @type {boolean} + * @since 3.0.0 + */ + this.flipY = false; + }, + + /** + * Changes the Texture Frame being used by this Bob. + * The frame must be part of the Texture the parent Blitter is using. + * If no value is given it will use the default frame of the Blitter parent. + * + * @method Phaser.GameObjects.Bob#setFrame + * @since 3.0.0 + * + * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. + * + * @return {this} This Bob Game Object. + */ + setFrame: function (frame) + { + if (frame === undefined) + { + this.frame = this.parent.frame; + } + else if (frame instanceof Frame && frame.texture === this.parent.texture) + { + this.frame = frame; + } + else + { + this.frame = this.parent.texture.get(frame); + } + + return this; + }, + + /** + * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. + * + * @method Phaser.GameObjects.Bob#resetFlip + * @since 3.0.0 + * + * @return {this} This Bob Game Object. + */ + resetFlip: function () + { + this.flipX = false; + this.flipY = false; + + return this; + }, + + /** + * Resets this Bob. + * + * Changes the position to the values given, and optionally changes the frame. + * + * Also resets the flipX and flipY values, sets alpha back to 1 and visible to true. + * + * @method Phaser.GameObjects.Bob#reset + * @since 3.0.0 + * + * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. + * + * @return {this} This Bob Game Object. + */ + reset: function (x, y, frame) + { + this.x = x; + this.y = y; + + this.flipX = false; + this.flipY = false; + + this._alpha = 1; + this._visible = true; + + this.parent.dirty = true; + + if (frame) + { + this.setFrame(frame); + } + + return this; + }, + + /** + * Changes the position of this Bob to the values given. + * + * @method Phaser.GameObjects.Bob#setPosition + * @since 3.20.0 + * + * @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * + * @return {this} This Bob Game Object. + */ + setPosition: function (x, y) + { + this.x = x; + this.y = y; + + return this; + }, + + /** + * Sets the horizontal flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#setFlipX + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. + */ + setFlipX: function (value) + { + this.flipX = value; + + return this; + }, + + /** + * Sets the vertical flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#setFlipY + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. + */ + setFlipY: function (value) + { + this.flipY = value; + + return this; + }, + + /** + * Sets the horizontal and vertical flipped state of this Bob. + * + * @method Phaser.GameObjects.Bob#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 Bob Game Object. + */ + setFlip: function (x, y) + { + this.flipX = x; + this.flipY = y; + + return this; + }, + + /** + * Sets the visibility of this Bob. + * + * An invisible Bob will skip rendering. + * + * @method Phaser.GameObjects.Bob#setVisible + * @since 3.0.0 + * + * @param {boolean} value - The visible state of the Game Object. + * + * @return {this} This Bob Game Object. + */ + setVisible: function (value) + { + this.visible = value; + + return this; + }, + + /** + * Set the Alpha level of this Bob. 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. + * + * A Bob with alpha 0 will skip rendering. + * + * @method Phaser.GameObjects.Bob#setAlpha + * @since 3.0.0 + * + * @param {number} value - The alpha value used for this Bob. Between 0 and 1. + * + * @return {this} This Bob Game Object. + */ + setAlpha: function (value) + { + this.alpha = value; + + return this; + }, + + /** + * Sets the tint of this Bob. + * + * @method Phaser.GameObjects.Bob#setTint + * @since 3.20.0 + * + * @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff. + * + * @return {this} This Bob Game Object. + */ + setTint: function (value) + { + this.tint = value; + + return this; + }, + + /** + * Destroys this Bob instance. + * Removes itself from the Blitter and clears the parent, frame and data properties. + * + * @method Phaser.GameObjects.Bob#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.parent.dirty = true; + + this.parent.children.remove(this); + + this.parent = undefined; + this.frame = undefined; + this.data = undefined; + }, + + /** + * The visible state of the Bob. + * + * An invisible Bob will skip rendering. + * + * @name Phaser.GameObjects.Bob#visible + * @type {boolean} + * @since 3.0.0 + */ + visible: { + + get: function () + { + return this._visible; + }, + + set: function (value) + { + this.parent.dirty |= (this._visible !== value); + this._visible = value; + } + + }, + + /** + * The alpha value of the Bob, between 0 and 1. + * + * A Bob with alpha 0 will skip rendering. + * + * @name Phaser.GameObjects.Bob#alpha + * @type {number} + * @since 3.0.0 + */ + alpha: { + + get: function () + { + return this._alpha; + }, + + set: function (value) + { + this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); + this._alpha = value; + } + + } + +}); + +module.exports = Bob; + + +/***/ }), +/* 435 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +/** + * 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; + + +/***/ }), +/* 436 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var DOMElementRender = __webpack_require__(1049); +var GameObject = __webpack_require__(15); +var IsPlainObject = __webpack_require__(7); +var RemoveFromDOM = __webpack_require__(199); +var SCENE_EVENTS = __webpack_require__(21); +var Vector4 = __webpack_require__(138); + +/** + * @classdesc + * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. + * + * In order for DOM Elements to display you have to enable them by adding the following to your game + * configuration object: + * + * ```javascript + * dom { + * createContainer: true + * } + * ``` + * + * When this is added, Phaser will automatically create a DOM Container div that is positioned over the top + * of the game canvas. This div is sized to match the canvas, and if the canvas size changes, as a result of + * settings within the Scale Manager, the dom container is resized accordingly. + * + * If you have not already done so, you have to provide a `parent` in the Game Configuration, or the DOM + * Container will fail to be created. + * + * You can create a DOM Element by either passing in DOMStrings, or by passing in a reference to an existing + * Element that you wish to be placed under the control of Phaser. For example: + * + * ```javascript + * this.add.dom(x, y, 'div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * The above code will insert a div element into the DOM Container at the given x/y coordinate. The DOMString in + * the 4th argument sets the initial CSS style of the div and the final argument is the inner text. In this case, + * it will create a lime colored div that is 220px by 100px in size with the text Phaser in it, in an Arial font. + * + * You should nearly always, without exception, use explicitly sized HTML Elements, in order to fully control + * alignment and positioning of the elements next to regular game content. + * + * Rather than specify the CSS and HTML directly you can use the `load.html` File Loader to load it into the + * cache and then use the `createFromCache` method instead. You can also use `createFromHTML` and various other + * methods available in this class to help construct your elements. + * + * Once the element has been created you can then control it like you would any other Game Object. You can set its + * position, scale, rotation, alpha and other properties. It will move as the main Scene Camera moves and be clipped + * at the edge of the canvas. It's important to remember some limitations of DOM Elements: The obvious one is that + * they appear above or below your game canvas. You cannot blend them into the display list, meaning you cannot have + * a DOM Element, then a Sprite, then another DOM Element behind it. + * + * They also cannot be enabled for input. To do that, you have to use the `addListener` method to add native event + * listeners directly. The final limitation is to do with cameras. The DOM Container is sized to match the game canvas + * entirely and clipped accordingly. DOM Elements respect camera scrolling and scrollFactor settings, but if you + * change the size of the camera so it no longer matches the size of the canvas, they won't be clipped accordingly. + * + * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. + * + * Note that you should only have DOM Elements in a Scene with a _single_ Camera. If you require multiple cameras, + * use parallel scenes to achieve this. + * + * DOM Elements are a powerful way to align native HTML with your Phaser Game Objects. For example, you can insert + * a login form for a multiplayer game directly into your title screen. Or a text input box for a highscore table. + * Or a banner ad from a 3rd party service. Or perhaps you'd like to use them for high resolution text display and + * UI. The choice is up to you, just remember that you're dealing with standard HTML and CSS floating over the top + * of your game, and should treat it accordingly. + * + * @class DOMElement + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.17.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.ScrollFactor + * @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 DOM Element in the world. + * @param {number} [y=0] - The vertical position of this DOM Element in the world. + * @param {(Element|string)} [element] - An existing DOM element, or a string. If a string starting with a # it will do a `getElementById` look-up on the string (minus the hash). Without a hash, it represents the type of element to create, i.e. 'div'. + * @param {(string|any)} [style] - If a string, will be set directly as the elements `style` property value. If a plain object, will be iterated and the values transferred. In both cases the values replacing whatever CSS styles may have been previously set. + * @param {string} [innerText] - If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. + */ +var DOMElement = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Origin, + Components.ScrollFactor, + Components.Transform, + Components.Visible, + DOMElementRender + ], + + initialize: + + function DOMElement (scene, x, y, element, style, innerText) + { + GameObject.call(this, scene, 'DOMElement'); + + /** + * A reference to the parent DOM Container that the Game instance created when it started. + * + * @name Phaser.GameObjects.DOMElement#parent + * @type {Element} + * @since 3.17.0 + */ + this.parent = scene.sys.game.domContainer; + + /** + * A reference to the HTML Cache. + * + * @name Phaser.GameObjects.DOMElement#cache + * @type {Phaser.Cache.BaseCache} + * @since 3.17.0 + */ + this.cache = scene.sys.cache.html; + + /** + * The actual DOM Element that this Game Object is bound to. For example, if you've created a `
` + * then this property is a direct reference to that element within the dom. + * + * @name Phaser.GameObjects.DOMElement#node + * @type {Element} + * @since 3.17.0 + */ + this.node; + + /** + * By default a DOM Element will have its transform, display, opacity, zIndex and blend mode properties + * updated when its rendered. If, for some reason, you don't want any of these changed other than the + * CSS transform, then set this flag to `true`. When `true` only the CSS Transform is applied and it's + * up to you to keep track of and set the other properties as required. + * + * This can be handy if, for example, you've a nested DOM Element and you don't want the opacity to be + * picked-up by any of its children. + * + * @name Phaser.GameObjects.DOMElement#transformOnly + * @type {boolean} + * @since 3.17.0 + */ + this.transformOnly = false; + + /** + * The angle, in radians, by which to skew the DOM Element on the horizontal axis. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @name Phaser.GameObjects.DOMElement#skewX + * @type {number} + * @since 3.17.0 + */ + this.skewX = 0; + + /** + * The angle, in radians, by which to skew the DOM Element on the vertical axis. + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @name Phaser.GameObjects.DOMElement#skewY + * @type {number} + * @since 3.17.0 + */ + this.skewY = 0; + + /** + * A Vector4 that contains the 3D rotation of this DOM Element around a fixed axis in 3D space. + * + * All values in the Vector4 are treated as degrees, unless the `rotate3dAngle` property is changed. + * + * For more details see the following MDN page: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d + * + * @name Phaser.GameObjects.DOMElement#rotate3d + * @type {Phaser.Math.Vector4} + * @since 3.17.0 + */ + this.rotate3d = new Vector4(); + + /** + * The unit that represents the 3D rotation values. By default this is `deg` for degrees, but can + * be changed to any supported unit. See this page for further details: + * + * https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d + * + * @name Phaser.GameObjects.DOMElement#rotate3dAngle + * @type {string} + * @since 3.17.0 + */ + this.rotate3dAngle = 'deg'; + + /** + * The native (un-scaled) width of this Game Object. + * + * For a DOM Element this property is read-only. + * + * The property `displayWidth` holds the computed bounds of this DOM Element, factoring in scaling. + * + * @name Phaser.GameObjects.DOMElement#width + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.width = 0; + + /** + * The native (un-scaled) height of this Game Object. + * + * For a DOM Element this property is read-only. + * + * The property `displayHeight` holds the computed bounds of this DOM Element, factoring in scaling. + * + * @name Phaser.GameObjects.DOMElement#height + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.height = 0; + + /** + * The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call. + * + * The property `width` holds the un-scaled width of this DOM Element. + * + * @name Phaser.GameObjects.DOMElement#displayWidth + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.displayWidth = 0; + + /** + * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. + * + * The property `height` holds the un-scaled height of this DOM Element. + * + * @name Phaser.GameObjects.DOMElement#displayHeight + * @type {number} + * @readonly + * @since 3.17.0 + */ + this.displayHeight = 0; + + /** + * Internal native event handler. + * + * @name Phaser.GameObjects.DOMElement#handler + * @type {number} + * @private + * @since 3.17.0 + */ + this.handler = this.dispatchNativeEvent.bind(this); + + this.setPosition(x, y); + + if (typeof element === 'string') + { + // hash? + if (element[0] === '#') + { + this.setElement(element.substr(1), style, innerText); + } + else + { + this.createElement(element, style, innerText); + } + } + else if (element) + { + this.setElement(element, style, innerText); + } + + scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); + scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + }, + + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); + }, + + /** + * Handles a Scene Sleep and Wake event. + * + * @method Phaser.GameObjects.DOMElement#handleSceneEvent + * @private + * @since 3.22.0 + * + * @param {Phaser.Scenes.Systems} sys - The Scene Systems. + */ + handleSceneEvent: function (sys) + { + var node = this.node; + var style = node.style; + + if (node) + { + style.display = (sys.settings.visible) ? 'block' : 'none'; + } + }, + + /** + * Sets the horizontal and vertical skew values of this DOM Element. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * @method Phaser.GameObjects.DOMElement#setSkew + * @since 3.17.0 + * + * @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis. + * @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis. + * + * @return {this} This DOM Element instance. + */ + setSkew: function (x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this.skewX = x; + this.skewY = y; + + return this; + }, + + /** + * Sets the perspective CSS property of the _parent DOM Container_. This determines the distance between the z=0 + * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with + * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined + * by the value of this property. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * + * @method Phaser.GameObjects.DOMElement#setPerspective + * @since 3.17.0 + * + * @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user. + * + * @return {this} This DOM Element instance. + */ + setPerspective: function (value) + { + this.parent.style.perspective = value + 'px'; + + return this; + }, + + /** + * The perspective CSS property value of the _parent DOM Container_. This determines the distance between the z=0 + * plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with + * z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined + * by the value of this property. + * + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * + * @name Phaser.GameObjects.DOMElement#perspective + * @type {number} + * @since 3.17.0 + */ + perspective: { + + get: function () + { + return parseFloat(this.parent.style.perspective); + }, + + set: function (value) + { + this.parent.style.perspective = value + 'px'; + } + + }, + + /** + * Adds one or more native DOM event listeners onto the underlying Element of this Game Object. + * The event is then dispatched via this Game Objects standard event emitter. + * + * For example: + * + * ```javascript + * var div = this.add.dom(x, y, element); + * + * div.addListener('click'); + * + * div.on('click', handler); + * ``` + * + * @method Phaser.GameObjects.DOMElement#addListener + * @since 3.17.0 + * + * @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces. + * + * @return {this} This DOM Element instance. + */ + addListener: function (events) + { + if (this.node) + { + events = events.split(' '); + + for (var i = 0; i < events.length; i++) + { + this.node.addEventListener(events[i], this.handler, false); + } + } + + return this; + }, + + /** + * Removes one or more native DOM event listeners from the underlying Element of this Game Object. + * + * @method Phaser.GameObjects.DOMElement#removeListener + * @since 3.17.0 + * + * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. + * + * @return {this} This DOM Element instance. + */ + removeListener: function (events) + { + if (this.node) + { + events = events.split(' '); + + for (var i = 0; i < events.length; i++) + { + this.node.removeEventListener(events[i], this.handler); + } + } + + return this; + }, + + /** + * Internal event proxy to dispatch native DOM Events via this Game Object. + * + * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent + * @private + * @since 3.17.0 + * + * @param {any} event - The native DOM event. + */ + dispatchNativeEvent: function (event) + { + this.emit(event.type, event); + }, + + /** + * Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object, + * so you can control it. The `tagName` should be a string and is passed to `document.createElement`: + * + * ```javascript + * this.add.dom().createElement('div'); + * ``` + * + * For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement + * + * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` + * value as well. Here is an example of a DOMString: + * + * ```javascript + * this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * And using a style object: + * + * ```javascript + * var style = { + * 'background-color': 'lime'; + * 'width': '200px'; + * 'height': '100px'; + * 'font': '48px Arial'; + * }; + * + * this.add.dom().createElement('div', style, 'Phaser'); + * ``` + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createElement + * @since 3.17.0 + * + * @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method. + * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. + * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. + * + * @return {this} This DOM Element instance. + */ + createElement: function (tagName, style, innerText) + { + return this.setElement(document.createElement(tagName), style, innerText); + }, + + /** + * Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM + * entirely first. Any event listeners you may have previously created will need to be re-created on the new element. + * + * The `element` argument you pass to this method can be either a string tagName: + * + * ```javascript + *

Phaser

+ * + * this.add.dom().setElement('heading'); + * ``` + * + * Or a reference to an Element instance: + * + * ```javascript + *

Phaser

+ * + * var h1 = document.getElementById('heading'); + * + * this.add.dom().setElement(h1); + * ``` + * + * You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText` + * value as well. Here is an example of a DOMString: + * + * ```javascript + * this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser'); + * ``` + * + * And using a style object: + * + * ```javascript + * var style = { + * 'background-color': 'lime'; + * 'width': '200px'; + * 'height': '100px'; + * 'font': '48px Arial'; + * }; + * + * this.add.dom().setElement(h1, style, 'Phaser'); + * ``` + * + * @method Phaser.GameObjects.DOMElement#setElement + * @since 3.17.0 + * + * @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. + * @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from. + * @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element. + * + * @return {this} This DOM Element instance. + */ + setElement: function (element, style, innerText) + { + // Already got an element? Remove it first + this.removeElement(); + + var target; + + if (typeof element === 'string') + { + // hash? + if (element[0] === '#') + { + element = element.substr(1); + } + + target = document.getElementById(element); + } + else if (typeof element === 'object' && element.nodeType === 1) + { + target = element; + } + + if (!target) + { + return this; + } + + this.node = target; + + // style can be empty, a string or a plain object + if (style && IsPlainObject(style)) + { + for (var key in style) + { + target.style[key] = style[key]; + } + } + else if (typeof style === 'string') + { + target.style = style; + } + + // Add / Override the values we need + + target.style.zIndex = '0'; + target.style.display = 'inline'; + target.style.position = 'absolute'; + + // Node handler + + target.phaser = this; + + if (this.parent) + { + this.parent.appendChild(target); + } + + // InnerText + + if (innerText) + { + target.innerText = innerText; + } + + return this.updateSize(); + }, + + /** + * Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then + * creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created + * element. + * + * Assume the following html is stored in a file called `loginform.html`: + * + * ```html + * + * + * ``` + * + * Which is loaded into your game using the cache key 'login': + * + * ```javascript + * this.load.html('login', 'assets/loginform.html'); + * ``` + * + * You can create a DOM Element from it using the cache key: + * + * ```javascript + * this.add.dom().createFromCache('login'); + * ``` + * + * The optional `elementType` argument controls the container that is created, into which the loaded html is inserted. + * The default is a plain `div` object, but any valid tagName can be given. + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createFromCache + * @since 3.17.0 + * + * @param {string} The key of the html cache entry to use for this DOM Element. + * @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. + * + * @return {this} This DOM Element instance. + */ + createFromCache: function (key, tagName) + { + var html = this.cache.get(key); + + if (html) + { + this.createFromHTML(html, tagName); + } + + return this; + }, + + /** + * Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML` + * property of the created element. + * + * ```javascript + * let form = ` + * + * + * `; + * ``` + * + * You can create a DOM Element from it using the string: + * + * ```javascript + * this.add.dom().createFromHTML(form); + * ``` + * + * The optional `elementType` argument controls the type of container that is created, into which the html is inserted. + * The default is a plain `div` object, but any valid tagName can be given. + * + * If this Game Object already has an Element, it is removed from the DOM entirely first. + * Any event listeners you may have previously created will need to be re-created after this call. + * + * @method Phaser.GameObjects.DOMElement#createFromHTML + * @since 3.17.0 + * + * @param {string} A string of html to be set as the `innerHTML` property of the created element. + * @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. + * + * @return {this} This DOM Element instance. + */ + createFromHTML: function (html, tagName) + { + if (tagName === undefined) { tagName = 'div'; } + + // Already got an element? Remove it first + this.removeElement(); + + var element = document.createElement(tagName); + + this.node = element; + + element.style.zIndex = '0'; + element.style.display = 'inline'; + element.style.position = 'absolute'; + + // Node handler + + element.phaser = this; + + if (this.parent) + { + this.parent.appendChild(element); + } + + element.innerHTML = html; + + return this.updateSize(); + }, + + /** + * Removes the current DOM Element bound to this Game Object from the DOM entirely and resets the + * `node` property of this Game Object to be `null`. + * + * @method Phaser.GameObjects.DOMElement#removeElement + * @since 3.17.0 + * + * @return {this} This DOM Element instance. + */ + removeElement: function () + { + if (this.node) + { + RemoveFromDOM(this.node); + + this.node = null; + } + + return this; + }, + + /** + * Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width + * and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight` + * values into the `width` and `height` properties respectively. + * + * This is called automatically whenever a new element is created or set. + * + * @method Phaser.GameObjects.DOMElement#updateSize + * @since 3.17.0 + * + * @return {this} This DOM Element instance. + */ + updateSize: function () + { + var node = this.node; + + var nodeBounds = node.getBoundingClientRect(); + + this.width = node.clientWidth; + this.height = node.clientHeight; + + this.displayWidth = nodeBounds.width || 0; + this.displayHeight = nodeBounds.height || 0; + + return this; + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a property matching the given key and value. It then returns this child + * if found, or `null` if not. + * + * @method Phaser.GameObjects.DOMElement#getChildByProperty + * @since 3.17.0 + * + * @param {string} property - The property to search the children for. + * @param {string} value - The value the property must strictly equal. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByProperty: function (property, value) + { + if (this.node) + { + var children = this.node.querySelectorAll('*'); + + for (var i = 0; i < children.length; i++) + { + if (children[i][property] === value) + { + return children[i]; + } + } + } + + return null; + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not. + * + * Be aware that class and id names are case-sensitive. + * + * @method Phaser.GameObjects.DOMElement#getChildByID + * @since 3.17.0 + * + * @param {string} id - The id to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByID: function (id) + { + return this.getChildByProperty('id', id); + }, + + /** + * Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through + * them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not. + * + * Be aware that class and id names are case-sensitive. + * + * @method Phaser.GameObjects.DOMElement#getChildByName + * @since 3.17.0 + * + * @param {string} name - The name to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. + */ + getChildByName: function (name) + { + return this.getChildByProperty('name', name); + }, + + /** + * Sets the `className` property of the DOM Element node and updates the internal sizes. + * + * @method Phaser.GameObjects.DOMElement#setClassName + * @since 3.17.0 + * + * @param {string} className - A string representing the class or space-separated classes of the element. + * + * @return {this} This DOM Element instance. + */ + setClassName: function (className) + { + if (this.node) + { + this.node.className = className; + + this.updateSize(); + } + + return this; + }, + + /** + * Sets the `innerText` property of the DOM Element node and updates the internal sizes. + * + * Note that only certain types of Elements can have `innerText` set on them. + * + * @method Phaser.GameObjects.DOMElement#setText + * @since 3.17.0 + * + * @param {string} text - A DOMString representing the rendered text content of the element. + * + * @return {this} This DOM Element instance. + */ + setText: function (text) + { + if (this.node) + { + this.node.innerText = text; + + this.updateSize(); + } + + return this; + }, + + /** + * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. + * + * @method Phaser.GameObjects.DOMElement#setHTML + * @since 3.17.0 + * + * @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element. + * + * @return {this} This DOM Element instance. + */ + setHTML: function (html) + { + if (this.node) + { + this.node.innerHTML = html; + + this.updateSize(); + } + + return this; + }, + + /** + * Runs internal update tasks. + * + * @method Phaser.GameObjects.DOMElement#preUpdate + * @private + * @since 3.17.0 + */ + preUpdate: function () + { + var parent = this.parentContainer; + var node = this.node; + + if (node && parent && !parent.willRender()) + { + node.style.display = 'none'; + } + }, + + /** + * Compares the renderMask with the renderFlags to see if this Game Object will render or not. + * + * DOMElements always return `true` as they need to still set values during the render pass, even if not visible. + * + * @method Phaser.GameObjects.DOMElement#willRender + * @since 3.17.0 + * + * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. + */ + willRender: function () + { + return true; + }, + + /** + * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. + * + * @method Phaser.GameObjects.DOMElement#preDestroy + * @private + * @since 3.17.0 + */ + preDestroy: function () + { + this.removeElement(); + + this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); + this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + } + +}); + +module.exports = DOMElement; + + +/***/ }), +/* 437 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CSSBlendModes = __webpack_require__(1050); +var GameObject = __webpack_require__(15); +var TransformMatrix = __webpack_require__(25); + +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); + +/** + * 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.DOMElement#renderWebGL + * @since 3.17.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active renderer. + * @param {Phaser.GameObjects.DOMElement} 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 DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) +{ + var node = src.node; + var style = node.style; + var settings = src.scene.sys.settings; + + if (!node || !style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) + { + if (node) + { + style.display = 'none'; + } + + return; + } + + var parent = src.parentContainer; + var alpha = camera.alpha * src.alpha; + + if (parent) + { + alpha *= parent.alpha; + } + + var camMatrix = tempMatrix1; + var srcMatrix = tempMatrix2; + var calcMatrix = tempMatrix3; + + var dx = 0; + var dy = 0; + + var tx = '0%'; + var ty = '0%'; + + if (parentMatrix) + { + dx = (src.width * src.scaleX) * src.originX; + dy = (src.height * src.scaleY) * src.originY; + + srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); + + camMatrix.copyFrom(camera.matrix); + + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); + + // Undo the camera scroll + srcMatrix.e = src.x - dx; + srcMatrix.f = src.y - dy; + + // Multiply by the src matrix, store result in calcMatrix + camMatrix.multiply(srcMatrix, calcMatrix); + } + else + { + dx = (src.width) * src.originX; + dy = (src.height) * src.originY; + + srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); + + camMatrix.copyFrom(camera.matrix); + + tx = (100 * src.originX) + '%'; + ty = (100 * src.originY) + '%'; + + srcMatrix.e -= camera.scrollX * src.scrollFactorX; + srcMatrix.f -= camera.scrollY * src.scrollFactorY; + + // Multiply by the src matrix, store result in calcMatrix + camMatrix.multiply(srcMatrix, calcMatrix); + } + + if (!src.transformOnly) + { + style.display = 'block'; + style.opacity = alpha; + style.zIndex = src._depth; + style.pointerEvents = 'auto'; + style.mixBlendMode = CSSBlendModes[src._blendMode]; + } + + // https://developer.mozilla.org/en-US/docs/Web/CSS/transform + + style.transform = + calcMatrix.getCSSMatrix() + + ' skew(' + src.skewX + 'rad, ' + src.skewY + 'rad)' + + ' rotate3d(' + src.rotate3d.x + ',' + src.rotate3d.y + ',' + src.rotate3d.z + ',' + src.rotate3d.w + src.rotate3dAngle + ')'; + + style.transformOrigin = tx + ' ' + ty; +}; + +module.exports = DOMElementCSSRenderer; + + +/***/ }), +/* 438 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var GameObject = __webpack_require__(15); +var ExternRender = __webpack_require__(1054); + +/** + * @classdesc + * An Extern Game Object is a special type of Game Object that allows you to pass + * rendering off to a 3rd party. + * + * When you create an Extern and place it in the display list of a Scene, the renderer will + * process the list as usual. When it finds an Extern it will flush the current batch, + * clear down the pipeline and prepare a transform matrix which your render function can + * take advantage of, if required. + * + * The WebGL context is then left is a 'clean' state, ready for you to bind your own shaders, + * or draw to it, whatever you wish to do. Once you've finished, you should free-up any + * of your resources. The Extern will then rebind the Phaser pipeline and carry on + * rendering the display list. + * + * Although this object has lots of properties such as Alpha, Blend Mode and Tint, none of + * them are used during rendering unless you take advantage of them in your own render code. + * + * @class Extern + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.16.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Tint + * @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. + */ +var Extern = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.Origin, + Components.ScrollFactor, + Components.Size, + Components.Texture, + Components.Tint, + Components.Transform, + Components.Visible, + ExternRender + ], + + initialize: + + function Extern (scene) + { + GameObject.call(this, scene, 'Extern'); + }, + + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); + }, + + preUpdate: function () + { + // override this! + // Arguments: time, delta + }, + + render: function () + { + // override this! + // Arguments: renderer, camera, calcMatrix + } + +}); + +module.exports = Extern; + + +/***/ }), +/* 439 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircumferencePoint = __webpack_require__(215); +var FromPercent = __webpack_require__(95); +var MATH_CONST = __webpack_require__(14); +var Point = __webpack_require__(4); + +/** + * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse + * based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point + * at 180 degrees around the circle. + * + * @function Phaser.Geom.Ellipse.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. + * @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the ellipse. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. + */ +var GetPoint = function (ellipse, position, out) +{ + if (out === undefined) { out = new Point(); } + + var angle = FromPercent(position, 0, MATH_CONST.PI2); + + return CircumferencePoint(ellipse, angle, out); +}; + +module.exports = GetPoint; + + +/***/ }), +/* 440 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circumference = __webpack_require__(441); +var CircumferencePoint = __webpack_require__(215); +var FromPercent = __webpack_require__(95); +var MATH_CONST = __webpack_require__(14); + +/** + * Returns an array of Point objects containing the coordinates of the points around the circumference of the Ellipse, + * based on the given quantity or stepRate values. + * + * @function Phaser.Geom.Ellipse.GetPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the points from. + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the circumference of the ellipse and dividing it by the stepRate. + * @param {(array|Phaser.Geom.Point[])} [out] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse. + */ +var GetPoints = function (ellipse, 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 = Circumference(ellipse) / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); + + out.push(CircumferencePoint(ellipse, angle)); + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 441 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns the circumference of the given Ellipse. + * + * @function Phaser.Geom.Ellipse.Circumference + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference of. + * + * @return {number} The circumference of th Ellipse. + */ +var Circumference = function (ellipse) +{ + var rx = ellipse.width / 2; + var ry = ellipse.height / 2; + var h = Math.pow((rx - ry), 2) / Math.pow((rx + ry), 2); + + return (Math.PI * (rx + ry)) * (1 + ((3 * h) / (10 + Math.sqrt(4 - (3 * h))))); +}; + +module.exports = Circumference; + + +/***/ }), +/* 442 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Commands = __webpack_require__(214); +var SetTransform = __webpack_require__(30); + +/** + * 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.Graphics#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Graphics} 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 + * @param {CanvasRenderingContext2D} [renderTargetCtx] - The target rendering context. + * @param {boolean} allowClip - If `true` then path operations will be used instead of fill operations. + */ +var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) +{ + var commandBuffer = src.commandBuffer; + var commandBufferLength = commandBuffer.length; + + var ctx = renderTargetCtx || renderer.currentContext; + + if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + return; + } + + var lineAlpha = 1; + var fillAlpha = 1; + var lineColor = 0; + var fillColor = 0; + var lineWidth = 1; + var red = 0; + var green = 0; + var blue = 0; + + // Reset any currently active paths + ctx.beginPath(); + + for (var index = 0; index < commandBufferLength; ++index) + { + var commandID = commandBuffer[index]; + + switch (commandID) + { + case Commands.ARC: + ctx.arc( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4], + commandBuffer[index + 5], + commandBuffer[index + 6] + ); + + // +7 because overshoot is the 7th value, not used in Canvas + index += 7; + break; + + case Commands.LINE_STYLE: + lineWidth = commandBuffer[index + 1]; + lineColor = commandBuffer[index + 2]; + lineAlpha = commandBuffer[index + 3]; + red = ((lineColor & 0xFF0000) >>> 16); + green = ((lineColor & 0xFF00) >>> 8); + blue = (lineColor & 0xFF); + ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + lineAlpha + ')'; + ctx.lineWidth = lineWidth; + index += 3; + break; + + case Commands.FILL_STYLE: + fillColor = commandBuffer[index + 1]; + fillAlpha = commandBuffer[index + 2]; + red = ((fillColor & 0xFF0000) >>> 16); + green = ((fillColor & 0xFF00) >>> 8); + blue = (fillColor & 0xFF); + ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; + index += 2; + break; + + case Commands.BEGIN_PATH: + ctx.beginPath(); + break; + + case Commands.CLOSE_PATH: + ctx.closePath(); + break; + + case Commands.FILL_PATH: + if (!allowClip) + { + ctx.fill(); + } + break; + + case Commands.STROKE_PATH: + if (!allowClip) + { + ctx.stroke(); + } + break; + + case Commands.FILL_RECT: + if (!allowClip) + { + ctx.fillRect( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4] + ); + } + else + { + ctx.rect( + commandBuffer[index + 1], + commandBuffer[index + 2], + commandBuffer[index + 3], + commandBuffer[index + 4] + ); + } + index += 4; + break; + + case Commands.FILL_TRIANGLE: + ctx.beginPath(); + ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); + ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); + ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); + ctx.closePath(); + if (!allowClip) + { + ctx.fill(); + } + index += 6; + break; + + case Commands.STROKE_TRIANGLE: + ctx.beginPath(); + ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]); + ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]); + ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]); + ctx.closePath(); + if (!allowClip) + { + ctx.stroke(); + } + index += 6; + break; + + case Commands.LINE_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.MOVE_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.LINE_FX_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; + + case Commands.MOVE_FX_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; + + case Commands.SAVE: + ctx.save(); + break; + + case Commands.RESTORE: + ctx.restore(); + break; + + case Commands.TRANSLATE: + ctx.translate( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.SCALE: + ctx.scale( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; + + case Commands.ROTATE: + ctx.rotate( + commandBuffer[index + 1] + ); + index += 1; + break; + + case Commands.GRADIENT_FILL_STYLE: + index += 5; + break; + + case Commands.GRADIENT_LINE_STYLE: + index += 6; + break; + } + } + + // Restore the context saved in SetTransform + ctx.restore(); +}; + +module.exports = GraphicsCanvasRenderer; + + +/***/ }), +/* 443 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var FloatBetween = __webpack_require__(135); +var GetEaseFunction = __webpack_require__(80); +var GetFastValue = __webpack_require__(2); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * A Particle Emitter property. + * + * Facilitates changing Particle properties as they are emitted and throughout their lifetime. + * + * @class EmitterOp + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for the Particle Emitter that owns this property. + * @param {string} key - The name of the property. + * @param {number} defaultValue - The default value of the property. + * @param {boolean} [emitOnly=false] - Whether the property can only be modified when a Particle is emitted. + */ +var EmitterOp = new Class({ + + initialize: + + function EmitterOp (config, key, defaultValue, emitOnly) + { + if (emitOnly === undefined) + { + emitOnly = false; + } + + /** + * The name of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#propertyKey + * @type {string} + * @since 3.0.0 + */ + this.propertyKey = key; + + /** + * The value of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue + * @type {number} + * @since 3.0.0 + */ + this.propertyValue = defaultValue; + + /** + * The default value of this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue + * @type {number} + * @since 3.0.0 + */ + this.defaultValue = defaultValue; + + /** + * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. + * + * @name Phaser.GameObjects.Particles.EmitterOp#steps + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.steps = 0; + + /** + * The step counter for stepped easing, per emit. + * + * @name Phaser.GameObjects.Particles.EmitterOp#counter + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.counter = 0; + + /** + * The start value for this property to ease between. + * + * @name Phaser.GameObjects.Particles.EmitterOp#start + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.start = 0; + + /** + * The end value for this property to ease between. + * + * @name Phaser.GameObjects.Particles.EmitterOp#end + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.end = 0; + + /** + * The easing function to use for updating this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#ease + * @type {?function} + * @since 3.0.0 + */ + this.ease; + + /** + * Whether this property can only be modified when a Particle is emitted. + * + * Set to `true` to allow only {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} callbacks to be set and + * affect this property. + * + * Set to `false` to allow both {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks to be set and affect this property. + * + * @name Phaser.GameObjects.Particles.EmitterOp#emitOnly + * @type {boolean} + * @since 3.0.0 + */ + this.emitOnly = emitOnly; + + /** + * The callback to run for Particles when they are emitted from the Particle Emitter. + * + * @name Phaser.GameObjects.Particles.EmitterOp#onEmit + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback} + * @since 3.0.0 + */ + this.onEmit = this.defaultEmit; + + /** + * The callback to run for Particles when they are updated. + * + * @name Phaser.GameObjects.Particles.EmitterOp#onUpdate + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} + * @since 3.0.0 + */ + this.onUpdate = this.defaultUpdate; + + this.loadConfig(config); + }, + + /** + * Load the property from a Particle Emitter configuration object. + * + * Optionally accepts a new property key to use, replacing the current one. + * + * @method Phaser.GameObjects.Particles.EmitterOp#loadConfig + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Settings for the Particle Emitter that owns this property. + * @param {string} [newKey] - The new key to use for this property, if any. + */ + loadConfig: function (config, newKey) + { + if (config === undefined) + { + config = {}; + } + + if (newKey) + { + this.propertyKey = newKey; + } + + this.propertyValue = GetFastValue( + config, + this.propertyKey, + this.defaultValue + ); + + this.setMethods(); + + if (this.emitOnly) + { + // Reset it back again + this.onUpdate = this.defaultUpdate; + } + }, + + /** + * Build a JSON representation of this Particle Emitter property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#toJSON + * @since 3.0.0 + * + * @return {object} A JSON representation of this Particle Emitter property. + */ + toJSON: function () + { + return this.propertyValue; + }, + + /** + * Change the current value of the property and update its callback methods. + * + * @method Phaser.GameObjects.Particles.EmitterOp#onChange + * @since 3.0.0 + * + * @param {number} value - The value of the property. + * + * @return {this} This Emitter Op object. + */ + onChange: function (value) + { + this.propertyValue = value; + + return this.setMethods(); + }, + + /** + * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the type of the current + * {@link Phaser.GameObjects.Particles.EmitterOp#propertyValue}. + * + * @method Phaser.GameObjects.Particles.EmitterOp#setMethods + * @since 3.0.0 + * + * @return {this} This Emitter Op object. + */ + setMethods: function () + { + var value = this.propertyValue; + + var t = typeof value; + + // Reset them in case they're not changed below + this.onEmit = this.defaultEmit; + this.onUpdate = this.defaultUpdate; + + if (t === 'number') + { + // Explicit static value: + // x: 400 + + this.onEmit = this.staticValueEmit; + this.onUpdate = this.staticValueUpdate; // How? + } + else if (Array.isArray(value)) + { + // Picks a random element from the array: + // x: [ 100, 200, 300, 400 ] + + this.onEmit = this.randomStaticValueEmit; + } + else if (t === 'function') + { + // The same as setting just the onUpdate function and no onEmit (unless this op is an emitOnly one) + // Custom callback, must return a value: + + /* + x: function (particle, key, t, value) + { + return value + 50; + } + */ + + if (this.emitOnly) + { + this.onEmit = value; + } + else + { + this.onUpdate = value; + } + } + else if (t === 'object' && this.hasBoth(value, 'start', 'end')) + { + this.start = value.start; + this.end = value.end; + + // x: { start: 100, end: 400, random: true } (random optional) = eases between start and end + + var isRandom = this.has(value, 'random'); + + if (isRandom) + { + this.onEmit = this.randomRangedValueEmit; + } + + if (this.has(value, 'steps')) + { + // A stepped (per emit) range + + // x: { start: 100, end: 400, steps: 64 } + + // Increments a value stored in the emitter + + this.steps = value.steps; + this.counter = this.start; + + this.onEmit = this.steppedEmit; + } + else + { + // An eased range (defaults to Linear if not specified) + + // x: { start: 100, end: 400, [ ease: 'Linear' ] } + + var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; + + this.ease = GetEaseFunction(easeType, value.easeParams); + + if (!isRandom) + { + this.onEmit = this.easedValueEmit; + } + + this.onUpdate = this.easeValueUpdate; + } + } + else if (t === 'object' && this.hasBoth(value, 'min', 'max')) + { + // { min: 100, max: 400 } = pick a random number between min and max + + this.start = value.min; + this.end = value.max; + this.onEmit = this.randomRangedValueEmit; + } + else if (t === 'object' && this.has(value, 'random')) + { + // { random: [ 100, 400 ] } = pick a random number between the two elements of the array + + var rnd = value.random; + + if (Array.isArray(rnd)) + { + this.start = rnd[0]; + this.end = rnd[1]; + } + + this.onEmit = this.randomRangedValueEmit; + } + else if (t === 'object' && this.hasEither(value, 'onEmit', 'onUpdate')) + { + // Custom onEmit and onUpdate callbacks + + /* + x: { + // Called at the start of the particles life, when it is being created + onEmit: function (particle, key, t, value) + { + return value; + }, + + // Called during the particles life on each update + onUpdate: function (particle, key, t, value) + { + return value; + } + } + */ + + if (this.has(value, 'onEmit')) + { + this.onEmit = value.onEmit; + } + + if (this.has(value, 'onUpdate')) + { + this.onUpdate = value.onUpdate; + } + } + + return this; + }, + + /** + * Check whether an object has the given property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#has + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key - The key of the property to look for in the object. + * + * @return {boolean} `true` if the property exists in the object, `false` otherwise. + */ + has: function (object, key) + { + return object.hasOwnProperty(key); + }, + + /** + * Check whether an object has both of the given properties. + * + * @method Phaser.GameObjects.Particles.EmitterOp#hasBoth + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key1 - The key of the first property to check the object for. + * @param {string} key2 - The key of the second property to check the object for. + * + * @return {boolean} `true` if both properties exist in the object, `false` otherwise. + */ + hasBoth: function (object, key1, key2) + { + return object.hasOwnProperty(key1) && object.hasOwnProperty(key2); + }, + + /** + * Check whether an object has at least one of the given properties. + * + * @method Phaser.GameObjects.Particles.EmitterOp#hasEither + * @since 3.0.0 + * + * @param {object} object - The object to check. + * @param {string} key1 - The key of the first property to check the object for. + * @param {string} key2 - The key of the second property to check the object for. + * + * @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist. + */ + hasEither: function (object, key1, key2) + { + return object.hasOwnProperty(key1) || object.hasOwnProperty(key2); + }, + + /** + * The returned value sets what the property will be at the START of the particles life, on emit. + * + * @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} [value] - The current value of the property. + * + * @return {number} The new value of the property. + */ + defaultEmit: function (particle, key, value) + { + return value; + }, + + /** + * The returned value updates the property for the duration of the particles life. + * + * @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The T value (between 0 and 1) + * @param {number} value - The current value of the property. + * + * @return {number} The new value of the property. + */ + defaultUpdate: function (particle, key, t, value) + { + return value; + }, + + /** + * An `onEmit` callback that returns the current value of the property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit + * @since 3.0.0 + * + * @return {number} The current value of the property. + */ + staticValueEmit: function () + { + return this.propertyValue; + }, + + /** + * An `onUpdate` callback that returns the current value of the property. + * + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate + * @since 3.0.0 + * + * @return {number} The current value of the property. + */ + staticValueUpdate: function () + { + return this.propertyValue; + }, + + /** + * An `onEmit` callback that returns a random value from the current value array. + * + * @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit + * @since 3.0.0 + * + * @return {number} The new value of the property. + */ + randomStaticValueEmit: function () + { + var randomIndex = Math.floor(Math.random() * this.propertyValue.length); + + return this.propertyValue[randomIndex]; + }, + + /** + * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The key of the property. + * + * @return {number} The new value of the property. + */ + randomRangedValueEmit: function (particle, key) + { + var value = FloatBetween(this.start, this.end); + + if (particle && particle.data[key]) + { + particle.data[key].min = value; + } + + return value; + }, + + /** + * An `onEmit` callback that returns a stepped value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit + * @since 3.0.0 + * + * @return {number} The new value of the property. + */ + steppedEmit: function () + { + var current = this.counter; + + var next = this.counter + (this.end - this.start) / this.steps; + + this.counter = Wrap(next, this.start, this.end); + + return current; + }, + + /** + * An `onEmit` callback for an eased property. + * + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. + * + * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * + * @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property. + */ + easedValueEmit: function (particle, key) + { + if (particle && particle.data[key]) + { + var data = particle.data[key]; + + data.min = this.start; + data.max = this.end; + } + + return this.start; + }, + + /** + * An `onUpdate` callback that returns an eased value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + * + * @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The T value (between 0 and 1) + * + * @return {number} The new value of the property. + */ + easeValueUpdate: function (particle, key, t) + { + var data = particle.data[key]; + + return (data.max - data.min) * this.ease(t) + data.min; + } +}); + +module.exports = EmitterOp; + + +/***/ }), +/* 444 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * The GravityWell action applies a force on the particle to draw it towards, or repel it from, a single point. + * + * The force applied is inversely proportional to the square of the distance from the particle to the point, in accordance with Newton's law of gravity. + * + * This simulates the effect of gravity over large distances (as between planets, for example). + * + * @class GravityWell + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {(number|Phaser.Types.GameObjects.Particles.GravityWellConfig)} [x=0] - The x coordinate of the Gravity Well, in world space. + * @param {number} [y=0] - The y coordinate of the Gravity Well, in world space. + * @param {number} [power=0] - The strength of the gravity force - larger numbers produce a stronger force. + * @param {number} [epsilon=100] - The minimum distance for which the gravity force is calculated. + * @param {number} [gravity=50] - The gravitational force of this Gravity Well. + */ +var GravityWell = new Class({ + + initialize: + + function GravityWell (x, y, power, epsilon, gravity) + { + if (typeof x === 'object') + { + var config = x; + + x = GetFastValue(config, 'x', 0); + y = GetFastValue(config, 'y', 0); + power = GetFastValue(config, 'power', 0); + epsilon = GetFastValue(config, 'epsilon', 100); + gravity = GetFastValue(config, 'gravity', 50); + } + else + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (power === undefined) { power = 0; } + if (epsilon === undefined) { epsilon = 100; } + if (gravity === undefined) { gravity = 50; } + } + + /** + * The x coordinate of the Gravity Well, in world space. + * + * @name Phaser.GameObjects.Particles.GravityWell#x + * @type {number} + * @since 3.0.0 + */ + this.x = x; + + /** + * The y coordinate of the Gravity Well, in world space. + * + * @name Phaser.GameObjects.Particles.GravityWell#y + * @type {number} + * @since 3.0.0 + */ + this.y = y; + + /** + * The active state of the Gravity Well. An inactive Gravity Well will not influence any particles. + * + * @name Phaser.GameObjects.Particles.GravityWell#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Internal gravity value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_gravity + * @type {number} + * @private + * @since 3.0.0 + */ + this._gravity = gravity; + + /** + * Internal power value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_power + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._power = 0; + + /** + * Internal epsilon value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_epsilon + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._epsilon = 0; + + /** + * The strength of the gravity force - larger numbers produce a stronger force. + * + * @name Phaser.GameObjects.Particles.GravityWell#power + * @type {number} + * @since 3.0.0 + */ + this.power = power; + + /** + * The minimum distance for which the gravity force is calculated. + * + * @name Phaser.GameObjects.Particles.GravityWell#epsilon + * @type {number} + * @since 3.0.0 + */ + this.epsilon = epsilon; + }, + + /** + * Takes a Particle and updates it based on the properties of this Gravity Well. + * + * @method Phaser.GameObjects.Particles.GravityWell#update + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update. + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + */ + update: function (particle, delta) + { + var x = this.x - particle.x; + var y = this.y - particle.y; + var dSq = x * x + y * y; + + if (dSq === 0) + { + return; + } + + var d = Math.sqrt(dSq); + + if (dSq < this._epsilon) + { + dSq = this._epsilon; + } + + var factor = ((this._power * delta) / (dSq * d)) * 100; + + particle.velocityX += x * factor; + particle.velocityY += y * factor; + }, + + epsilon: { + + get: function () + { + return Math.sqrt(this._epsilon); + }, + + set: function (value) + { + this._epsilon = value * value; + } + + }, + + power: { + + get: function () + { + return this._power / this._gravity; + }, + + set: function (value) + { + this._power = value * this._gravity; + } + + }, + + gravity: { + + get: function () + { + return this._gravity; + }, + + set: function (value) + { + var pwr = this.power; + this._gravity = value; + this.power = pwr; + } + + } + +}); + +module.exports = GravityWell; + + +/***/ }), +/* 445 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var DistanceBetween = __webpack_require__(48); + +/** + * @classdesc + * A Particle is a simple Game Object controlled by a Particle Emitter and Manager, and rendered by the Manager. + * It uses its own lightweight physics system, and can interact only with its Emitter's bounds and zones. + * + * @class Particle + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. + */ +var Particle = new Class({ + + initialize: + + function Particle (emitter) + { + /** + * The Emitter to which this Particle belongs. + * + * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. + * + * @name Phaser.GameObjects.Particles.Particle#emitter + * @type {Phaser.GameObjects.Particles.ParticleEmitter} + * @since 3.0.0 + */ + this.emitter = emitter; + + /** + * The texture frame used to render this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#frame + * @type {Phaser.Textures.Frame} + * @default null + * @since 3.0.0 + */ + this.frame = null; + + /** + * The x coordinate of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; + + /** + * The y coordinate of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; + + /** + * The x velocity of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#velocityX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.velocityX = 0; + + /** + * The y velocity of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#velocityY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.velocityY = 0; + + /** + * The x acceleration of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#accelerationX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.accelerationX = 0; + + /** + * The y acceleration of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#accelerationY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.accelerationY = 0; + + /** + * The maximum horizontal velocity this Particle can travel at. + * + * @name Phaser.GameObjects.Particles.Particle#maxVelocityX + * @type {number} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityX = 10000; + + /** + * The maximum vertical velocity this Particle can travel at. + * + * @name Phaser.GameObjects.Particles.Particle#maxVelocityY + * @type {number} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityY = 10000; + + /** + * The bounciness, or restitution, of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#bounce + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.bounce = 0; + + /** + * The horizontal scale of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#scaleX + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.scaleX = 1; + + /** + * The vertical scale of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#scaleY + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.scaleY = 1; + + /** + * The alpha value of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#alpha + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.alpha = 1; + + /** + * The angle of this Particle in degrees. + * + * @name Phaser.GameObjects.Particles.Particle#angle + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angle = 0; + + /** + * The angle of this Particle in radians. + * + * @name Phaser.GameObjects.Particles.Particle#rotation + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.rotation = 0; + + /** + * The tint applied to this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#tint + * @type {number} + * @webglOnly + * @since 3.0.0 + */ + this.tint = 0xffffff; + + /** + * The lifespan of this Particle in ms. + * + * @name Phaser.GameObjects.Particles.Particle#life + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.life = 1000; + + /** + * The current life of this Particle in ms. + * + * @name Phaser.GameObjects.Particles.Particle#lifeCurrent + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.lifeCurrent = 1000; + + /** + * The delay applied to this Particle upon emission, in ms. + * + * @name Phaser.GameObjects.Particles.Particle#delayCurrent + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.delayCurrent = 0; + + /** + * The normalized lifespan T value, where 0 is the start and 1 is the end. + * + * @name Phaser.GameObjects.Particles.Particle#lifeT + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lifeT = 0; + + /** + * The data used by the ease equation. + * + * @name Phaser.GameObjects.Particles.Particle#data + * @type {object} + * @since 3.0.0 + */ + this.data = { + tint: { min: 0xffffff, max: 0xffffff, current: 0xffffff }, + alpha: { min: 1, max: 1 }, + rotate: { min: 0, max: 0 }, + scaleX: { min: 1, max: 1 }, + scaleY: { min: 1, max: 1 } + }; + }, + + /** + * Checks to see if this Particle is alive and updating. + * + * @method Phaser.GameObjects.Particles.Particle#isAlive + * @since 3.0.0 + * + * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. + */ + isAlive: function () + { + return (this.lifeCurrent > 0); + }, + + /** + * Resets the position of this particle back to zero. + * + * @method Phaser.GameObjects.Particles.Particle#resetPosition + * @since 3.16.0 + */ + resetPosition: function () + { + this.x = 0; + this.y = 0; + }, + + /** + * Starts this Particle from the given coordinates. + * + * @method Phaser.GameObjects.Particles.Particle#fire + * @since 3.0.0 + * + * @param {number} x - The x coordinate to launch this Particle from. + * @param {number} y - The y coordinate to launch this Particle from. + */ + fire: function (x, y) + { + var emitter = this.emitter; + + this.frame = emitter.getFrame(); + + if (emitter.emitZone) + { + // Updates particle.x and particle.y during this call + emitter.emitZone.getPoint(this); + } + + if (x === undefined) + { + this.x += emitter.x.onEmit(this, 'x'); + } + else + { + this.x += x; + } + + if (y === undefined) + { + this.y += emitter.y.onEmit(this, 'y'); + } + else + { + this.y += y; + } + + this.life = emitter.lifespan.onEmit(this, 'lifespan'); + this.lifeCurrent = this.life; + this.lifeT = 0; + + var sx = emitter.speedX.onEmit(this, 'speedX'); + var sy = (emitter.speedY) ? emitter.speedY.onEmit(this, 'speedY') : sx; + + if (emitter.radial) + { + var rad = DegToRad(emitter.angle.onEmit(this, 'angle')); + + this.velocityX = Math.cos(rad) * Math.abs(sx); + this.velocityY = Math.sin(rad) * Math.abs(sy); + } + else if (emitter.moveTo) + { + var mx = emitter.moveToX.onEmit(this, 'moveToX'); + var my = (emitter.moveToY) ? emitter.moveToY.onEmit(this, 'moveToY') : mx; + + var angle = Math.atan2(my - this.y, mx - this.x); + + var speed = DistanceBetween(this.x, this.y, mx, my) / (this.life / 1000); + + // We know how many pixels we need to move, but how fast? + // var speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000); + + this.velocityX = Math.cos(angle) * speed; + this.velocityY = Math.sin(angle) * speed; + } + else + { + this.velocityX = sx; + this.velocityY = sy; + } + + if (emitter.acceleration) + { + this.accelerationX = emitter.accelerationX.onEmit(this, 'accelerationX'); + this.accelerationY = emitter.accelerationY.onEmit(this, 'accelerationY'); + } + + this.maxVelocityX = emitter.maxVelocityX.onEmit(this, 'maxVelocityX'); + this.maxVelocityY = emitter.maxVelocityY.onEmit(this, 'maxVelocityY'); + + this.delayCurrent = emitter.delay.onEmit(this, 'delay'); + + this.scaleX = emitter.scaleX.onEmit(this, 'scaleX'); + this.scaleY = (emitter.scaleY) ? emitter.scaleY.onEmit(this, 'scaleY') : this.scaleX; + + this.angle = emitter.rotate.onEmit(this, 'rotate'); + this.rotation = DegToRad(this.angle); + + this.bounce = emitter.bounce.onEmit(this, 'bounce'); + + this.alpha = emitter.alpha.onEmit(this, 'alpha'); + + this.tint = emitter.tint.onEmit(this, 'tint'); + }, + + /** + * An internal method that calculates the velocity of the Particle. + * + * @method Phaser.GameObjects.Particles.Particle#computeVelocity + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle. + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + * @param {array} processors - Particle processors (gravity wells). + */ + computeVelocity: function (emitter, delta, step, processors) + { + var vx = this.velocityX; + var vy = this.velocityY; + + var ax = this.accelerationX; + var ay = this.accelerationY; + + var mx = this.maxVelocityX; + var my = this.maxVelocityY; + + vx += (emitter.gravityX * step); + vy += (emitter.gravityY * step); + + if (ax) + { + vx += (ax * step); + } + + if (ay) + { + vy += (ay * step); + } + + if (vx > mx) + { + vx = mx; + } + else if (vx < -mx) + { + vx = -mx; + } + + if (vy > my) + { + vy = my; + } + else if (vy < -my) + { + vy = -my; + } + + this.velocityX = vx; + this.velocityY = vy; + + // Apply any additional processors + for (var i = 0; i < processors.length; i++) + { + processors[i].update(this, delta, step); + } + }, + + /** + * Checks if this Particle is still within the bounds defined by the given Emitter. + * + * If not, and depending on the Emitter collision flags, the Particle may either stop or rebound. + * + * @method Phaser.GameObjects.Particles.Particle#checkBounds + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against. + */ + checkBounds: function (emitter) + { + var bounds = emitter.bounds; + var bounce = -this.bounce; + + if (this.x < bounds.x && emitter.collideLeft) + { + this.x = bounds.x; + this.velocityX *= bounce; + } + else if (this.x > bounds.right && emitter.collideRight) + { + this.x = bounds.right; + this.velocityX *= bounce; + } + + if (this.y < bounds.y && emitter.collideTop) + { + this.y = bounds.y; + this.velocityY *= bounce; + } + else if (this.y > bounds.bottom && emitter.collideBottom) + { + this.y = bounds.bottom; + this.velocityY *= bounce; + } + }, + + /** + * The main update method for this Particle. + * + * Updates its life values, computes the velocity and repositions the Particle. + * + * @method Phaser.GameObjects.Particles.Particle#update + * @since 3.0.0 + * + * @param {number} delta - The delta time in ms. + * @param {number} step - The delta value divided by 1000. + * @param {array} processors - An optional array of update processors. + * + * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. + */ + update: function (delta, step, processors) + { + if (this.delayCurrent > 0) + { + this.delayCurrent -= delta; + + return false; + } + + var emitter = this.emitter; + + // How far along in life is this particle? (t = 0 to 1) + var t = 1 - (this.lifeCurrent / this.life); + + this.lifeT = t; + + this.computeVelocity(emitter, delta, step, processors); + + this.x += this.velocityX * step; + this.y += this.velocityY * step; + + if (emitter.bounds) + { + this.checkBounds(emitter); + } + + if (emitter.deathZone && emitter.deathZone.willKill(this)) + { + this.lifeCurrent = 0; + + // No need to go any further, particle has been killed + return true; + } + + this.scaleX = emitter.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); + + if (emitter.scaleY) + { + this.scaleY = emitter.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); + } + else + { + this.scaleY = this.scaleX; + } + + this.angle = emitter.rotate.onUpdate(this, 'rotate', t, this.angle); + this.rotation = DegToRad(this.angle); + + this.alpha = emitter.alpha.onUpdate(this, 'alpha', t, this.alpha); + + this.tint = emitter.tint.onUpdate(this, 'tint', t, this.tint); + + this.lifeCurrent -= delta; + + return (this.lifeCurrent <= 0); + } + +}); + +module.exports = Particle; + + +/***/ }), +/* 446 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BlendModes = __webpack_require__(33); +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var DeathZone = __webpack_require__(447); +var EdgeZone = __webpack_require__(448); +var EmitterOp = __webpack_require__(443); +var GetFastValue = __webpack_require__(2); +var GetRandom = __webpack_require__(207); +var HasAny = __webpack_require__(449); +var HasValue = __webpack_require__(125); +var Particle = __webpack_require__(445); +var RandomZone = __webpack_require__(450); +var Rectangle = __webpack_require__(10); +var StableSort = __webpack_require__(79); +var Vector2 = __webpack_require__(3); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * A particle emitter represents a single particle stream. + * It controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles} and is controlled by a {@link Phaser.GameObjects.Particles.ParticleEmitterManager Particle Emitter Manager}. + * + * @class ParticleEmitter + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} manager - The Emitter Manager this Emitter belongs to. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + */ +var ParticleEmitter = new Class({ + + Mixins: [ + Components.BlendMode, + Components.Mask, + Components.ScrollFactor, + Components.Visible + ], + + initialize: + + function ParticleEmitter (manager, config) + { + /** + * The Emitter Manager this Emitter belongs to. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#manager + * @type {Phaser.GameObjects.Particles.ParticleEmitterManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * The texture assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#texture + * @type {Phaser.Textures.Texture} + * @since 3.0.0 + */ + this.texture = manager.texture; + + /** + * The texture frames assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frames + * @type {Phaser.Textures.Frame[]} + * @since 3.0.0 + */ + this.frames = [ manager.defaultFrame ]; + + /** + * The default texture frame assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#defaultFrame + * @type {Phaser.Textures.Frame} + * @since 3.0.0 + */ + this.defaultFrame = manager.defaultFrame; + + /** + * Names of simple configuration properties. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#configFastMap + * @type {object} + * @since 3.0.0 + */ + this.configFastMap = [ + 'active', + 'blendMode', + 'collideBottom', + 'collideLeft', + 'collideRight', + 'collideTop', + 'deathCallback', + 'deathCallbackScope', + 'emitCallback', + 'emitCallbackScope', + 'follow', + 'frequency', + 'gravityX', + 'gravityY', + 'maxParticles', + 'name', + 'on', + 'particleBringToTop', + 'particleClass', + 'radial', + 'timeScale', + 'trackVisible', + 'visible' + ]; + + /** + * Names of complex configuration properties. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#configOpMap + * @type {object} + * @since 3.0.0 + */ + this.configOpMap = [ + 'accelerationX', + 'accelerationY', + 'angle', + 'alpha', + 'bounce', + 'delay', + 'lifespan', + 'maxVelocityX', + 'maxVelocityY', + 'moveToX', + 'moveToY', + 'quantity', + 'rotate', + 'scaleX', + 'scaleY', + 'speedX', + 'speedY', + 'tint', + 'x', + 'y' + ]; + + /** + * The name of this Particle Emitter. + * + * Empty by default and never populated by Phaser, this is left for developers to use. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#name + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.name = ''; + + /** + * The Particle Class which will be emitted by this Emitter. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass + * @type {Phaser.GameObjects.Particles.Particle} + * @default Phaser.GameObjects.Particles.Particle + * @since 3.0.0 + */ + this.particleClass = Particle; + + /** + * The x-coordinate of the particle origin (where particles will be emitted). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#x + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + */ + this.x = new EmitterOp(config, 'x', 0, true); + + /** + * The y-coordinate of the particle origin (where particles will be emitted). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#y + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + */ + this.y = new EmitterOp(config, 'y', 0, true); + + /** + * A radial emitter will emit particles in all directions between angle min and max, + * using {@link Phaser.GameObjects.Particles.ParticleEmitter#speed} as the value. If set to false then this acts as a point Emitter. + * A point emitter will emit particles only in the direction derived from the speedX and speedY values. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#radial + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial + */ + this.radial = true; + + /** + * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + */ + this.gravityX = 0; + + /** + * Vertical acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + */ + this.gravityY = 0; + + /** + * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#acceleration + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.acceleration = false; + + /** + * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.accelerationX = new EmitterOp(config, 'accelerationX', 0, true); + + /** + * Vertical acceleration applied to emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.accelerationY = new EmitterOp(config, 'accelerationY', 0, true); + + /** + * The maximum horizontal velocity of emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityX = new EmitterOp(config, 'maxVelocityX', 10000, true); + + /** + * The maximum vertical velocity of emitted particles, in pixels per second squared. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 10000 + * @since 3.0.0 + */ + this.maxVelocityY = new EmitterOp(config, 'maxVelocityY', 10000, true); + + /** + * The initial horizontal speed of emitted particles, in pixels per second. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX + */ + this.speedX = new EmitterOp(config, 'speedX', 0, true); + + /** + * The initial vertical speed of emitted particles, in pixels per second. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY + */ + this.speedY = new EmitterOp(config, 'speedY', 0, true); + + /** + * Whether moveToX and moveToY are nonzero. Set automatically during configuration. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveTo + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.moveTo = false; + + /** + * The x-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.moveToX = new EmitterOp(config, 'moveToX', 0, true); + + /** + * The y-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.moveToY = new EmitterOp(config, 'moveToY', 0, true); + + /** + * Whether particles will rebound when they meet the emitter bounds. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#bounce + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.bounce = new EmitterOp(config, 'bounce', 0, true); + + /** + * The horizontal scale of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleX + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleX + */ + this.scaleX = new EmitterOp(config, 'scaleX', 1); + + /** + * The vertical scale of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#scaleY + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @see Phaser.GameObjects.Particles.ParticleEmitter#setScaleY + */ + this.scaleY = new EmitterOp(config, 'scaleY', 1); + + /** + * Color tint applied to emitted particles. Value must not include the alpha channel. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#tint + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0xffffff + * @since 3.0.0 + */ + this.tint = new EmitterOp(config, 'tint', 0xffffff); + + /** + * The alpha (transparency) of emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#alpha + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAlpha + */ + this.alpha = new EmitterOp(config, 'alpha', 1); + + /** + * The lifespan of emitted particles, in ms. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1000 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setLifespan + */ + this.lifespan = new EmitterOp(config, 'lifespan', 1000, true); + + /** + * The angle of the initial velocity of emitted particles, in degrees. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#angle + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default { min: 0, max: 360 } + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAngle + */ + this.angle = new EmitterOp(config, 'angle', { min: 0, max: 360 }, true); + + /** + * The rotation of emitted particles, in degrees. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#rotate + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.rotate = new EmitterOp(config, 'rotate', 0); + + /** + * A function to call when a particle is emitted. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} + * @default null + * @since 3.0.0 + */ + this.emitCallback = null; + + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 + */ + this.emitCallbackScope = null; + + /** + * A function to call when a particle dies. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleDeathCallback} + * @default null + * @since 3.0.0 + */ + this.deathCallback = null; + + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 + */ + this.deathCallbackScope = null; + + /** + * Set to hard limit the amount of particle objects this emitter is allowed to create. + * 0 means unlimited. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxParticles + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxParticles = 0; + + /** + * How many particles are emitted each time particles are emitted (one explosion or one flow cycle). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#quantity + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + */ + this.quantity = new EmitterOp(config, 'quantity', 1, true); + + /** + * How many ms to wait after emission before the particles start updating. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#delay + * @type {Phaser.GameObjects.Particles.EmitterOp} + * @default 0 + * @since 3.0.0 + */ + this.delay = new EmitterOp(config, 'delay', 0, true); + + /** + * For a flow emitter, the time interval (>= 0) between particle flow cycles in ms. + * A value of 0 means there is one particle flow cycle for each logic update (the maximum flow frequency). This is the default setting. + * For an exploding emitter, this value will be -1. + * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} also puts the emitter in flow mode (frequency >= 0). + * Calling {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} also puts the emitter in explode mode (frequency = -1). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frequency + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + */ + this.frequency = 0; + + /** + * Controls if the emitter is currently emitting a particle flow (when frequency >= 0). + * Already alive particles will continue to update until they expire. + * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#start} and {@link Phaser.GameObjects.Particles.ParticleEmitter#stop}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#on + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.on = true; + + /** + * Newly emitted particles are added to the top of the particle list, i.e. rendered above those already alive. + * Set to false to send them to the back. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.particleBringToTop = true; + + /** + * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * An object describing a shape to emit particles from. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitZone + * @type {?Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone + */ + this.emitZone = null; + + /** + * An object describing a shape that deactivates particles when they interact with it. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathZone + * @type {?Phaser.GameObjects.Particles.Zones.DeathZone} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone + */ + this.deathZone = null; + + /** + * A rectangular boundary constraining particle movement. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#bounds + * @type {?Phaser.Geom.Rectangle} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setBounds + */ + this.bounds = null; + + /** + * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideLeft + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideLeft = true; + + /** + * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideRight + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideRight = true; + + /** + * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideTop + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideTop = true; + + /** + * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#collideBottom + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.collideBottom = true; + + /** + * Whether this emitter updates itself and its particles. + * + * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#pause} + * and {@link Phaser.GameObjects.Particles.ParticleEmitter#resume}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Set this to false to hide any active particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#visible + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setVisible + */ + this.visible = true; + + /** + * The blend mode of this emitter's particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#blendMode + * @type {number} + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setBlendMode + */ + this.blendMode = BlendModes.NORMAL; + + /** + * A Game Object whose position is used as the particle origin. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#follow + * @type {?Phaser.GameObjects.GameObject} + * @default null + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + * @see Phaser.GameObjects.Particles.ParticleEmitter#stopFollow + */ + this.follow = null; + + /** + * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#followOffset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + */ + this.followOffset = new Vector2(); + + /** + * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track + * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#trackVisible + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow + */ + this.trackVisible = false; + + /** + * The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.currentFrame = 0; + + /** + * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#randomFrame + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.randomFrame = true; + + /** + * The number of consecutive particles that receive a single texture frame (per frame cycle). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity + * @type {number} + * @default 1 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrame + */ + this.frameQuantity = 1; + + /** + * Inactive particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#dead + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.dead = []; + + /** + * Active particles + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#alive + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.alive = []; + + /** + * The time until the next flow cycle. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#_counter + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._counter = 0; + + /** + * Counts up to {@link Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#_frameCounter + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._frameCounter = 0; + + if (config) + { + this.fromJSON(config); + } + }, + + /** + * Merges configuration settings into the emitter's current settings. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#fromJSON + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + * + * @return {this} This Particle Emitter. + */ + fromJSON: function (config) + { + if (!config) + { + return this; + } + + // Only update properties from their current state if they exist in the given config + + var i = 0; + var key = ''; + + for (i = 0; i < this.configFastMap.length; i++) + { + key = this.configFastMap[i]; + + if (HasValue(config, key)) + { + this[key] = GetFastValue(config, key); + } + } + + for (i = 0; i < this.configOpMap.length; i++) + { + key = this.configOpMap[i]; + + if (HasValue(config, key)) + { + this[key].loadConfig(config); + } + } + + this.acceleration = (this.accelerationX.propertyValue !== 0 || this.accelerationY.propertyValue !== 0); + + this.moveTo = (this.moveToX.propertyValue !== 0 || this.moveToY.propertyValue !== 0); + + // Special 'speed' override + + if (HasValue(config, 'speed')) + { + this.speedX.loadConfig(config, 'speed'); + this.speedY = null; + } + + // If you specify speedX, speedY or moveTo then it changes the emitter from radial to a point emitter + if (HasAny(config, [ 'speedX', 'speedY' ]) || this.moveTo) + { + this.radial = false; + } + + // Special 'scale' override + + if (HasValue(config, 'scale')) + { + this.scaleX.loadConfig(config, 'scale'); + this.scaleY = null; + } + + if (HasValue(config, 'callbackScope')) + { + var callbackScope = GetFastValue(config, 'callbackScope', null); + + this.emitCallbackScope = callbackScope; + this.deathCallbackScope = callbackScope; + } + + if (HasValue(config, 'emitZone')) + { + this.setEmitZone(config.emitZone); + } + + if (HasValue(config, 'deathZone')) + { + this.setDeathZone(config.deathZone); + } + + if (HasValue(config, 'bounds')) + { + this.setBounds(config.bounds); + } + + if (HasValue(config, 'followOffset')) + { + this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); + } + + if (HasValue(config, 'frame')) + { + this.setFrame(config.frame); + } + + if (HasValue(config, 'reserve')) + { + this.reserve(config.reserve); + } + + return this; + }, + + /** + * Creates a description of this emitter suitable for JSON serialization. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON + * @since 3.0.0 + * + * @param {object} [output] - An object to copy output into. + * + * @return {object} - The output object. + */ + toJSON: function (output) + { + if (output === undefined) { output = {}; } + + var i = 0; + var key = ''; + + for (i = 0; i < this.configFastMap.length; i++) + { + key = this.configFastMap[i]; + + output[key] = this[key]; + } + + for (i = 0; i < this.configOpMap.length; i++) + { + key = this.configOpMap[i]; + + if (this[key]) + { + output[key] = this[key].toJSON(); + } + } + + // special handlers + if (!this.speedY) + { + delete output.speedX; + output.speed = this.speedX.toJSON(); + } + + if (!this.scaleY) + { + delete output.scaleX; + output.scale = this.scaleX.toJSON(); + } + + return output; + }, + + /** + * Continuously moves the particle origin to follow a Game Object's position. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} target - The Game Object to follow. + * @param {number} [offsetX=0] - Horizontal offset of the particle origin from the Game Object. + * @param {number} [offsetY=0] - Vertical offset of the particle origin from the Game Object. + * @param {boolean} [trackVisible=false] - Whether the emitter's visible state will track the target's visible state. + * + * @return {this} This Particle Emitter. + */ + startFollow: function (target, offsetX, offsetY, trackVisible) + { + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } + if (trackVisible === undefined) { trackVisible = false; } + + this.follow = target; + this.followOffset.set(offsetX, offsetY); + this.trackVisible = trackVisible; + + return this; + }, + + /** + * Stops following a Game Object. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + stopFollow: function () + { + this.follow = null; + this.followOffset.set(0, 0); + this.trackVisible = false; + + return this; + }, + + /** + * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame + * @since 3.0.0 + * + * @return {Phaser.Textures.Frame} The texture frame. + */ + getFrame: function () + { + if (this.frames.length === 1) + { + return this.defaultFrame; + } + else if (this.randomFrame) + { + return GetRandom(this.frames); + } + else + { + var frame = this.frames[this.currentFrame]; + + this._frameCounter++; + + if (this._frameCounter === this.frameQuantity) + { + this._frameCounter = 0; + this.currentFrame = Wrap(this.currentFrame + 1, 0, this._frameLength); + } + + return frame; + } + }, + + // frame: 0 + // frame: 'red' + // frame: [ 0, 1, 2, 3 ] + // frame: [ 'red', 'green', 'blue', 'pink', 'white' ] + // frame: { frames: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } + + /** + * Sets a pattern for assigning texture frames to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrame + * @since 3.0.0 + * + * @param {(array|string|number|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} frames - One or more texture frames, or a configuration object. + * @param {boolean} [pickRandom=true] - Whether frames should be assigned at random from `frames`. + * @param {number} [quantity=1] - The number of consecutive particles that will receive each frame. + * + * @return {this} This Particle Emitter. + */ + setFrame: function (frames, pickRandom, quantity) + { + if (pickRandom === undefined) { pickRandom = true; } + if (quantity === undefined) { quantity = 1; } + + this.randomFrame = pickRandom; + this.frameQuantity = quantity; + this.currentFrame = 0; + this._frameCounter = 0; + + var t = typeof (frames); + + if (Array.isArray(frames) || t === 'string' || t === 'number') + { + this.manager.setEmitterFrames(frames, this); + } + else if (t === 'object') + { + var frameConfig = frames; + + frames = GetFastValue(frameConfig, 'frames', null); + + if (frames) + { + this.manager.setEmitterFrames(frames, this); + } + + var isCycle = GetFastValue(frameConfig, 'cycle', false); + + this.randomFrame = (isCycle) ? false : true; + + this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); + } + + this._frameLength = this.frames.length; + + if (this._frameLength === 1) + { + this.frameQuantity = 1; + this.randomFrame = false; + } + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial + * @since 3.0.0 + * + * @param {boolean} [value=true] - Radial mode (true) or point mode (true). + * + * @return {this} This Particle Emitter. + */ + setRadial: function (value) + { + if (value === undefined) { value = true; } + + this.radial = value; + + return this; + }, + + /** + * Sets the position of the emitter's particle origin. + * New particles will be emitted here. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setPosition + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} x - The x-coordinate of the particle origin. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} y - The y-coordinate of the particle origin. + * + * @return {this} This Particle Emitter. + */ + setPosition: function (x, y) + { + this.x.onChange(x); + this.y.onChange(y); + + return this; + }, + + /** + * Sets or modifies a rectangular boundary constraining the particles. + * + * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setBounds + * @since 3.0.0 + * + * @param {(number|Phaser.Types.GameObjects.Particles.ParticleEmitterBounds|Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt)} x - The x-coordinate of the left edge of the boundary, or an object representing a rectangle. + * @param {number} y - The y-coordinate of the top edge of the boundary. + * @param {number} width - The width of the boundary. + * @param {number} height - The height of the boundary. + * + * @return {this} This Particle Emitter. + */ + setBounds: function (x, y, width, height) + { + if (typeof x === 'object') + { + var obj = x; + + x = obj.x; + y = obj.y; + width = (HasValue(obj, 'w')) ? obj.w : obj.width; + height = (HasValue(obj, 'h')) ? obj.h : obj.height; + } + + if (this.bounds) + { + this.bounds.setTo(x, y, width, height); + } + else + { + this.bounds = new Rectangle(x, y, width, height); + } + + return this; + }, + + /** + * Sets the initial horizontal speed of emitted particles. + * Changes the emitter to point mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeedX: function (value) + { + this.speedX.onChange(value); + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = false; + + return this; + }, + + /** + * Sets the initial vertical speed of emitted particles. + * Changes the emitter to point mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeedY: function (value) + { + if (this.speedY) + { + this.speedY.onChange(value); + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = false; + } + + return this; + }, + + /** + * Sets the initial radial speed of emitted particles. + * Changes the emitter to radial mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeed + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The speed, in pixels per second. + * + * @return {this} This Particle Emitter. + */ + setSpeed: function (value) + { + this.speedX.onChange(value); + this.speedY = null; + + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = true; + + return this; + }, + + /** + * Sets the horizontal scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleX + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScaleX: function (value) + { + this.scaleX.onChange(value); + + return this; + }, + + /** + * Sets the vertical scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleY + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScaleY: function (value) + { + this.scaleY.onChange(value); + + return this; + }, + + /** + * Sets the scale of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - The scale, relative to 1. + * + * @return {this} This Particle Emitter. + */ + setScale: function (value) + { + this.scaleX.onChange(value); + this.scaleY = null; + + return this; + }, + + /** + * Sets the horizontal gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityX + * @since 3.0.0 + * + * @param {number} value - Acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravityX: function (value) + { + this.gravityX = value; + + return this; + }, + + /** + * Sets the vertical gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityY + * @since 3.0.0 + * + * @param {number} value - Acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravityY: function (value) + { + this.gravityY = value; + + return this; + }, + + /** + * Sets the gravity applied to emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravity + * @since 3.0.0 + * + * @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. + * @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. + * + * @return {this} This Particle Emitter. + */ + setGravity: function (x, y) + { + this.gravityX = x; + this.gravityY = y; + + return this; + }, + + /** + * Sets the opacity of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setAlpha + * @since 3.0.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 (transparent) and 1 (opaque). + * + * @return {this} This Particle Emitter. + */ + setAlpha: function (value) + { + this.alpha.onChange(value); + + return this; + }, + + /** + * Sets the color tint of emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setTint + * @since 3.22.0 + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff. + * + * @return {this} This Particle Emitter. + */ + setTint: function (value) + { + this.tint.onChange(value); + + return this; + }, + + /** + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. + * + * @return {this} This Particle Emitter. + */ + setEmitterAngle: function (value) + { + this.angle.onChange(value); + + return this; + }, + + /** + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setAngle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles. + * + * @return {this} This Particle Emitter. + */ + setAngle: function (value) + { + this.angle.onChange(value); + + return this; + }, + + /** + * Sets the lifespan of newly emitted particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setLifespan + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The particle lifespan, in ms. + * + * @return {this} This Particle Emitter. + */ + setLifespan: function (value) + { + this.lifespan.onChange(value); + + return this; + }, + + /** + * Sets the number of particles released at each flow cycle or explosion. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} quantity - The number of particles to release at each flow cycle or explosion. + * + * @return {this} This Particle Emitter. + */ + setQuantity: function (quantity) + { + this.quantity.onChange(quantity); + + return this; + }, + + /** + * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} + * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @since 3.0.0 + * + * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [quantity] - The number of particles to release at each flow cycle or explosion. + * + * @return {this} This Particle Emitter. + */ + setFrequency: function (frequency, quantity) + { + this.frequency = frequency; + + this._counter = 0; + + if (quantity) + { + this.quantity.onChange(quantity); + } + + return this; + }, + + /** + * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#emitZone}. + * + * An {@link Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig EdgeZone} places particles on its edges. Its {@link Phaser.Types.GameObjects.Particles.EdgeZoneSource source} can be a Curve, Path, Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback getPoints} method. + * + * A {@link Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig RandomZone} places randomly within its interior. Its {@link RandomZoneSource source} can be a Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.RandomZoneSourceCallback getRandomPoint} method. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current emit zone. + * + * @return {this} This Particle Emitter. + */ + setEmitZone: function (zoneConfig) + { + if (zoneConfig === undefined) + { + this.emitZone = null; + } + else + { + // Where source = Geom like Circle, or a Path or Curve + // emitZone: { type: 'random', source: X } + // emitZone: { type: 'edge', source: X, quantity: 32, [stepRate=0], [yoyo=false], [seamless=true] } + + var type = GetFastValue(zoneConfig, 'type', 'random'); + var source = GetFastValue(zoneConfig, 'source', null); + + switch (type) + { + case 'random': + + this.emitZone = new RandomZone(source); + + break; + + case 'edge': + + var quantity = GetFastValue(zoneConfig, 'quantity', 1); + var stepRate = GetFastValue(zoneConfig, 'stepRate', 0); + var yoyo = GetFastValue(zoneConfig, 'yoyo', false); + var seamless = GetFastValue(zoneConfig, 'seamless', true); + + this.emitZone = new EdgeZone(source, quantity, stepRate, yoyo, seamless); + + break; + } + } + + return this; + }, + + /** + * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig} [zoneConfig] - An object describing the zone, or `undefined` to remove any current death zone. + * + * @return {this} This Particle Emitter. + */ + setDeathZone: function (zoneConfig) + { + if (zoneConfig === undefined) + { + this.deathZone = null; + } + else + { + // Where source = Geom like Circle or Rect that supports a 'contains' function + // deathZone: { type: 'onEnter', source: X } + // deathZone: { type: 'onLeave', source: X } + + var type = GetFastValue(zoneConfig, 'type', 'onEnter'); + var source = GetFastValue(zoneConfig, 'source', null); + + if (source && typeof source.contains === 'function') + { + var killOnEnter = (type === 'onEnter') ? true : false; + + this.deathZone = new DeathZone(source, killOnEnter); + } + } + + return this; + }, + + /** + * Creates inactive particles and adds them to this emitter's pool. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve + * @since 3.0.0 + * + * @param {number} particleCount - The number of particles to create. + * + * @return {this} This Particle Emitter. + */ + reserve: function (particleCount) + { + var dead = this.dead; + + for (var i = 0; i < particleCount; i++) + { + dead.push(new this.particleClass(this)); + } + + return this; + }, + + /** + * Gets the number of active (in-use) particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles with `active=true`. + */ + getAliveParticleCount: function () + { + return this.alive.length; + }, + + /** + * Gets the number of inactive (available) particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles with `active=false`. + */ + getDeadParticleCount: function () + { + return this.dead.length; + }, + + /** + * Gets the total number of particles in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount + * @since 3.0.0 + * + * @return {number} The number of particles, including both alive and dead. + */ + getParticleCount: function () + { + return this.getAliveParticleCount() + this.getDeadParticleCount(); + }, + + /** + * Whether this emitter is at its limit (if set). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit + * @since 3.0.0 + * + * @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level. + */ + atLimit: function () + { + return (this.maxParticles > 0 && this.getParticleCount() === this.maxParticles); + }, + + /** + * Sets a function to call for each newly emitted particle. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} [context] - The calling context. + * + * @return {this} This Particle Emitter. + */ + onParticleEmit: function (callback, context) + { + if (callback === undefined) + { + // Clear any previously set callback + this.emitCallback = null; + this.emitCallbackScope = null; + } + else if (typeof callback === 'function') + { + this.emitCallback = callback; + + if (context) + { + this.emitCallbackScope = context; + } + } + + return this; + }, + + /** + * Sets a function to call for each particle death. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleDeathCallback} callback - The function. + * @param {*} [context] - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + onParticleDeath: function (callback, context) + { + if (callback === undefined) + { + // Clear any previously set callback + this.deathCallback = null; + this.deathCallbackScope = null; + } + else if (typeof callback === 'function') + { + this.deathCallback = callback; + + if (context) + { + this.deathCallbackScope = context; + } + } + + return this; + }, + + /** + * Deactivates every particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + killAll: function () + { + var dead = this.dead; + var alive = this.alive; + + while (alive.length > 0) + { + dead.push(alive.pop()); + } + + return this; + }, + + /** + * Calls a function for each active particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + forEachAlive: function (callback, context) + { + var alive = this.alive; + var length = alive.length; + + for (var index = 0; index < length; ++index) + { + // Sends the Particle and the Emitter + callback.call(context, alive[index], this); + } + + return this; + }, + + /** + * Calls a function for each inactive particle in this emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The function's calling context. + * + * @return {this} This Particle Emitter. + */ + forEachDead: function (callback, context) + { + var dead = this.dead; + var length = dead.length; + + for (var index = 0; index < length; ++index) + { + // Sends the Particle and the Emitter + callback.call(context, dead[index], this); + } + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on} the emitter and resets the flow counter. + * + * If this emitter is in flow mode (frequency >= 0; the default), the particle flow will start (or restart). + * + * If this emitter is in explode mode (frequency = -1), nothing will happen. + * Use {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} or {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} instead. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#start + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + start: function () + { + this.on = true; + + this._counter = 0; + + return this; + }, + + /** + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#stop + * @since 3.11.0 + * + * @return {this} This Particle Emitter. + */ + stop: function () + { + this.on = false; + + return this; + }, + + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#pause + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + pause: function () + { + this.active = false; + + return this; + }, + + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#resume + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + resume: function () + { + this.active = true; + + return this; + }, + + /** + * Removes the emitter from its manager and the scene. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#remove + * @since 3.22.0 + * + * @return {this} This Particle Emitter. + */ + remove: function () + { + this.manager.removeEmitter(this); + + return this; + }, + + /** + * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort + * @since 3.0.0 + * + * @return {this} This Particle Emitter. + */ + depthSort: function () + { + StableSort(this.alive, this.depthSortCallback); + + return this; + }, + + /** + * Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow. + * + * To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#flow + * @since 3.0.0 + * + * @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [count=1] - The number of particles to emit at each flow cycle. + * + * @return {this} This Particle Emitter. + */ + flow: function (frequency, count) + { + if (count === undefined) { count = 1; } + + this.frequency = frequency; + + this.quantity.onChange(count); + + return this.start(); + }, + + /** + * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#explode + * @since 3.0.0 + * + * @param {number} count - The amount of Particles to emit. + * @param {number} x - The x coordinate to emit the Particles from. + * @param {number} y - The y coordinate to emit the Particles from. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + */ + explode: function (count, x, y) + { + this.frequency = -1; + + return this.emitParticle(count, x, y); + }, + + /** + * Emits particles at a given position (or the emitter's current position). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt + * @since 3.0.0 + * + * @param {number} [x=this.x] - The x coordinate to emit the Particles from. + * @param {number} [y=this.x] - The y coordinate to emit the Particles from. + * @param {number} [count=this.quantity] - The number of Particles to emit. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + */ + emitParticleAt: function (x, y, count) + { + return this.emitParticle(count, x, y); + }, + + /** + * Emits particles at a given position (or the emitter's current position). + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle + * @since 3.0.0 + * + * @param {number} [count=this.quantity] - The number of Particles to emit. + * @param {number} [x=this.x] - The x coordinate to emit the Particles from. + * @param {number} [y=this.x] - The y coordinate to emit the Particles from. + * + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + * + * @see Phaser.GameObjects.Particles.Particle#fire + */ + emitParticle: function (count, x, y) + { + if (this.atLimit()) + { + return; + } + + if (count === undefined) + { + count = this.quantity.onEmit(); + } + + var dead = this.dead; + + var followX = (this.follow) ? this.follow.x + this.followOffset.x : x; + var followY = (this.follow) ? this.follow.y + this.followOffset.y : y; + + for (var i = 0; i < count; i++) + { + var particle = dead.pop(); + + if (!particle) + { + particle = new this.particleClass(this); + } + + particle.fire(followX, followY); + + if (this.particleBringToTop) + { + this.alive.push(particle); + } + else + { + this.alive.unshift(particle); + } + + if (this.emitCallback) + { + this.emitCallback.call(this.emitCallbackScope, particle, this); + } + + if (this.atLimit()) + { + break; + } + } + + return particle; + }, + + /** + * Updates this emitter and its particles. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) + { + // Scale the delta + delta *= this.timeScale; + + var step = (delta / 1000); + + if (this.trackVisible) + { + this.visible = this.follow.visible; + } + + // Any particle processors? + var processors = this.manager.getProcessors(); + + var particles = this.alive; + var dead = this.dead; + + var i = 0; + var rip = []; + var length = particles.length; + + for (i = 0; i < length; i++) + { + var particle = particles[i]; + + // update returns `true` if the particle is now dead (lifeCurrent <= 0) + if (particle.update(delta, step, processors)) + { + rip.push({ index: i, particle: particle }); + } + } + + // Move dead particles to the dead array + length = rip.length; + + if (length > 0) + { + var deathCallback = this.deathCallback; + var deathCallbackScope = this.deathCallbackScope; + + for (i = length - 1; i >= 0; i--) + { + var entry = rip[i]; + + // Remove from particles array + particles.splice(entry.index, 1); + + // Add to dead array + dead.push(entry.particle); + + // Callback + if (deathCallback) + { + deathCallback.call(deathCallbackScope, entry.particle); + } + + entry.particle.resetPosition(); + } + } + + if (!this.on) + { + return; + } + + if (this.frequency === 0) + { + this.emitParticle(); + } + else if (this.frequency > 0) + { + this._counter -= delta; + + if (this._counter <= 0) + { + this.emitParticle(); + + // counter = frequency - remained from previous delta + this._counter = (this.frequency - Math.abs(this._counter)); + } + } + }, + + /** + * Calculates the difference of two particles, for sorting them by depth. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback + * @since 3.0.0 + * + * @param {object} a - The first particle. + * @param {object} b - The second particle. + * + * @return {number} The difference of a and b's y coordinates. + */ + depthSortCallback: function (a, b) + { + return a.y - b.y; + } + +}); + +module.exports = ParticleEmitter; + + +/***/ }), +/* 447 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A Death Zone. + * + * A Death Zone is a special type of zone that will kill a Particle as soon as it either enters, or leaves, the zone. + * + * The zone consists of a `source` which could be a Geometric shape, such as a Rectangle or Ellipse, or your own + * object as long as it includes a `contains` method for which the Particles can be tested against. + * + * @class DeathZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.DeathZoneSource} source - An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. + * @param {boolean} killOnEnter - Should the Particle be killed when it enters the zone? `true` or leaves it? `false` + */ +var DeathZone = new Class({ + + initialize: + + function DeathZone (source, killOnEnter) + { + /** + * An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. + * This could be a Geometry shape, such as `Phaser.Geom.Circle`, or your own custom object. + * + * @name Phaser.GameObjects.Particles.Zones.DeathZone#source + * @type {Phaser.Types.GameObjects.Particles.DeathZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * Set to `true` if the Particle should be killed if it enters this zone. + * Set to `false` to kill the Particle if it leaves this zone. + * + * @name Phaser.GameObjects.Particles.Zones.DeathZone#killOnEnter + * @type {boolean} + * @since 3.0.0 + */ + this.killOnEnter = killOnEnter; + }, + + /** + * Checks if the given Particle will be killed or not by this zone. + * + * @method Phaser.GameObjects.Particles.Zones.DeathZone#willKill + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to be checked against this zone. + * + * @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`. + */ + willKill: function (particle) + { + var withinZone = this.source.contains(particle.x, particle.y); + + return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); + } + +}); + +module.exports = DeathZone; + + +/***/ }), +/* 448 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * A zone that places particles on a shape's edges. + * + * @class EdgeZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * @param {number} quantity - The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * @param {number} stepRate - The distance between each particle. When set, `quantity` is implied and should be set to 0. + * @param {boolean} [yoyo=false] - Whether particles are placed from start to end and then end to start. + * @param {boolean} [seamless=true] - Whether one endpoint will be removed if it's identical to the other. + */ +var EdgeZone = new Class({ + + initialize: + + function EdgeZone (source, quantity, stepRate, yoyo, seamless) + { + if (yoyo === undefined) { yoyo = false; } + if (seamless === undefined) { seamless = true; } + + /** + * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source + * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * The points placed on the source edge. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points + * @type {Phaser.Geom.Point[]} + * @default [] + * @since 3.0.0 + */ + this.points = []; + + /** + * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#quantity + * @type {number} + * @since 3.0.0 + */ + this.quantity = quantity; + + /** + * The distance between each particle. When set, `quantity` is implied and should be set to 0. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#stepRate + * @type {number} + * @since 3.0.0 + */ + this.stepRate = stepRate; + + /** + * Whether particles are placed from start to end and then end to start. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#yoyo + * @type {boolean} + * @since 3.0.0 + */ + this.yoyo = yoyo; + + /** + * The counter used for iterating the EdgeZone's points. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.counter = -1; + + /** + * Whether one endpoint will be removed if it's identical to the other. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless + * @type {boolean} + * @since 3.0.0 + */ + this.seamless = seamless; + + /** + * An internal count of the points belonging to this EdgeZone. + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_length + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._length = 0; + + /** + * An internal value used to keep track of the current iteration direction for the EdgeZone's points. + * + * 0 = forwards, 1 = backwards + * + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_direction + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._direction = 0; + + this.updateSource(); + }, + + /** + * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's + * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. + * + * Also updates internal properties. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource + * @since 3.0.0 + * + * @return {this} This Edge Zone. + */ + updateSource: function () + { + this.points = this.source.getPoints(this.quantity, this.stepRate); + + // Remove ends? + if (this.seamless) + { + var a = this.points[0]; + var b = this.points[this.points.length - 1]; + + if (a.x === b.x && a.y === b.y) + { + this.points.pop(); + } + } + + var oldLength = this._length; + + this._length = this.points.length; + + // Adjust counter if we now have less points than before + if (this._length < oldLength && this.counter > this._length) + { + this.counter = this._length - 1; + } + + return this; + }, + + /** + * Change the source of the EdgeZone. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * + * @return {this} This Edge Zone. + */ + changeSource: function (source) + { + this.source = source; + + return this.updateSource(); + }, + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. + */ + getPoint: function (particle) + { + if (this._direction === 0) + { + this.counter++; + + if (this.counter >= this._length) + { + if (this.yoyo) + { + this._direction = 1; + this.counter = this._length - 1; + } + else + { + this.counter = 0; + } + } + } + else + { + this.counter--; + + if (this.counter === -1) + { + if (this.yoyo) + { + this._direction = 0; + this.counter = 0; + } + else + { + this.counter = this._length - 1; + } + } + } + + var point = this.points[this.counter]; + + if (point) + { + particle.x = point.x; + particle.y = point.y; + } + } + +}); + +module.exports = EdgeZone; + + +/***/ }), +/* 449 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Verifies that an object contains at least one of the requested keys + * + * @function Phaser.Utils.Objects.HasAny + * @since 3.0.0 + * + * @param {object} source - an object on which to check for key existence + * @param {string[]} keys - an array of keys to search the object for + * + * @return {boolean} true if the source object contains at least one of the keys, false otherwise + */ +var HasAny = function (source, keys) +{ + for (var i = 0; i < keys.length; i++) + { + if (source.hasOwnProperty(keys[i])) + { + return true; + } + } + + return false; +}; + +module.exports = HasAny; + + +/***/ }), +/* 450 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A zone that places particles randomly within a shapes area. + * + * @class RandomZone + * @memberof Phaser.GameObjects.Particles.Zones + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.RandomZoneSource} source - An object instance with a `getRandomPoint(point)` method. + */ +var RandomZone = new Class({ + + initialize: + + function RandomZone (source) + { + /** + * An object instance with a `getRandomPoint(point)` method. + * + * @name Phaser.GameObjects.Particles.Zones.RandomZone#source + * @type {Phaser.Types.GameObjects.Particles.RandomZoneSource} + * @since 3.0.0 + */ + this.source = source; + + /** + * Internal calculation vector. + * + * @name Phaser.GameObjects.Particles.Zones.RandomZone#_tempVec + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tempVec = new Vector2(); + }, + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * + * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. + */ + getPoint: function (particle) + { + var vec = this._tempVec; + + this.source.getRandomPoint(vec); + + particle.x = vec.x; + particle.y = vec.y; + } + +}); + +module.exports = RandomZone; + + +/***/ }), +/* 451 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var Sprite = __webpack_require__(73); + +/** + * @classdesc + * A PathFollower Game Object. + * + * A PathFollower is a Sprite Game Object with some extra helpers to allow it to follow a Path automatically. + * + * Anything you can do with a standard Sprite can be done with this PathFollower, such as animate it, tint it, + * scale it and so on. + * + * PathFollowers are bound to a single Path at any one time and can traverse the length of the Path, from start + * to finish, forwards or backwards, or from any given point on the Path to its end. They can optionally rotate + * to face the direction of the path, be offset from the path coordinates or rotate independently of the Path. + * + * @class PathFollower + * @extends Phaser.GameObjects.Sprite + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.PathFollower + * + * @param {Phaser.Scene} scene - The Scene to which this PathFollower belongs. + * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. + * @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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + */ +var PathFollower = new Class({ + + Extends: Sprite, + + Mixins: [ + Components.PathFollower + ], + + initialize: + + function PathFollower (scene, path, x, y, texture, frame) + { + Sprite.call(this, scene, x, y, texture, frame); + + this.path = path; + }, + + /** + * 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.PathFollower#preUpdate + * @protected + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) + { + this.anims.update(time, delta); + this.pathUpdate(time); + } + +}); + +module.exports = PathFollower; + + +/***/ }), +/* 452 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns an object containing dimensions of the Text object. + * + * @function Phaser.GameObjects.GetTextSize + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Text} text - The Text object to calculate the size from. + * @param {Phaser.Types.GameObjects.Text.TextMetrics} size - The Text metrics to use when calculating the size. + * @param {string[]} lines - The lines of text to calculate the size from. + * + * @return {Phaser.Types.GameObjects.Text.GetTextSizeObject} An object containing dimensions of the Text object. + */ +var GetTextSize = function (text, size, lines) +{ + var canvas = text.canvas; + var context = text.context; + var style = text.style; + + var lineWidths = []; + var maxLineWidth = 0; + var drawnLines = lines.length; + + if (style.maxLines > 0 && style.maxLines < lines.length) + { + drawnLines = style.maxLines; + } + + style.syncFont(canvas, context); + + // Text Width + + for (var i = 0; i < drawnLines; i++) + { + var lineWidth = style.strokeThickness; + + lineWidth += context.measureText(lines[i]).width; + + // Adjust for wrapped text + if (style.wordWrap) + { + lineWidth -= context.measureText(' ').width; + } + + lineWidths[i] = Math.ceil(lineWidth); + maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); + } + + // Text Height + + var lineHeight = size.fontSize + style.strokeThickness; + var height = lineHeight * drawnLines; + var lineSpacing = text.lineSpacing; + + // Adjust for line spacing + if (drawnLines > 1) + { + height += lineSpacing * (drawnLines - 1); + } + + return { + width: maxLineWidth, + height: height, + lines: drawnLines, + lineWidths: lineWidths, + lineSpacing: lineSpacing, + lineHeight: lineHeight + }; +}; + +module.exports = GetTextSize; + + +/***/ }), +/* 453 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetAdvancedValue = __webpack_require__(13); +var GetValue = __webpack_require__(6); +var MeasureText = __webpack_require__(454); + +// Key: [ Object Key, Default Value ] + +var propertyMap = { + fontFamily: [ 'fontFamily', 'Courier' ], + fontSize: [ 'fontSize', '16px' ], + fontStyle: [ 'fontStyle', '' ], + backgroundColor: [ 'backgroundColor', null ], + color: [ 'color', '#fff' ], + stroke: [ 'stroke', '#fff' ], + strokeThickness: [ 'strokeThickness', 0 ], + shadowOffsetX: [ 'shadow.offsetX', 0 ], + shadowOffsetY: [ 'shadow.offsetY', 0 ], + shadowColor: [ 'shadow.color', '#000' ], + shadowBlur: [ 'shadow.blur', 0 ], + shadowStroke: [ 'shadow.stroke', false ], + shadowFill: [ 'shadow.fill', false ], + align: [ 'align', 'left' ], + maxLines: [ 'maxLines', 0 ], + fixedWidth: [ 'fixedWidth', 0 ], + fixedHeight: [ 'fixedHeight', 0 ], + resolution: [ 'resolution', 0 ], + rtl: [ 'rtl', false ], + testString: [ 'testString', '|MÉqgy' ], + baselineX: [ 'baselineX', 1.2 ], + baselineY: [ 'baselineY', 1.4 ], + wordWrapWidth: [ 'wordWrap.width', null ], + wordWrapCallback: [ 'wordWrap.callback', null ], + wordWrapCallbackScope: [ 'wordWrap.callbackScope', null ], + wordWrapUseAdvanced: [ 'wordWrap.useAdvancedWrap', false ] +}; + +/** + * @classdesc + * A TextStyle class manages all of the style settings for a Text object. + * + * Text Game Objects create a TextStyle instance automatically, which is + * accessed via the `Text.style` property. You do not normally need to + * instantiate one yourself. + * + * @class TextStyle + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Text} text - The Text object that this TextStyle is styling. + * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. + */ +var TextStyle = new Class({ + + initialize: + + function TextStyle (text, style) + { + /** + * The Text object that this TextStyle is styling. + * + * @name Phaser.GameObjects.TextStyle#parent + * @type {Phaser.GameObjects.Text} + * @since 3.0.0 + */ + this.parent = text; + + /** + * The font family. + * + * @name Phaser.GameObjects.TextStyle#fontFamily + * @type {string} + * @default 'Courier' + * @since 3.0.0 + */ + this.fontFamily; + + /** + * The font size. + * + * @name Phaser.GameObjects.TextStyle#fontSize + * @type {string} + * @default '16px' + * @since 3.0.0 + */ + this.fontSize; + + /** + * The font style. + * + * @name Phaser.GameObjects.TextStyle#fontStyle + * @type {string} + * @since 3.0.0 + */ + this.fontStyle; + + /** + * The background color. + * + * @name Phaser.GameObjects.TextStyle#backgroundColor + * @type {string} + * @since 3.0.0 + */ + this.backgroundColor; + + /** + * The text fill color. + * + * @name Phaser.GameObjects.TextStyle#color + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.color; + + /** + * The text stroke color. + * + * @name Phaser.GameObjects.TextStyle#stroke + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.stroke; + + /** + * The text stroke thickness. + * + * @name Phaser.GameObjects.TextStyle#strokeThickness + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.strokeThickness; + + /** + * The horizontal shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetX; + + /** + * The vertical shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetY; + + /** + * The shadow color. + * + * @name Phaser.GameObjects.TextStyle#shadowColor + * @type {string} + * @default '#000' + * @since 3.0.0 + */ + this.shadowColor; + + /** + * The shadow blur radius. + * + * @name Phaser.GameObjects.TextStyle#shadowBlur + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowBlur; + + /** + * Whether shadow stroke is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowStroke + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowStroke; + + /** + * Whether shadow fill is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowFill + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowFill; + + /** + * The text alignment. + * + * @name Phaser.GameObjects.TextStyle#align + * @type {string} + * @default 'left' + * @since 3.0.0 + */ + this.align; + + /** + * The maximum number of lines to draw. + * + * @name Phaser.GameObjects.TextStyle#maxLines + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxLines; + + /** + * The fixed width of the text. + * + * `0` means no fixed with. + * + * @name Phaser.GameObjects.TextStyle#fixedWidth + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.fixedWidth; + + /** + * The fixed height of the text. + * + * `0` means no fixed height. + * + * @name Phaser.GameObjects.TextStyle#fixedHeight + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.fixedHeight; + + /** + * The resolution the text is rendered to its internal canvas at. + * The default is 0, which means it will use the resolution set in the Game Config. + * + * @name Phaser.GameObjects.TextStyle#resolution + * @type {number} + * @default 0 + * @since 3.12.0 + */ + this.resolution; + + /** + * Whether the text should render right to left. + * + * @name Phaser.GameObjects.TextStyle#rtl + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.rtl; + + /** + * The test string to use when measuring the font. + * + * @name Phaser.GameObjects.TextStyle#testString + * @type {string} + * @default '|MÉqgy' + * @since 3.0.0 + */ + this.testString; + + /** + * The amount of horizontal padding added to the width of the text when calculating the font metrics. + * + * @name Phaser.GameObjects.TextStyle#baselineX + * @type {number} + * @default 1.2 + * @since 3.3.0 + */ + this.baselineX; + + /** + * The amount of vertical padding added to the height of the text when calculating the font metrics. + * + * @name Phaser.GameObjects.TextStyle#baselineY + * @type {number} + * @default 1.4 + * @since 3.3.0 + */ + this.baselineY; + + /** + * The maximum width of a line of text in pixels. Null means no line wrapping. Setting this + * property directly will not re-run the word wrapping algorithm. To change the width and + * re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapWidth + * @type {number | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapWidth; + + /** + * A custom function that will be responsible for wrapping the text. It will receive two + * arguments: text (the string to wrap), textObject (this Text instance). It should return + * the wrapped lines either as an array of lines or as a string with newline characters in + * place to indicate where breaks should happen. Setting this directly will not re-run the + * word wrapping algorithm. To change the callback and re-wrap, use + * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapCallback + * @type {TextStyleWordWrapCallback | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapCallback; + + /** + * The scope that will be applied when the wordWrapCallback is invoked. Setting this directly will not re-run the + * word wrapping algorithm. To change the callback and re-wrap, use + * {@link Phaser.GameObjects.TextStyle#setWordWrapCallback}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapCallbackScope + * @type {object | null} + * @default null + * @since 3.24.0 + */ + this.wordWrapCallbackScope; + + /** + * Whether or not to use the advanced wrapping algorithm. If true, spaces are collapsed and + * whitespace is trimmed from lines. If false, spaces and whitespace are left as is. Setting + * this property directly will not re-run the word wrapping algorithm. To change the + * advanced setting and re-wrap, use {@link Phaser.GameObjects.TextStyle#setWordWrapWidth}. + * + * @name Phaser.GameObjects.TextStyle#wordWrapUseAdvanced + * @type {boolean} + * @default false + * @since 3.24.0 + */ + this.wordWrapUseAdvanced; + + /** + * The font style, size and family. + * + * @name Phaser.GameObjects.TextStyle#_font + * @type {string} + * @private + * @since 3.0.0 + */ + this._font; + + // Set to defaults + user style + this.setStyle(style, false, true); + + var metrics = GetValue(style, 'metrics', false); + + // Provide optional TextMetrics in the style object to avoid the canvas look-up / scanning + // Doing this is reset if you then change the font of this TextStyle after creation + if (metrics) + { + this.metrics = { + ascent: GetValue(metrics, 'ascent', 0), + descent: GetValue(metrics, 'descent', 0), + fontSize: GetValue(metrics, 'fontSize', 0) + }; + } + else + { + this.metrics = MeasureText(this); + } + }, + + /** + * Set the text style. + * + * @example + * text.setStyle({ + * fontSize: '64px', + * fontFamily: 'Arial', + * color: '#ffffff', + * align: 'center', + * backgroundColor: '#ff00ff' + * }); + * + * @method Phaser.GameObjects.TextStyle#setStyle + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set. + * @param {boolean} [updateText=true] - Whether to update the text immediately. + * @param {boolean} [setDefaults=false] - Use the default values is not set, or the local values. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setStyle: function (style, updateText, setDefaults) + { + if (updateText === undefined) { updateText = true; } + if (setDefaults === undefined) { setDefaults = false; } + + // Avoid type mutation + // eslint-disable-next-line no-prototype-builtins + if (style && style.hasOwnProperty('fontSize') && typeof style.fontSize === 'number') + { + style.fontSize = style.fontSize.toString() + 'px'; + } + + for (var key in propertyMap) + { + var value = (setDefaults) ? propertyMap[key][1] : this[key]; + + if (key === 'wordWrapCallback' || key === 'wordWrapCallbackScope') + { + // Callback & scope should be set without processing the values + this[key] = GetValue(style, propertyMap[key][0], value); + } + else + { + this[key] = GetAdvancedValue(style, propertyMap[key][0], value); + } + } + + // Allow for 'font' override + var font = GetValue(style, 'font', null); + + if (font !== null) + { + this.setFont(font, false); + } + + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); + + // Allow for 'fill' to be used in place of 'color' + var fill = GetValue(style, 'fill', null); + + if (fill !== null) + { + this.color = fill; + } + + if (updateText) + { + return this.update(true); + } + else + { + return this.parent; + } + }, + + /** + * Synchronize the font settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncFont + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + */ + syncFont: function (canvas, context) + { + context.font = this._font; + }, + + /** + * Synchronize the text style settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncStyle + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + */ + syncStyle: function (canvas, context) + { + context.textBaseline = 'alphabetic'; + + context.fillStyle = this.color; + context.strokeStyle = this.stroke; + + context.lineWidth = this.strokeThickness; + context.lineCap = 'round'; + context.lineJoin = 'round'; + }, + + /** + * Synchronize the shadow settings to the given Canvas Rendering Context. + * + * @method Phaser.GameObjects.TextStyle#syncShadow + * @since 3.0.0 + * + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @param {boolean} enabled - Whether shadows are enabled or not. + */ + syncShadow: function (context, enabled) + { + if (enabled) + { + context.shadowOffsetX = this.shadowOffsetX; + context.shadowOffsetY = this.shadowOffsetY; + context.shadowColor = this.shadowColor; + context.shadowBlur = this.shadowBlur; + } + else + { + context.shadowOffsetX = 0; + context.shadowOffsetY = 0; + context.shadowColor = 0; + context.shadowBlur = 0; + } + }, + + /** + * Update the style settings for the parent Text object. + * + * @method Phaser.GameObjects.TextStyle#update + * @since 3.0.0 + * + * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + update: function (recalculateMetrics) + { + if (recalculateMetrics) + { + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); + + this.metrics = MeasureText(this); + } + + return this.parent.updateText(); + }, + + /** + * Set the font. + * + * If a string is given, the font family is set. + * + * If an object is given, the `fontFamily`, `fontSize` and `fontStyle` + * properties of that object are set. + * + * @method Phaser.GameObjects.TextStyle#setFont + * @since 3.0.0 + * + * @param {(string|object)} font - The font family or font settings to set. + * @param {boolean} [updateText=true] - Whether to update the text immediately. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFont: function (font, updateText) + { + if (updateText === undefined) { updateText = true; } + + var fontFamily = font; + var fontSize = ''; + var fontStyle = ''; + + if (typeof font !== 'string') + { + fontFamily = GetValue(font, 'fontFamily', 'Courier'); + fontSize = GetValue(font, 'fontSize', '16px'); + fontStyle = GetValue(font, 'fontStyle', ''); + } + else + { + var fontSplit = font.split(' '); + + var i = 0; + + fontStyle = (fontSplit.length > 2) ? fontSplit[i++] : ''; + fontSize = fontSplit[i++] || '16px'; + fontFamily = fontSplit[i++] || 'Courier'; + } + + if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) + { + this.fontFamily = fontFamily; + this.fontSize = fontSize; + this.fontStyle = fontStyle; + + if (updateText) + { + this.update(true); + } + } + + return this.parent; + }, + + /** + * Set the font family. + * + * @method Phaser.GameObjects.TextStyle#setFontFamily + * @since 3.0.0 + * + * @param {string} family - The font family. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontFamily: function (family) + { + if (this.fontFamily !== family) + { + this.fontFamily = family; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the font style. + * + * @method Phaser.GameObjects.TextStyle#setFontStyle + * @since 3.0.0 + * + * @param {string} style - The font style. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontStyle: function (style) + { + if (this.fontStyle !== style) + { + this.fontStyle = style; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the font size. + * + * @method Phaser.GameObjects.TextStyle#setFontSize + * @since 3.0.0 + * + * @param {(number|string)} size - The font size. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFontSize: function (size) + { + if (typeof size === 'number') + { + size = size.toString() + 'px'; + } + + if (this.fontSize !== size) + { + this.fontSize = size; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the test string to use when measuring the font. + * + * @method Phaser.GameObjects.TextStyle#setTestString + * @since 3.0.0 + * + * @param {string} string - The test string to use when measuring the font. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setTestString: function (string) + { + this.testString = string; + + return this.update(true); + }, + + /** + * Set a fixed width and height for the text. + * + * Pass in `0` for either of these parameters to disable fixed width or height respectively. + * + * @method Phaser.GameObjects.TextStyle#setFixedSize + * @since 3.0.0 + * + * @param {number} width - The fixed width to set. + * @param {number} height - The fixed height to set. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFixedSize: function (width, height) + { + this.fixedWidth = width; + this.fixedHeight = height; + + if (width) + { + this.parent.width = width; + } + + if (height) + { + this.parent.height = height; + } + + return this.update(false); + }, + + /** + * Set the background color. + * + * @method Phaser.GameObjects.TextStyle#setBackgroundColor + * @since 3.0.0 + * + * @param {string} color - The background color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setBackgroundColor: function (color) + { + this.backgroundColor = color; + + return this.update(false); + }, + + /** + * Set the text fill color. + * + * @method Phaser.GameObjects.TextStyle#setFill + * @since 3.0.0 + * + * @param {string} color - The text fill color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setFill: function (color) + { + this.color = color; + + return this.update(false); + }, + + /** + * Set the text fill color. + * + * @method Phaser.GameObjects.TextStyle#setColor + * @since 3.0.0 + * + * @param {string} color - The text fill color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setColor: function (color) + { + this.color = color; + + return this.update(false); + }, + + /** + * Set the resolution used by the Text object. + * + * By default it will be set to match the resolution set in the Game Config, + * but you can override it via this method. It allows for much clearer text on High DPI devices, + * at the cost of memory because it uses larger internal Canvas textures for the Text. + * + * Please use with caution, as the more high res Text you have, the more memory it uses up. + * + * @method Phaser.GameObjects.TextStyle#setResolution + * @since 3.12.0 + * + * @param {number} value - The resolution for this Text object to use. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setResolution: function (value) + { + this.resolution = value; + + return this.update(false); + }, + + /** + * Set the stroke settings. + * + * @method Phaser.GameObjects.TextStyle#setStroke + * @since 3.0.0 + * + * @param {string} color - The stroke color. + * @param {number} thickness - The stroke thickness. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setStroke: function (color, thickness) + { + if (thickness === undefined) { thickness = this.strokeThickness; } + + if (color === undefined && this.strokeThickness !== 0) + { + // Reset the stroke to zero (disabling it) + this.strokeThickness = 0; + + this.update(true); + } + else if (this.stroke !== color || this.strokeThickness !== thickness) + { + this.stroke = color; + this.strokeThickness = thickness; + + this.update(true); + } + + return this.parent; + }, + + /** + * Set the shadow settings. + * + * Calling this method always re-measures the parent Text object, + * so only call it when you actually change the shadow settings. + * + * @method Phaser.GameObjects.TextStyle#setShadow + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal shadow offset. + * @param {number} [y=0] - The vertical shadow offset. + * @param {string} [color='#000'] - The shadow color. + * @param {number} [blur=0] - The shadow blur radius. + * @param {boolean} [shadowStroke=false] - Whether to stroke the shadow. + * @param {boolean} [shadowFill=true] - Whether to fill the shadow. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadow: function (x, y, color, blur, shadowStroke, shadowFill) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (color === undefined) { color = '#000'; } + if (blur === undefined) { blur = 0; } + if (shadowStroke === undefined) { shadowStroke = false; } + if (shadowFill === undefined) { shadowFill = true; } + + this.shadowOffsetX = x; + this.shadowOffsetY = y; + this.shadowColor = color; + this.shadowBlur = blur; + this.shadowStroke = shadowStroke; + this.shadowFill = shadowFill; + + return this.update(false); + }, + + /** + * Set the shadow offset. + * + * @method Phaser.GameObjects.TextStyle#setShadowOffset + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal shadow offset. + * @param {number} [y=0] - The vertical shadow offset. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowOffset: function (x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this.shadowOffsetX = x; + this.shadowOffsetY = y; + + return this.update(false); + }, + + /** + * Set the shadow color. + * + * @method Phaser.GameObjects.TextStyle#setShadowColor + * @since 3.0.0 + * + * @param {string} [color='#000'] - The shadow color. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowColor: function (color) + { + if (color === undefined) { color = '#000'; } + + this.shadowColor = color; + + return this.update(false); + }, + + /** + * Set the shadow blur radius. + * + * @method Phaser.GameObjects.TextStyle#setShadowBlur + * @since 3.0.0 + * + * @param {number} [blur=0] - The shadow blur radius. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowBlur: function (blur) + { + if (blur === undefined) { blur = 0; } + + this.shadowBlur = blur; + + return this.update(false); + }, + + /** + * Enable or disable shadow stroke. + * + * @method Phaser.GameObjects.TextStyle#setShadowStroke + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow stroke is enabled or not. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowStroke: function (enabled) + { + this.shadowStroke = enabled; + + return this.update(false); + }, + + /** + * Enable or disable shadow fill. + * + * @method Phaser.GameObjects.TextStyle#setShadowFill + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow fill is enabled or not. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setShadowFill: function (enabled) + { + this.shadowFill = enabled; + + return this.update(false); + }, + + /** + * Set the width (in pixels) to use for wrapping lines. + * + * Pass in null to remove wrapping by width. + * + * @method Phaser.GameObjects.TextStyle#setWordWrapWidth + * @since 3.0.0 + * + * @param {number} width - The maximum width of a line in pixels. Set to null to remove wrapping. + * @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping + * algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false, + * spaces and whitespace are left as is. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setWordWrapWidth: function (width, useAdvancedWrap) + { + if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } + + this.wordWrapWidth = width; + this.wordWrapUseAdvanced = useAdvancedWrap; + + return this.update(false); + }, + + /** + * Set a custom callback for wrapping lines. + * + * Pass in null to remove wrapping by callback. + * + * @method Phaser.GameObjects.TextStyle#setWordWrapCallback + * @since 3.0.0 + * + * @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the + * text. It will receive two arguments: text (the string to wrap), textObject (this Text + * instance). It should return the wrapped lines either as an array of lines or as a string with + * newline characters in place to indicate where breaks should happen. + * @param {object} [scope=null] - The scope that will be applied when the callback is invoked. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setWordWrapCallback: function (callback, scope) + { + if (scope === undefined) { scope = null; } + + this.wordWrapCallback = callback; + this.wordWrapCallbackScope = scope; + + return this.update(false); + }, + + /** + * Set the alignment of the text in this Text object. + * + * The argument can be one of: `left`, `right`, `center` or `justify`. + * + * Alignment only works if the Text object has more than one line of text. + * + * @method Phaser.GameObjects.TextStyle#setAlign + * @since 3.0.0 + * + * @param {string} [align='left'] - The text alignment for multi-line text. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setAlign: function (align) + { + if (align === undefined) { align = 'left'; } + + this.align = align; + + return this.update(false); + }, + + /** + * Set the maximum number of lines to draw. + * + * @method Phaser.GameObjects.TextStyle#setMaxLines + * @since 3.0.0 + * + * @param {number} [max=0] - The maximum number of lines to draw. + * + * @return {Phaser.GameObjects.Text} The parent Text object. + */ + setMaxLines: function (max) + { + if (max === undefined) { max = 0; } + + this.maxLines = max; + + return this.update(false); + }, + + /** + * Get the current text metrics. + * + * @method Phaser.GameObjects.TextStyle#getTextMetrics + * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. + */ + getTextMetrics: function () + { + var metrics = this.metrics; + + return { + ascent: metrics.ascent, + descent: metrics.descent, + fontSize: metrics.fontSize + }; + }, + + /** + * Build a JSON representation of this Text Style. + * + * @method Phaser.GameObjects.TextStyle#toJSON + * @since 3.0.0 + * + * @return {object} A JSON representation of this Text Style. + */ + toJSON: function () + { + var output = {}; + + for (var key in propertyMap) + { + output[key] = this[key]; + } + + output.metrics = this.getTextMetrics(); + + return output; + }, + + /** + * Destroy this Text Style. + * + * @method Phaser.GameObjects.TextStyle#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.parent = undefined; + } + +}); + +module.exports = TextStyle; + + +/***/ }), +/* 454 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(31); + +/** + * Calculates the ascent, descent and fontSize of a given font style. + * + * @function Phaser.GameObjects.MeasureText + * @since 3.0.0 + * + * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. + * + * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. + */ +var MeasureText = function (textStyle) +{ + var canvas = CanvasPool.create(this); + var context = canvas.getContext('2d'); + + textStyle.syncFont(canvas, context); + + var metrics = context.measureText(textStyle.testString); + + if (metrics.hasOwnProperty('actualBoundingBoxAscent')) + { + var ascent = metrics.actualBoundingBoxAscent; + var descent = metrics.actualBoundingBoxDescent; + + CanvasPool.remove(canvas); + + return { + ascent: ascent, + descent: descent, + fontSize: ascent + descent + }; + } + + var width = Math.ceil(metrics.width * textStyle.baselineX); + var baseline = width; + var height = 2 * baseline; + + baseline = baseline * textStyle.baselineY | 0; + + canvas.width = width; + canvas.height = height; + + context.fillStyle = '#f00'; + context.fillRect(0, 0, width, height); + + context.font = textStyle._font; + + context.textBaseline = 'alphabetic'; + context.fillStyle = '#000'; + context.fillText(textStyle.testString, 0, baseline); + + var output = { + ascent: 0, + descent: 0, + fontSize: 0 + }; + + if (!context.getImageData(0, 0, width, height)) + { + output.ascent = baseline; + output.descent = baseline + 6; + output.fontSize = output.ascent + output.descent; + + CanvasPool.remove(canvas); + + return output; + } + + var imagedata = context.getImageData(0, 0, width, height).data; + var pixels = imagedata.length; + var line = width * 4; + var i; + var j; + var idx = 0; + var stop = false; + + // ascent. scan from top to bottom until we find a non red pixel + for (i = 0; i < baseline; i++) + { + for (j = 0; j < line; j += 4) + { + if (imagedata[idx + j] !== 255) + { + stop = true; + break; + } + } + + if (!stop) + { + idx += line; + } + else + { + break; + } + } + + output.ascent = baseline - i; + + idx = pixels - line; + stop = false; + + // descent. scan from bottom to top until we find a non red pixel + for (i = height; i > baseline; i--) + { + for (j = 0; j < line; j += 4) + { + if (imagedata[idx + j] !== 255) + { + stop = true; + break; + } + } + + if (!stop) + { + idx -= line; + } + else + { + break; + } + } + + output.descent = (i - baseline); + output.fontSize = output.ascent + output.descent; + + CanvasPool.remove(canvas); + + return output; +}; + +module.exports = MeasureText; + + +/***/ }), +/* 455 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcRender = __webpack_require__(1091); +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var Earcut = __webpack_require__(68); +var GeomCircle = __webpack_require__(62); +var MATH_CONST = __webpack_require__(14); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Arc Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * When it renders it displays an arc shape. You can control the start and end angles of the arc, + * as well as if the angles are winding clockwise or anti-clockwise. With the default settings + * it renders as a complete circle. By changing the angles you can create other arc shapes, + * such as half-circles. + * + * Arcs also have an `iterations` property and corresponding `setIterations` method. This allows + * you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. + * + * @class Arc + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [radius=128] - The radius of the arc. + * @param {number} [startAngle=0] - The start angle of the arc, in degrees. + * @param {number} [endAngle=360] - The end angle of the arc, in degrees. + * @param {boolean} [anticlockwise=false] - The winding order of the start and end angles. + * @param {number} [fillColor] - The color the arc will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Arc = new Class({ + + Extends: Shape, + + Mixins: [ + ArcRender + ], + + initialize: + + function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 128; } + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 360; } + if (anticlockwise === undefined) { anticlockwise = false; } + + Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius)); + + /** + * Private internal value. Holds the start angle in degrees. + * + * @name Phaser.GameObjects.Arc#_startAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._startAngle = startAngle; + + /** + * Private internal value. Holds the end angle in degrees. + * + * @name Phaser.GameObjects.Arc#_endAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._endAngle = endAngle; + + /** + * Private internal value. Holds the winding order of the start and end angles. + * + * @name Phaser.GameObjects.Arc#_anticlockwise + * @type {boolean} + * @private + * @since 3.13.0 + */ + this._anticlockwise = anticlockwise; + + /** + * Private internal value. Holds the number of iterations used when drawing the arc. + * + * @name Phaser.GameObjects.Arc#_iterations + * @type {number} + * @default 0.01 + * @private + * @since 3.13.0 + */ + this._iterations = 0.01; + + this.setPosition(x, y); + + var diameter = this.geom.radius * 2; + this.setSize(diameter, diameter); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * The number of iterations used when drawing the arc. + * Increase this value for smoother arcs, at the cost of more polygons being rendered. + * Modify this value by small amounts, such as 0.01. + * + * @name Phaser.GameObjects.Arc#iterations + * @type {number} + * @default 0.01 + * @since 3.13.0 + */ + iterations: { + + get: function () + { + return this._iterations; + }, + + set: function (value) + { + this._iterations = value; + + this.updateData(); + } + + }, + + /** + * The radius of the arc. + * + * @name Phaser.GameObjects.Arc#radius + * @type {number} + * @since 3.13.0 + */ + radius: { + + get: function () + { + return this.geom.radius; + }, + + set: function (value) + { + this.geom.radius = value; + + var diameter = value * 2; + this.setSize(diameter, diameter); + this.updateDisplayOrigin(); + this.updateData(); + } + + }, + + /** + * The start angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#startAngle + * @type {number} + * @since 3.13.0 + */ + startAngle: { + + get: function () + { + return this._startAngle; + }, + + set: function (value) + { + this._startAngle = value; + + this.updateData(); + } + + }, + + /** + * The end angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#endAngle + * @type {number} + * @since 3.13.0 + */ + endAngle: { + + get: function () + { + return this._endAngle; + }, + + set: function (value) + { + this._endAngle = value; + + this.updateData(); + } + + }, + + /** + * The winding order of the start and end angles. + * + * @name Phaser.GameObjects.Arc#anticlockwise + * @type {boolean} + * @since 3.13.0 + */ + anticlockwise: { + + get: function () + { + return this._anticlockwise; + }, + + set: function (value) + { + this._anticlockwise = value; + + this.updateData(); + } + + }, + + /** + * Sets the radius of the arc. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setRadius + * @since 3.13.0 + * + * @param {number} value - The value to set the radius to. + * + * @return {this} This Game Object instance. + */ + setRadius: function (value) + { + this.radius = value; + + return this; + }, + + /** + * Sets the number of iterations used when drawing the arc. + * Increase this value for smoother arcs, at the cost of more polygons being rendered. + * Modify this value by small amounts, such as 0.01. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setIterations + * @since 3.13.0 + * + * @param {number} value - The value to set the iterations to. + * + * @return {this} This Game Object instance. + */ + setIterations: function (value) + { + if (value === undefined) { value = 0.01; } + + this.iterations = value; + + return this; + }, + + /** + * Sets the starting angle of the arc, in degrees. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setStartAngle + * @since 3.13.0 + * + * @param {number} value - The value to set the starting angle to. + * + * @return {this} This Game Object instance. + */ + setStartAngle: function (angle, anticlockwise) + { + this._startAngle = angle; + + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } + + return this.updateData(); + }, + + /** + * Sets the ending angle of the arc, in degrees. + * This call can be chained. + * + * @method Phaser.GameObjects.Arc#setEndAngle + * @since 3.13.0 + * + * @param {number} value - The value to set the ending angle to. + * + * @return {this} This Game Object instance. + */ + setEndAngle: function (angle, anticlockwise) + { + this._endAngle = angle; + + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Arc#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var step = this._iterations; + var iteration = step; + + var radius = this.geom.radius; + var startAngle = DegToRad(this._startAngle); + var endAngle = DegToRad(this._endAngle); + var anticlockwise = this._anticlockwise; + + var x = radius; + var y = radius; + + endAngle -= startAngle; + + if (anticlockwise) + { + if (endAngle < -MATH_CONST.PI2) + { + endAngle = -MATH_CONST.PI2; + } + else if (endAngle > 0) + { + endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; + } + } + else if (endAngle > MATH_CONST.PI2) + { + endAngle = MATH_CONST.PI2; + } + else if (endAngle < 0) + { + endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; + } + + var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; + + var ta; + + while (iteration < 1) + { + ta = endAngle * iteration + startAngle; + + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + + iteration += step; + } + + ta = endAngle + startAngle; + + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + + path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Arc; + + +/***/ }), +/* 456 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CurveRender = __webpack_require__(1094); +var Earcut = __webpack_require__(68); +var Rectangle = __webpack_require__(10); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Curve Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to + * the Curve Shape in the constructor. + * + * The Curve shape also has a `smoothness` property and corresponding `setSmoothness` method. + * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. Increase and decrease the default value for smoother, or more + * jagged, shapes. + * + * @class Curve + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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.Curves.Curve} [curve] - The Curve object to use to create the Shape. + * @param {number} [fillColor] - The color the curve will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Curve = new Class({ + + Extends: Shape, + + Mixins: [ + CurveRender + ], + + initialize: + + function Curve (scene, x, y, curve, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + Shape.call(this, scene, 'Curve', curve); + + /** + * Private internal value. + * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. + * + * @name Phaser.GameObjects.Curve#_smoothness + * @type {number} + * @private + * @since 3.13.0 + */ + this._smoothness = 32; + + /** + * Private internal value. + * The Curve bounds rectangle. + * + * @name Phaser.GameObjects.Curve#_curveBounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.13.0 + */ + this._curveBounds = new Rectangle(); + + this.closePath = false; + + this.setPosition(x, y); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateData(); + }, + + /** + * The smoothness of the curve. The number of points used when rendering it. + * Increase this value for smoother curves, at the cost of more polygons being rendered. + * + * @name Phaser.GameObjects.Curve#smoothness + * @type {number} + * @default 32 + * @since 3.13.0 + */ + smoothness: { + + get: function () + { + return this._smoothness; + }, + + set: function (value) + { + this._smoothness = value; + + this.updateData(); + } + + }, + + /** + * Sets the smoothness of the curve. The number of points used when rendering it. + * Increase this value for smoother curves, at the cost of more polygons being rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.Curve#setSmoothness + * @since 3.13.0 + * + * @param {number} value - The value to set the smoothness to. + * + * @return {this} This Game Object instance. + */ + setSmoothness: function (value) + { + this._smoothness = value; + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Curve#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var bounds = this._curveBounds; + var smoothness = this._smoothness; + + // Update the bounds in case the underlying data has changed + this.geom.getBounds(bounds, smoothness); + + this.setSize(bounds.width, bounds.height); + this.updateDisplayOrigin(); + + var path = []; + var points = this.geom.getPoints(smoothness); + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Curve; + + +/***/ }), +/* 457 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var EllipseRender = __webpack_require__(1097); +var GeomEllipse = __webpack_require__(108); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * When it renders it displays an ellipse shape. You can control the width and height of the ellipse. + * If the width and height match it will render as a circle. If the width is less than the height, + * it will look more like an egg shape. + * + * The Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method. + * This allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations + * that take place during construction. Increase and decrease the default value for smoother, or more + * jagged, shapes. + * + * @class Ellipse + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [width=128] - The width of the ellipse. An ellipse with equal width and height renders as a circle. + * @param {number} [height=128] - The height of the ellipse. An ellipse with equal width and height renders as a circle. + * @param {number} [fillColor] - The color the ellipse will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Ellipse = new Class({ + + Extends: Shape, + + Mixins: [ + EllipseRender + ], + + initialize: + + function Ellipse (scene, x, y, width, height, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + + Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); + + /** + * Private internal value. + * The number of points used to draw the curve. Higher values create smoother renders at the cost of more triangles being drawn. + * + * @name Phaser.GameObjects.Ellipse#_smoothness + * @type {number} + * @private + * @since 3.13.0 + */ + this._smoothness = 64; + + this.setPosition(x, y); + + this.width = width; + this.height = height; + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * The smoothness of the ellipse. The number of points used when rendering it. + * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. + * + * @name Phaser.GameObjects.Ellipse#smoothness + * @type {number} + * @default 64 + * @since 3.13.0 + */ + smoothness: { + + get: function () + { + return this._smoothness; + }, + + set: function (value) + { + this._smoothness = value; + + this.updateData(); + } + + }, + + /** + * Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object. + * This call can be chained. + * + * @method Phaser.GameObjects.Ellipse#setSize + * @since 3.13.0 + * + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. + * + * @return {this} This Game Object instance. + */ + setSize: function (width, height) + { + this.width = width; + this.height = height; + this.geom.setPosition(width / 2, height / 2); + this.geom.setSize(width, height); + + return this.updateData(); + }, + + /** + * Sets the smoothness of the ellipse. The number of points used when rendering it. + * Increase this value for a smoother ellipse, at the cost of more polygons being rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.Ellipse#setSmoothness + * @since 3.13.0 + * + * @param {number} value - The value to set the smoothness to. + * + * @return {this} This Game Object instance. + */ + setSmoothness: function (value) + { + this._smoothness = value; + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Ellipse#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var points = this.geom.getPoints(this._smoothness); + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Ellipse; + + +/***/ }), +/* 458 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GridRender = __webpack_require__(1100); + +/** + * @classdesc + * The Grid Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * A Grid Shape allows you to display a grid in your game, where you can control the size of the + * grid as well as the width and height of the grid cells. You can set a fill color for each grid + * cell as well as an alternate fill color. When the alternate fill color is set then the grid + * cells will alternate the fill colors as they render, creating a chess-board effect. You can + * also optionally have an outline fill color. If set, this draws lines between the grid cells + * in the given color. If you specify an outline color with an alpha of zero, then it will draw + * the cells spaced out, but without the lines between them. + * + * @class Grid + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [width=128] - The width of the grid. + * @param {number} [height=128] - The height of the grid. + * @param {number} [cellWidth=32] - The width of one cell in the grid. + * @param {number} [cellHeight=32] - The height of one cell in the grid. + * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * @param {number} [outlineFillColor] - The color of the lines between the grid cells. See the `setOutline` method. + * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. + */ +var Grid = new Class({ + + Extends: Shape, + + Mixins: [ + GridRender + ], + + initialize: + + function Grid (scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + if (cellWidth === undefined) { cellWidth = 32; } + if (cellHeight === undefined) { cellHeight = 32; } + + Shape.call(this, scene, 'Grid', null); + + /** + * The width of each grid cell. + * Must be a positive value. + * + * @name Phaser.GameObjects.Grid#cellWidth + * @type {number} + * @since 3.13.0 + */ + this.cellWidth = cellWidth; + + /** + * The height of each grid cell. + * Must be a positive value. + * + * @name Phaser.GameObjects.Grid#cellHeight + * @type {number} + * @since 3.13.0 + */ + this.cellHeight = cellHeight; + + /** + * Will the grid render its cells in the `fillColor`? + * + * @name Phaser.GameObjects.Grid#showCells + * @type {boolean} + * @since 3.13.0 + */ + this.showCells = true; + + /** + * The color of the lines between each grid cell. + * + * @name Phaser.GameObjects.Grid#outlineFillColor + * @type {number} + * @since 3.13.0 + */ + this.outlineFillColor = 0; + + /** + * The alpha value for the color of the lines between each grid cell. + * + * @name Phaser.GameObjects.Grid#outlineFillAlpha + * @type {number} + * @since 3.13.0 + */ + this.outlineFillAlpha = 0; + + /** + * Will the grid display the lines between each cell when it renders? + * + * @name Phaser.GameObjects.Grid#showOutline + * @type {boolean} + * @since 3.13.0 + */ + this.showOutline = true; + + /** + * Will the grid render the alternating cells in the `altFillColor`? + * + * @name Phaser.GameObjects.Grid#showAltCells + * @type {boolean} + * @since 3.13.0 + */ + this.showAltCells = false; + + /** + * The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. + * + * @name Phaser.GameObjects.Grid#altFillColor + * @type {number} + * @since 3.13.0 + */ + this.altFillColor; + + /** + * The alpha the alternating grid cells will be filled with. + * You can also set the alpha of the overall Shape using its `alpha` property. + * + * @name Phaser.GameObjects.Grid#altFillAlpha + * @type {number} + * @since 3.13.0 + */ + this.altFillAlpha; + + this.setPosition(x, y); + this.setSize(width, height); + + this.setFillStyle(fillColor, fillAlpha); + + if (outlineFillColor !== undefined) + { + this.setOutlineStyle(outlineFillColor, outlineFillAlpha); + } + + this.updateDisplayOrigin(); + }, + + /** + * Sets the fill color and alpha level the grid cells will use when rendering. + * + * If this method is called with no values then the grid cells will not be rendered, + * however the grid lines and alternating cells may still be. + * + * Also see the `setOutlineStyle` and `setAltFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showCells = false; + } + else + { + this.fillColor = fillColor; + this.fillAlpha = fillAlpha; + this.showCells = true; + } + + return this; + }, + + /** + * Sets the fill color and alpha level that the alternating grid cells will use. + * + * If this method is called with no values then alternating grid cells will not be rendered in a different color. + * + * Also see the `setOutlineStyle` and `setFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setAltFillStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the alternating grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the alternating grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setAltFillStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showAltCells = false; + } + else + { + this.altFillColor = fillColor; + this.altFillAlpha = fillAlpha; + this.showAltCells = true; + } + + return this; + }, + + /** + * Sets the fill color and alpha level that the lines between each grid cell will use. + * + * If this method is called with no values then the grid lines will not be rendered at all, however + * the cells themselves may still be if they have colors set. + * + * Also see the `setFillStyle` and `setAltFillStyle` methods. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Grid#setOutlineStyle + * @since 3.13.0 + * + * @param {number} [fillColor] - The color the lines between the grid cells will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha=1] - The alpha the lines between the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {this} This Game Object instance. + */ + setOutlineStyle: function (fillColor, fillAlpha) + { + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showOutline = false; + } + else + { + this.outlineFillColor = fillColor; + this.outlineFillAlpha = fillAlpha; + this.showOutline = true; + } + + return this; + } + +}); + +module.exports = Grid; + + +/***/ }), +/* 459 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var IsoBoxRender = __webpack_require__(1103); +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The IsoBox Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * An IsoBox is an 'isometric' rectangle. Each face of it has a different fill color. You can set + * the color of the top, left and right faces of the rectangle respectively. You can also choose + * which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. + * + * You cannot view an IsoBox from under-neath, however you can change the 'angle' by setting + * the `projection` property. + * + * @class IsoBox + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [size=48] - The width of the iso box in pixels. The left and right faces will be exactly half this value. + * @param {number} [height=32] - The height of the iso box. The left and right faces will be this tall. The overall height of the isobox will be this value plus half the `size` value. + * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso box. + * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso box. + * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso box. + */ +var IsoBox = new Class({ + + Extends: Shape, + + Mixins: [ + IsoBoxRender + ], + + initialize: + + function IsoBox (scene, x, y, size, height, fillTop, fillLeft, fillRight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (size === undefined) { size = 48; } + if (height === undefined) { height = 32; } + if (fillTop === undefined) { fillTop = 0xeeeeee; } + if (fillLeft === undefined) { fillLeft = 0x999999; } + if (fillRight === undefined) { fillRight = 0xcccccc; } + + Shape.call(this, scene, 'IsoBox', null); + + /** + * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * + * @name Phaser.GameObjects.IsoBox#projection + * @type {number} + * @default 4 + * @since 3.13.0 + */ + this.projection = 4; + + /** + * The color used to fill in the top of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillTop + * @type {number} + * @since 3.13.0 + */ + this.fillTop = fillTop; + + /** + * The color used to fill in the left-facing side of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillLeft + * @type {number} + * @since 3.13.0 + */ + this.fillLeft = fillLeft; + + /** + * The color used to fill in the right-facing side of the iso box. + * + * @name Phaser.GameObjects.IsoBox#fillRight + * @type {number} + * @since 3.13.0 + */ + this.fillRight = fillRight; + + /** + * Controls if the top-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showTop + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showTop = true; + + /** + * Controls if the left-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showLeft + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showLeft = true; + + /** + * Controls if the right-face of the iso box be rendered. + * + * @name Phaser.GameObjects.IsoBox#showRight + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showRight = true; + + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); + }, + + /** + * Sets the projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setProjection + * @since 3.13.0 + * + * @param {number} value - The value to set the projection to. + * + * @return {this} This Game Object instance. + */ + setProjection: function (value) + { + this.projection = value; + + return this; + }, + + /** + * Sets which faces of the iso box will be rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setFaces + * @since 3.13.0 + * + * @param {boolean} [showTop=true] - Show the top-face of the iso box. + * @param {boolean} [showLeft=true] - Show the left-face of the iso box. + * @param {boolean} [showRight=true] - Show the right-face of the iso box. + * + * @return {this} This Game Object instance. + */ + setFaces: function (showTop, showLeft, showRight) + { + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } + + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; + + return this; + }, + + /** + * Sets the fill colors for each face of the iso box. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoBox#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillTop] - The color used to fill the top of the iso box. + * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso box. + * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso box. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillTop, fillLeft, fillRight) + { + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.isFilled = true; + + return this; + } + +}); + +module.exports = IsoBox; + + +/***/ }), +/* 460 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var IsoTriangleRender = __webpack_require__(1106); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The IsoTriangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only fill colors and cannot be stroked. + * + * An IsoTriangle is an 'isometric' triangle. Think of it like a pyramid. Each face has a different + * fill color. You can set the color of the top, left and right faces of the triangle respectively + * You can also choose which of the faces are rendered via the `showTop`, `showLeft` and `showRight` properties. + * + * You cannot view an IsoTriangle from under-neath, however you can change the 'angle' by setting + * the `projection` property. The `reversed` property controls if the IsoTriangle is rendered upside + * down or not. + * + * @class IsoTriangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [size=48] - The width of the iso triangle in pixels. The left and right faces will be exactly half this value. + * @param {number} [height=32] - The height of the iso triangle. The left and right faces will be this tall. The overall height of the iso triangle will be this value plus half the `size` value. + * @param {boolean} [reversed=false] - Is the iso triangle upside down? + * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso triangle. + * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso triangle. + * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso triangle. + */ +var IsoTriangle = new Class({ + + Extends: Shape, + + Mixins: [ + IsoTriangleRender + ], + + initialize: + + function IsoTriangle (scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (size === undefined) { size = 48; } + if (height === undefined) { height = 32; } + if (reversed === undefined) { reversed = false; } + if (fillTop === undefined) { fillTop = 0xeeeeee; } + if (fillLeft === undefined) { fillLeft = 0x999999; } + if (fillRight === undefined) { fillRight = 0xcccccc; } + + Shape.call(this, scene, 'IsoTriangle', null); + + /** + * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * + * @name Phaser.GameObjects.IsoTriangle#projection + * @type {number} + * @default 4 + * @since 3.13.0 + */ + this.projection = 4; + + /** + * The color used to fill in the top of the iso triangle. This is only used if the triangle is reversed. + * + * @name Phaser.GameObjects.IsoTriangle#fillTop + * @type {number} + * @since 3.13.0 + */ + this.fillTop = fillTop; + + /** + * The color used to fill in the left-facing side of the iso triangle. + * + * @name Phaser.GameObjects.IsoTriangle#fillLeft + * @type {number} + * @since 3.13.0 + */ + this.fillLeft = fillLeft; + + /** + * The color used to fill in the right-facing side of the iso triangle. + * + * @name Phaser.GameObjects.IsoTriangle#fillRight + * @type {number} + * @since 3.13.0 + */ + this.fillRight = fillRight; + + /** + * Controls if the top-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showTop + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showTop = true; + + /** + * Controls if the left-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showLeft + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showLeft = true; + + /** + * Controls if the right-face of the iso triangle be rendered. + * + * @name Phaser.GameObjects.IsoTriangle#showRight + * @type {boolean} + * @default true + * @since 3.13.0 + */ + this.showRight = true; + + /** + * Sets if the iso triangle will be rendered upside down or not. + * + * @name Phaser.GameObjects.IsoTriangle#isReversed + * @type {boolean} + * @default false + * @since 3.13.0 + */ + this.isReversed = reversed; + + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); + }, + + /** + * Sets the projection level of the iso triangle. Change this to change the 'angle' at which you are looking at the pyramid. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setProjection + * @since 3.13.0 + * + * @param {number} value - The value to set the projection to. + * + * @return {this} This Game Object instance. + */ + setProjection: function (value) + { + this.projection = value; + + return this; + }, + + /** + * Sets if the iso triangle will be rendered upside down or not. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setReversed + * @since 3.13.0 + * + * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. + * + * @return {this} This Game Object instance. + */ + setReversed: function (reversed) + { + this.isReversed = reversed; + + return this; + }, + + /** + * Sets which faces of the iso triangle will be rendered. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setFaces + * @since 3.13.0 + * + * @param {boolean} [showTop=true] - Show the top-face of the iso triangle (only if `reversed` is true) + * @param {boolean} [showLeft=true] - Show the left-face of the iso triangle. + * @param {boolean} [showRight=true] - Show the right-face of the iso triangle. + * + * @return {this} This Game Object instance. + */ + setFaces: function (showTop, showLeft, showRight) + { + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } + + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; + + return this; + }, + + /** + * Sets the fill colors for each face of the iso triangle. + * This call can be chained. + * + * @method Phaser.GameObjects.IsoTriangle#setFillStyle + * @since 3.13.0 + * + * @param {number} [fillTop] - The color used to fill the top of the iso triangle. + * @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso triangle. + * @param {number} [fillRight] - The color used to fill in the right-facing side of the iso triangle. + * + * @return {this} This Game Object instance. + */ + setFillStyle: function (fillTop, fillLeft, fillRight) + { + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.isFilled = true; + + return this; + } + +}); + +module.exports = IsoTriangle; + + +/***/ }), +/* 461 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GeomLine = __webpack_require__(45); +var LineRender = __webpack_require__(1109); + +/** + * @classdesc + * The Line Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports only stroke colors and cannot be filled. + * + * A Line Shape allows you to draw a line between two points in your game. You can control the + * stroke color and thickness of the line. In WebGL only you can also specify a different + * thickness for the start and end of the line, allowing you to render lines that taper-off. + * + * If you need to draw multiple lines in a sequence you may wish to use the Polygon Shape instead. + * + * Be aware that as with all Game Objects the default origin is 0.5. If you need to draw a Line + * between two points and want the x1/y1 values to match the x/y values, then set the origin to 0. + * + * @class Line + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [x1=0] - The horizontal position of the start of the line. + * @param {number} [y1=0] - The vertical position of the start of the line. + * @param {number} [x2=128] - The horizontal position of the end of the line. + * @param {number} [y2=0] - The vertical position of the end of the line. + * @param {number} [strokeColor] - The color the line will be drawn in, i.e. 0xff0000 for red. + * @param {number} [strokeAlpha] - The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Line = new Class({ + + Extends: Shape, + + Mixins: [ + LineRender + ], + + initialize: + + function Line (scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 128; } + if (y2 === undefined) { y2 = 0; } + + Shape.call(this, scene, 'Line', new GeomLine(x1, y1, x2, y2)); + + var width = Math.max(1, this.geom.right - this.geom.left); + var height = Math.max(1, this.geom.bottom - this.geom.top); + + /** + * The width (or thickness) of the line. + * See the setLineWidth method for extra details on changing this on WebGL. + * + * @name Phaser.GameObjects.Line#lineWidth + * @type {number} + * @since 3.13.0 + */ + this.lineWidth = 1; + + /** + * Private internal value. Holds the start width of the line. + * + * @name Phaser.GameObjects.Line#_startWidth + * @type {number} + * @private + * @since 3.13.0 + */ + this._startWidth = 1; + + /** + * Private internal value. Holds the end width of the line. + * + * @name Phaser.GameObjects.Line#_endWidth + * @type {number} + * @private + * @since 3.13.0 + */ + this._endWidth = 1; + + this.setPosition(x, y); + this.setSize(width, height); + + if (strokeColor !== undefined) + { + this.setStrokeStyle(1, strokeColor, strokeAlpha); + } + + this.updateDisplayOrigin(); + }, + + /** + * Sets the width of the line. + * + * When using the WebGL renderer you can have different start and end widths. + * When using the Canvas renderer only the `startWidth` value is used. The `endWidth` is ignored. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Line#setLineWidth + * @since 3.13.0 + * + * @param {number} startWidth - The start width of the line. + * @param {number} [endWidth] - The end width of the line. Only used in WebGL. + * + * @return {this} This Game Object instance. + */ + setLineWidth: function (startWidth, endWidth) + { + if (endWidth === undefined) { endWidth = startWidth; } + + this._startWidth = startWidth; + this._endWidth = endWidth; + + this.lineWidth = startWidth; + + return this; + }, + + /** + * Sets the start and end coordinates of this Line. + * + * @method Phaser.GameObjects.Line#setTo + * @since 3.13.0 + * + * @param {number} [x1=0] - The horizontal position of the start of the line. + * @param {number} [y1=0] - The vertical position of the start of the line. + * @param {number} [x2=0] - The horizontal position of the end of the line. + * @param {number} [y2=0] - The vertical position of the end of the line. + * + * @return {this} This Line object. + */ + setTo: function (x1, y1, x2, y2) + { + this.geom.setTo(x1, y1, x2, y2); + + return this; + } + +}); + +module.exports = Line; + + +/***/ }), +/* 462 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var PolygonRender = __webpack_require__(1112); +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var GetAABB = __webpack_require__(463); +var GeomPolygon = __webpack_require__(224); +var Shape = __webpack_require__(32); +var Smooth = __webpack_require__(466); + +/** + * @classdesc + * The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * The Polygon Shape is created by providing a list of points, which are then used to create an + * internal Polygon geometry object. The points can be set from a variety of formats: + * + * - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` + * - An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]` + * - An array of objects with public x/y properties: `[obj1, obj2, ...]` + * - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]` + * - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]` + * + * By default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending + * on the coordinates of the points provided, the final shape may be rendered offset from its origin. + * + * @class Polygon + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {any} [points] - The points that make up the polygon. + * @param {number} [fillColor] - The color the polygon will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Polygon = new Class({ + + Extends: Shape, + + Mixins: [ + PolygonRender + ], + + initialize: + + function Polygon (scene, x, y, points, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + Shape.call(this, scene, 'Polygon', new GeomPolygon(points)); + + var bounds = GetAABB(this.geom); + + this.setPosition(x, y); + this.setSize(bounds.width, bounds.height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Smooths the polygon over the number of iterations specified. + * The base polygon data will be updated and replaced with the smoothed values. + * This call can be chained. + * + * @method Phaser.GameObjects.Polygon#smooth + * @since 3.13.0 + * + * @param {number} [iterations=1] - The number of times to apply the polygon smoothing. + * + * @return {this} This Game Object instance. + */ + smooth: function (iterations) + { + if (iterations === undefined) { iterations = 1; } + + for (var i = 0; i < iterations; i++) + { + Smooth(this.geom); + } + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Polygon#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var points = this.geom.points; + + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } + + path.push(points[0].x, points[0].y); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Polygon; + + +/***/ }), +/* 463 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +/** + * Calculates the bounding AABB rectangle of a polygon. + * + * @function Phaser.Geom.Polygon.GetAABB + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The polygon that should be calculated. + * @param {(Phaser.Geom.Rectangle|object)} [out] - The rectangle or object that has x, y, width, and height properties to store the result. Optional. + * + * @return {(Phaser.Geom.Rectangle|object)} The resulting rectangle or object that is passed in with position and dimensions of the polygon's AABB. + */ +var GetAABB = function (polygon, out) +{ + if (out === undefined) { out = new Rectangle(); } + + var minX = Infinity; + var minY = Infinity; + var maxX = -minX; + var maxY = -minY; + var p; + + for (var i = 0; i < polygon.points.length; i++) + { + p = polygon.points[i]; + + minX = Math.min(minX, p.x); + minY = Math.min(minY, p.y); + maxX = Math.max(maxX, p.x); + maxY = Math.max(maxY, p.y); + } + + out.x = minX; + out.y = minY; + out.width = maxX - minX; + out.height = maxY - minY; + + return out; +}; + +module.exports = GetAABB; + + +/***/ }), +/* 464 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Line = __webpack_require__(45); +var Perimeter = __webpack_require__(465); + +/** + * Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon, + * based on the given quantity or stepRate values. + * + * @function Phaser.Geom.Polygon.GetPoints + * @since 3.12.0 + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the points from. + * @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead. + * @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate. + * @param {array} [output] - An array to insert the points in to. If not provided a new array will be created. + * + * @return {Phaser.Geom.Point[]} An array of Point objects pertaining to the points around the perimeter of the Polygon. + */ +var GetPoints = function (polygon, quantity, stepRate, out) +{ + if (out === undefined) { out = []; } + + var points = polygon.points; + var perimeter = Perimeter(polygon); + + // 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 / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var position = perimeter * (i / quantity); + var accumulatedPerimeter = 0; + + for (var j = 0; j < points.length; j++) + { + var pointA = points[j]; + var pointB = points[(j + 1) % points.length]; + var line = new Line( + pointA.x, + pointA.y, + pointB.x, + pointB.y + ); + var length = Length(line); + + if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) + { + accumulatedPerimeter += length; + continue; + } + + var point = line.getPoint((position - accumulatedPerimeter) / length); + out.push(point); + + break; + } + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 465 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Line = __webpack_require__(45); + +/** + * Returns the perimeter of the given Polygon. + * + * @function Phaser.Geom.Polygon.Perimeter + * @since 3.12.0 + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to get the perimeter of. + * + * @return {number} The perimeter of the Polygon. + */ +var Perimeter = function (polygon) +{ + var points = polygon.points; + var perimeter = 0; + + for (var i = 0; i < points.length; i++) + { + var pointA = points[i]; + var pointB = points[(i + 1) % points.length]; + var line = new Line( + pointA.x, + pointA.y, + pointB.x, + pointB.y + ); + + perimeter += Length(line); + } + + return perimeter; +}; + +module.exports = Perimeter; + + +/***/ }), +/* 466 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @author Igor Ognichenko + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @ignore + */ +var copy = function (out, a) +{ + out[0] = a[0]; + out[1] = a[1]; + + return out; +}; + +/** + * Takes a Polygon object and applies Chaikin's smoothing algorithm on its points. + * + * @function Phaser.Geom.Polygon.Smooth + * @since 3.13.0 + * + * @generic {Phaser.Geom.Polygon} O - [polygon,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The polygon to be smoothed. The polygon will be modified in-place and returned. + * + * @return {Phaser.Geom.Polygon} The input polygon. + */ +var Smooth = function (polygon) +{ + var i; + var points = []; + var data = polygon.points; + + for (i = 0; i < data.length; i++) + { + points.push([ data[i].x, data[i].y ]); + } + + var output = []; + + if (points.length > 0) + { + output.push(copy([ 0, 0 ], points[0])); + } + + for (i = 0; i < points.length - 1; i++) + { + var p0 = points[i]; + var p1 = points[i + 1]; + var p0x = p0[0]; + var p0y = p0[1]; + var p1x = p1[0]; + var p1y = p1[1]; + + output.push([ 0.85 * p0x + 0.15 * p1x, 0.85 * p0y + 0.15 * p1y ]); + output.push([ 0.15 * p0x + 0.85 * p1x, 0.15 * p0y + 0.85 * p1y ]); + } + + if (points.length > 1) + { + output.push(copy([ 0, 0 ], points[points.length - 1])); + } + + return polygon.setTo(output); +}; + +module.exports = Smooth; + + +/***/ }), +/* 467 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GeomRectangle = __webpack_require__(10); +var Shape = __webpack_require__(32); +var RectangleRender = __webpack_require__(1115); + +/** + * @classdesc + * The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * You can change the size of the rectangle by changing the `width` and `height` properties. + * + * @class Rectangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 - The horizontal position of this Game Object in the world. + * @param {number} y - The vertical position of this Game Object in the world. + * @param {number} [width=128] - The width of the rectangle. + * @param {number} [height=128] - The height of the rectangle. + * @param {number} [fillColor] - The color the rectangle will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Rectangle = new Class({ + + Extends: Shape, + + Mixins: [ + RectangleRender + ], + + initialize: + + function Rectangle (scene, x, y, width, height, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + + Shape.call(this, scene, 'Rectangle', new GeomRectangle(0, 0, width, height)); + + this.setPosition(x, y); + this.setSize(width, height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * 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.Rectangle#setSize + * @since 3.13.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; + + this.geom.setSize(width, height); + + this.updateData(); + + return this; + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Rectangle#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var rect = this.geom; + var line = this._tempLine; + + rect.getLineA(line); + + path.push(line.x1, line.y1, line.x2, line.y2); + + rect.getLineB(line); + + path.push(line.x2, line.y2); + + rect.getLineC(line); + + path.push(line.x2, line.y2); + + rect.getLineD(line); + + path.push(line.x2, line.y2); + + this.pathData = path; + + return this; + } + +}); + +module.exports = Rectangle; + + +/***/ }), +/* 468 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var StarRender = __webpack_require__(1118); +var Class = __webpack_require__(0); +var Earcut = __webpack_require__(68); +var Shape = __webpack_require__(32); + +/** + * @classdesc + * The Star Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * As the name implies, the Star shape will display a star in your game. You can control several + * aspects of it including the number of points that constitute the star. The default is 5. If + * you change it to 4 it will render as a diamond. If you increase them, you'll get a more spiky + * star shape. + * + * You can also control the inner and outer radius, which is how 'long' each point of the star is. + * Modify these values to create more interesting shapes. + * + * @class Star + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [points=5] - The number of points on the star. + * @param {number} [innerRadius=32] - The inner radius of the star. + * @param {number} [outerRadius=64] - The outer radius of the star. + * @param {number} [fillColor] - The color the star will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Star = new Class({ + + Extends: Shape, + + Mixins: [ + StarRender + ], + + initialize: + + function Star (scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (points === undefined) { points = 5; } + if (innerRadius === undefined) { innerRadius = 32; } + if (outerRadius === undefined) { outerRadius = 64; } + + Shape.call(this, scene, 'Star', null); + + /** + * Private internal value. + * The number of points in the star. + * + * @name Phaser.GameObjects.Star#_points + * @type {number} + * @private + * @since 3.13.0 + */ + this._points = points; + + /** + * Private internal value. + * The inner radius of the star. + * + * @name Phaser.GameObjects.Star#_innerRadius + * @type {number} + * @private + * @since 3.13.0 + */ + this._innerRadius = innerRadius; + + /** + * Private internal value. + * The outer radius of the star. + * + * @name Phaser.GameObjects.Star#_outerRadius + * @type {number} + * @private + * @since 3.13.0 + */ + this._outerRadius = outerRadius; + + this.setPosition(x, y); + this.setSize(outerRadius * 2, outerRadius * 2); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Sets the number of points that make up the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setPoints + * @since 3.13.0 + * + * @param {number} value - The amount of points the Star will have. + * + * @return {this} This Game Object instance. + */ + setPoints: function (value) + { + this._points = value; + + return this.updateData(); + }, + + /** + * Sets the inner radius of the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setInnerRadius + * @since 3.13.0 + * + * @param {number} value - The amount to set the inner radius to. + * + * @return {this} This Game Object instance. + */ + setInnerRadius: function (value) + { + this._innerRadius = value; + + return this.updateData(); + }, + + /** + * Sets the outer radius of the Star shape. + * This call can be chained. + * + * @method Phaser.GameObjects.Star#setOuterRadius + * @since 3.13.0 + * + * @param {number} value - The amount to set the outer radius to. + * + * @return {this} This Game Object instance. + */ + setOuterRadius: function (value) + { + this._outerRadius = value; + + return this.updateData(); + }, + + /** + * The number of points that make up the Star shape. + * + * @name Phaser.GameObjects.Star#points + * @type {number} + * @default 5 + * @since 3.13.0 + */ + points: { + + get: function () + { + return this._points; + }, + + set: function (value) + { + this._points = value; + + this.updateData(); + } + + }, + + /** + * The inner radius of the Star shape. + * + * @name Phaser.GameObjects.Star#innerRadius + * @type {number} + * @default 32 + * @since 3.13.0 + */ + innerRadius: { + + get: function () + { + return this._innerRadius; + }, + + set: function (value) + { + this._innerRadius = value; + + this.updateData(); + } + + }, + + /** + * The outer radius of the Star shape. + * + * @name Phaser.GameObjects.Star#outerRadius + * @type {number} + * @default 64 + * @since 3.13.0 + */ + outerRadius: { + + get: function () + { + return this._outerRadius; + }, + + set: function (value) + { + this._outerRadius = value; + + this.updateData(); + } + + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Star#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + + var points = this._points; + var innerRadius = this._innerRadius; + var outerRadius = this._outerRadius; + + var rot = Math.PI / 2 * 3; + var step = Math.PI / points; + + // So origin 0.5 = the center of the star + var x = outerRadius; + var y = outerRadius; + + path.push(x, y + -outerRadius); + + for (var i = 0; i < points; i++) + { + path.push(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius); + + rot += step; + + path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius); + + rot += step; + } + + path.push(x, y + -outerRadius); + + this.pathIndexes = Earcut(path); + this.pathData = path; + + return this; + } + +}); + +module.exports = Star; + + +/***/ }), +/* 469 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Shape = __webpack_require__(32); +var GeomTriangle = __webpack_require__(82); +var TriangleRender = __webpack_require__(1121); + +/** + * @classdesc + * The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can + * treat it like any other Game Object in your game, such as tweening it, scaling it, or enabling + * it for input or physics. It provides a quick and easy way for you to render this shape in your + * game without using a texture, while still taking advantage of being fully batched in WebGL. + * + * This shape supports both fill and stroke colors. + * + * The Triangle consists of 3 lines, joining up to form a triangular shape. You can control the + * position of each point of these lines. The triangle is always closed and cannot have an open + * face. If you require that, consider using a Polygon instead. + * + * @class Triangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @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 {number} [x1=0] - The horizontal position of the first point in the triangle. + * @param {number} [y1=128] - The vertical position of the first point in the triangle. + * @param {number} [x2=64] - The horizontal position of the second point in the triangle. + * @param {number} [y2=0] - The vertical position of the second point in the triangle. + * @param {number} [x3=128] - The horizontal position of the third point in the triangle. + * @param {number} [y3=128] - The vertical position of the third point in the triangle. + * @param {number} [fillColor] - The color the triangle will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + */ +var Triangle = new Class({ + + Extends: Shape, + + Mixins: [ + TriangleRender + ], + + initialize: + + function Triangle (scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 128; } + if (x2 === undefined) { x2 = 64; } + if (y2 === undefined) { y2 = 0; } + if (x3 === undefined) { x3 = 128; } + if (y3 === undefined) { y3 = 128; } + + Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); + + var width = this.geom.right - this.geom.left; + var height = this.geom.bottom - this.geom.top; + + this.setPosition(x, y); + this.setSize(width, height); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, + + /** + * Sets the data for the lines that make up this Triangle shape. + * + * @method Phaser.GameObjects.Triangle#setTo + * @since 3.13.0 + * + * @param {number} [x1=0] - The horizontal position of the first point in the triangle. + * @param {number} [y1=0] - The vertical position of the first point in the triangle. + * @param {number} [x2=0] - The horizontal position of the second point in the triangle. + * @param {number} [y2=0] - The vertical position of the second point in the triangle. + * @param {number} [x3=0] - The horizontal position of the third point in the triangle. + * @param {number} [y3=0] - The vertical position of the third point in the triangle. + * + * @return {this} This Game Object instance. + */ + setTo: function (x1, y1, x2, y2, x3, y3) + { + this.geom.setTo(x1, y1, x2, y2, x3, y3); + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. + * + * @method Phaser.GameObjects.Triangle#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. + */ + updateData: function () + { + var path = []; + var tri = this.geom; + var line = this._tempLine; + + tri.getLineA(line); + + path.push(line.x1, line.y1, line.x2, line.y2); + + tri.getLineB(line); + + path.push(line.x2, line.y2); + + tri.getLineC(line); + + path.push(line.x2, line.y2); + + this.pathData = path; + + return this; + } + +}); + +module.exports = Triangle; + + +/***/ }), +/* 470 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); +var Length = __webpack_require__(64); + +/** + * Returns a Point from around the perimeter of a Triangle. + * + * @function Phaser.Geom.Triangle.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the point on its perimeter from. + * @param {number} position - The position along the perimeter of the triangle. A value between 0 and 1. + * @param {(Phaser.Geom.Point|object)} [out] - An option Point, or Point-like object to store the value in. If not given a new Point will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point object containing the given position from the perimeter of the triangle. + */ +var GetPoint = function (triangle, position, out) +{ + if (out === undefined) { out = new Point(); } + + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); + + if (position <= 0 || position >= 1) + { + out.x = line1.x1; + out.y = line1.y1; + + return out; + } + + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); + + var perimeter = length1 + length2 + length3; + + var p = perimeter * position; + var localPosition = 0; + + // Which line is it on? + + if (p < length1) + { + // Line 1 + localPosition = p / length1; + + out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; + } + else if (p > length1 + length2) + { + // Line 3 + p -= length1 + length2; + localPosition = p / length3; + + out.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; + out.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; + } + else + { + // Line 2 + p -= length1; + localPosition = p / length2; + + out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } + + return out; +}; + +module.exports = GetPoint; + + +/***/ }), +/* 471 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Length = __webpack_require__(64); +var Point = __webpack_require__(4); + +/** + * Returns an array of evenly spaced points on the perimeter of a Triangle. + * + * @function Phaser.Geom.Triangle.GetPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the points from. + * @param {number} quantity - The number of evenly spaced points to return. Set to 0 to return an arbitrary number of points based on the `stepRate`. + * @param {number} stepRate - If `quantity` is 0, the distance between each returned point. + * @param {(array|Phaser.Geom.Point[])} [out] - An array to which the points should be appended. + * + * @return {(array|Phaser.Geom.Point[])} The modified `out` array, or a new array if none was provided. + */ +var GetPoints = function (triangle, quantity, stepRate, out) +{ + if (out === undefined) { out = []; } + + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); + + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); + + var perimeter = length1 + length2 + length3; + + // 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 / stepRate; + } + + for (var i = 0; i < quantity; i++) + { + var p = perimeter * (i / quantity); + var localPosition = 0; + + var point = new Point(); + + // Which line is it on? + + if (p < length1) + { + // Line 1 + localPosition = p / length1; + + point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; + } + else if (p > length1 + length2) + { + // Line 3 + p -= length1 + length2; + localPosition = p / length3; + + point.x = line3.x1 + (line3.x2 - line3.x1) * localPosition; + point.y = line3.y1 + (line3.y2 - line3.y1) * localPosition; + } + else + { + // Line 2 + p -= length1; + localPosition = p / length2; + + point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } + + out.push(point); + } + + return out; +}; + +module.exports = GetPoints; + + +/***/ }), +/* 472 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets a value in an object, allowing for dot notation to control the depth of the property. + * + * For example: + * + * ```javascript + * var data = { + * world: { + * position: { + * x: 200, + * y: 100 + * } + * } + * }; + * + * SetValue(data, 'world.position.y', 300); + * + * console.log(data.world.position.y); // 300 + * ``` + * + * @function Phaser.Utils.Objects.SetValue + * @since 3.17.0 + * + * @param {object} source - The object to set the value in. + * @param {string} key - The name of the property in the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) + * @param {any} value - The value to set into the property, if found in the source object. + * + * @return {boolean} `true` if the property key was valid and the value was set, otherwise `false`. + */ +var SetValue = function (source, key, value) +{ + if (!source || typeof source === 'number') + { + return false; + } + else if (source.hasOwnProperty(key)) + { + source[key] = value; + + return true; + } + else if (key.indexOf('.') !== -1) + { + var keys = key.split('.'); + var parent = source; + var prev = source; + + // 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 + prev = parent; + parent = parent[keys[i]]; + } + else + { + return false; + } + } + + prev[keys[keys.length - 1]] = value; + + return true; + } + + return false; +}; + +module.exports = SetValue; + + +/***/ }), +/* 473 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Face = __webpack_require__(113); +var Vertex = __webpack_require__(115); + +/** + * Generates a set of Face and Vertex objects by parsing the given data. + * + * This method will take vertex data in one of two formats, based on the `containsZ` parameter. + * + * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default) + * + * If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true. + * + * The `uvs` parameter is a numeric array consisting of `u` and `v` pairs. + * + * The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well. + * + * The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added. + * + * The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created. + * + * The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created. + * + * When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices. + * + * The following example will create a 256 x 256 sized quad using an index array: + * + * ```javascript + * const vertices = [ + * -128, 128, + * 128, 128, + * -128, -128, + * 128, -128 + * ]; + * + * const uvs = [ + * 0, 1, + * 1, 1, + * 0, 0, + * 1, 0 + * ]; + * + * const indices = [ 0, 2, 1, 2, 3, 1 ]; + * + * GenerateVerts(vertices, uvs, indicies); + * ``` + * + * If the data is not indexed, it's assumed that the arrays all contain sequential data. + * + * @function Phaser.Geom.Mesh.GenerateVerts + * @since 3.50.0 + * + * @param {number[]} vertices - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. + * @param {number[]} uvs - The UVs pairs array. + * @param {number[]} [indicies] - Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + * @param {boolean} [containsZ=false] - Does the vertices data include a `z` component? + * @param {number[]} [normals] - Optional vertex normals array. If you don't have one, pass `null` or an empty array. + * @param {number|number[]} [colors=0xffffff] - An array of colors, one per vertex, or a single color value applied to all vertices. + * @param {number|number[]} [alphas=1] - An array of alpha values, one per vertex, or a single alpha value applied to all vertices. + * + * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. + */ +var GenerateVerts = function (vertices, uvs, indicies, containsZ, normals, colors, alphas) +{ + if (containsZ === undefined) { containsZ = false; } + if (colors === undefined) { colors = 0xffffff; } + if (alphas === undefined) { alphas = 1; } + + if (vertices.length !== uvs.length) + { + console.warn('GenerateVerts: vertices and uvs count not equal'); + return; + } + + var result = { + faces: [], + verts: [] + }; + + var i; + + var x; + var y; + var z; + + var u; + var v; + + var color; + var alpha; + + var normalX; + var normalY; + var normalZ; + + var iInc = (containsZ) ? 3 : 2; + + var isColorArray = Array.isArray(colors); + var isAlphaArray = Array.isArray(alphas); + + if (Array.isArray(indicies) && indicies.length > 0) + { + for (i = 0; i < indicies.length; i++) + { + var index1 = indicies[i]; + var index2 = indicies[i] * 2; + var index3 = indicies[i] * iInc; + + x = vertices[index3]; + y = vertices[index3 + 1]; + z = (containsZ) ? vertices[index3 + 2] : 0; + + u = uvs[index2]; + v = uvs[index2 + 1]; + + color = (isColorArray) ? colors[index1] : colors; + alpha = (isAlphaArray) ? alphas[index1] : alphas; + + normalX = 0; + normalY = 0; + normalZ = 0; + + if (normals) + { + normalX = normals[index3]; + normalY = normals[index3 + 1]; + normalZ = (containsZ) ? normals[index3 + 2] : 0; + } + + result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + } + } + else + { + var uvIndex = 0; + var colorIndex = 0; + + for (i = 0; i < vertices.length; i += iInc) + { + x = vertices[i]; + y = vertices[i + 1]; + z = (containsZ) ? vertices[i + 2] : 0; + + u = uvs[uvIndex]; + v = uvs[uvIndex + 1]; + + color = (isColorArray) ? colors[colorIndex] : colors; + alpha = (isAlphaArray) ? alphas[colorIndex] : alphas; + + normalX = 0; + normalY = 0; + normalZ = 0; + + if (normals) + { + normalX = normals[i]; + normalY = normals[i + 1]; + normalZ = (containsZ) ? normals[i + 2] : 0; + } + + result.verts.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + + uvIndex += 2; + colorIndex++; + } + } + + for (i = 0; i < result.verts.length; i += 3) + { + var vert1 = result.verts[i]; + var vert2 = result.verts[i + 1]; + var vert3 = result.verts[i + 2]; + + result.faces.push(new Face(vert1, vert2, vert3)); + } + + return result; +}; + +module.exports = GenerateVerts; + + +/***/ }), +/* 474 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Face = __webpack_require__(113); +var Matrix4 = __webpack_require__(67); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); + +var tempPosition = new Vector3(); +var tempRotation = new Vector3(); +var tempMatrix = new Matrix4(); + +/** + * This method will return an object containing Face and Vertex instances, generated + * from the parsed triangulated OBJ Model data given to this function. + * + * The obj data should have been parsed in advance via the ParseObj function: + * + * ```javascript + * var data = Phaser.Geom.Mesh.ParseObj(rawData, flipUV); + * + * var results = GenerateObjVerts(data); + * ``` + * + * Alternatively, you can parse obj files loaded via the OBJFile loader: + * + * ```javascript + * preload () + * { + * this.load.obj('alien', 'assets/3d/alien.obj); + * } + * + * var results = GenerateObjVerts(this.cache.obj.get('alien)); + * ``` + * + * Make sure your 3D package has triangulated the model data prior to exporting it. + * + * You can use the data returned by this function to populate the vertices of a Mesh Game Object. + * + * You may add multiple models to a single Mesh, although they will act as one when + * moved or rotated. You can scale the model data, should it be too small (or large) to visualize. + * You can also offset the model via the `x`, `y` and `z` parameters. + * + * @function Phaser.Geom.Mesh.GenerateObjVerts + * @since 3.50.0 + * + * @param {Phaser.Types.Geom.Mesh.OBJData} data - The parsed OBJ model data. + * @param {Phaser.GameObjects.Mesh} [mesh] - An optional Mesh Game Object. If given, the generated Faces will be automatically added to this Mesh. Set to `null` to skip. + * @param {number} [scale=1] - An amount to scale the model data by. Use this if the model has exported too small, or large, to see. + * @param {number} [x=0] - Translate the model x position by this amount. + * @param {number} [y=0] - Translate the model y position by this amount. + * @param {number} [z=0] - Translate the model z position by this amount. + * @param {number} [rotateX=0] - Rotate the model on the x axis by this amount, in radians. + * @param {number} [rotateY=0] - Rotate the model on the y axis by this amount, in radians. + * @param {number} [rotateZ=0] - Rotate the model on the z axis by this amount, in radians. + * @param {boolean} [zIsUp=true] - Is the z axis up (true), or is y axis up (false)? + * + * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. + */ +var GenerateObjVerts = function (data, mesh, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) +{ + if (scale === undefined) { scale = 1; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (z === undefined) { z = 0; } + if (rotateX === undefined) { rotateX = 0; } + if (rotateY === undefined) { rotateY = 0; } + if (rotateZ === undefined) { rotateZ = 0; } + if (zIsUp === undefined) { zIsUp = true; } + + var result = { + faces: [], + verts: [] + }; + + var materials = data.materials; + + tempPosition.set(x, y, z); + tempRotation.set(rotateX, rotateY, rotateZ); + tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); + + for (var m = 0; m < data.models.length; m++) + { + var model = data.models[m]; + + var vertices = model.vertices; + var textureCoords = model.textureCoords; + var faces = model.faces; + + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; + + var v1 = face.vertices[0]; + var v2 = face.vertices[1]; + var v3 = face.vertices[2]; + + var m1 = vertices[v1.vertexIndex]; + var m2 = vertices[v2.vertexIndex]; + var m3 = vertices[v3.vertexIndex]; + + var t1 = v1.textureCoordsIndex; + var t2 = v2.textureCoordsIndex; + var t3 = v3.textureCoordsIndex; + + var uv1 = (t1 === -1) ? { u: 0, v: 1 } : textureCoords[t1]; + var uv2 = (t2 === -1) ? { u: 0, v: 0 } : textureCoords[t2]; + var uv3 = (t3 === -1) ? { u: 1, v: 1 } : textureCoords[t3]; + + var color = 0xffffff; + + if (face.material !== '' && materials[face.material]) + { + color = materials[face.material]; + } + + var vert1 = new Vertex(m1.x * scale, m1.y * scale, m1.z * scale, uv1.u, uv1.v, color).transformMat4(tempMatrix); + var vert2 = new Vertex(m2.x * scale, m2.y * scale, m2.z * scale, uv2.u, uv2.v, color).transformMat4(tempMatrix); + var vert3 = new Vertex(m3.x * scale, m3.y * scale, m3.z * scale, uv3.u, uv3.v, color).transformMat4(tempMatrix); + + result.verts.push(vert1, vert2, vert3); + result.faces.push(new Face(vert1, vert2, vert3)); + } + } + + if (mesh) + { + mesh.faces = mesh.faces.concat(result.faces); + mesh.vertices = mesh.vertices.concat(result.verts); + } + + return result; +}; + +module.exports = GenerateObjVerts; + + +/***/ }), +/* 475 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circle = __webpack_require__(62); +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var RGB = __webpack_require__(197); +var Utils = __webpack_require__(12); + +/** + * @classdesc + * A 2D point light. + * + * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. + * + * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. + * + * They can also simply be used to represent a point light for your own purposes. + * + * @class Light + * @extends Phaser.Geom.Circle + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Visible + * + * @param {number} x - The horizontal position of the light. + * @param {number} y - The vertical position of the light. + * @param {number} radius - The radius of the light. + * @param {number} r - The red color of the light. A value between 0 and 1. + * @param {number} g - The green color of the light. A value between 0 and 1. + * @param {number} b - The blue color of the light. A value between 0 and 1. + * @param {number} intensity - The intensity of the light. + */ +var Light = new Class({ + + Extends: Circle, + + Mixins: [ + Components.ScrollFactor, + Components.Visible + ], + + initialize: + + function Light (x, y, radius, r, g, b, intensity) + { + Circle.call(this, x, y, radius); + + /** + * The color of the light. + * + * @name Phaser.GameObjects.Light#color + * @type {Phaser.Display.RGB} + * @since 3.50.0 + */ + this.color = new RGB(r, g, b); + + /** + * The intensity of the light. + * + * @name Phaser.GameObjects.Light#intensity + * @type {number} + * @since 3.50.0 + */ + this.intensity = intensity; + + /** + * 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 {number} + * @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; + + this.setScrollFactor(1, 1); + }, + + /** + * 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.Light#willRender + * @since 3.50.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 !(Light.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + }, + + /** + * Set the color of the light from a single integer RGB value. + * + * @method Phaser.GameObjects.Light#setColor + * @since 3.0.0 + * + * @param {number} rgb - The integer RGB color of the light. + * + * @return {this} This Light object. + */ + setColor: function (rgb) + { + var color = Utils.getFloatsFromUintRGB(rgb); + + this.color.set(color[0], color[1], color[2]); + + return this; + }, + + /** + * Set the intensity of the light. + * + * @method Phaser.GameObjects.Light#setIntensity + * @since 3.0.0 + * + * @param {number} intensity - The intensity of the light. + * + * @return {this} This Light object. + */ + setIntensity: function (intensity) + { + this.intensity = intensity; + + return this; + }, + + /** + * Set the radius of the light. + * + * @method Phaser.GameObjects.Light#setRadius + * @since 3.0.0 + * + * @param {number} radius - The radius of the light. + * + * @return {this} This Light object. + */ + setRadius: function (radius) + { + this.radius = radius; + + return this; + } + +}); + +/** + * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + * + * @constant {number} RENDER_MASK + * @memberof Phaser.GameObjects.Light + * @default + */ +Light.RENDER_MASK = 15; + +module.exports = Light; + + +/***/ }), +/* 476 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircleToRectangle = __webpack_require__(150); +var Class = __webpack_require__(0); +var DistanceBetween = __webpack_require__(48); +var Light = __webpack_require__(475); +var PointLight = __webpack_require__(149); +var RGB = __webpack_require__(197); +var SpliceOne = __webpack_require__(74); +var StableSort = __webpack_require__(79); +var Utils = __webpack_require__(12); + +/** + * @callback LightForEach + * + * @param {Phaser.GameObjects.Light} light - The Light. + */ + +/** + * @classdesc + * Manages Lights for a Scene. + * + * Affects the rendering of Game Objects using the `Light2D` pipeline. + * + * @class LightsManager + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + */ +var LightsManager = new Class({ + + initialize: + + function LightsManager () + { + /** + * The Lights in the Scene. + * + * @name Phaser.GameObjects.LightsManager#lights + * @type {Phaser.GameObjects.Light[]} + * @default [] + * @since 3.0.0 + */ + this.lights = []; + + /** + * The ambient color. + * + * @name Phaser.GameObjects.LightsManager#ambientColor + * @type {Phaser.Display.RGB} + * @since 3.50.0 + */ + this.ambientColor = new RGB(0.1, 0.1, 0.1); + + /** + * Whether the Lights Manager is enabled. + * + * @name Phaser.GameObjects.LightsManager#active + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.active = false; + + /** + * The maximum number of lights that a single Camera and the lights shader can process. + * Change this via the `maxLights` property in your game config, as it cannot be changed at runtime. + * + * @name Phaser.GameObjects.LightsManager#maxLights + * @type {number} + * @readonly + * @since 3.15.0 + */ + this.maxLights = -1; + + /** + * The number of lights that the LightPipeline processed in the _previous_ frame. + * + * @name Phaser.GameObjects.LightsManager#visibleLights + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.visibleLights = 0; + }, + + addPointLight: function (x, y, color, radius, intensity) + { + return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity)); + }, + + /** + * Enable the Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#enable + * @since 3.0.0 + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + enable: function () + { + if (this.maxLights === -1) + { + this.maxLights = this.scene.sys.renderer.config.maxLights; + } + + this.active = true; + + return this; + }, + + /** + * Disable the Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#disable + * @since 3.0.0 + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + disable: function () + { + this.active = false; + + return this; + }, + + /** + * Get all lights that can be seen by the given Camera. + * + * It will automatically cull lights that are outside the world view of the Camera. + * + * If more lights are returned than supported by the pipeline, the lights are then culled + * based on the distance from the center of the camera. Only those closest are rendered. + * + * @method Phaser.GameObjects.LightsManager#getLights + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. + * + * @return {Phaser.GameObjects.Light[]} The culled Lights. + */ + getLights: function (camera) + { + var lights = this.lights; + var worldView = camera.worldView; + + var visibleLights = []; + + for (var i = 0; i < lights.length; i++) + { + var light = lights[i]; + + if (light.willRender(camera) && CircleToRectangle(light, worldView)) + { + visibleLights.push({ + light: light, + distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY) + }); + } + } + + if (visibleLights.length > this.maxLights) + { + // We've got too many lights, so sort by distance from camera and cull those far away + // This isn't ideal because it doesn't factor in the radius of the lights, but it'll do for now + // and is significantly better than we had before! + + StableSort(visibleLights, this.sortByDistance); + + visibleLights = visibleLights.slice(0, this.maxLights); + } + + this.visibleLights = visibleLights.length; + + return visibleLights; + }, + + sortByDistance: function (a, b) + { + return (a.distance >= b.distance); + }, + + /** + * Set the ambient light color. + * + * @method Phaser.GameObjects.LightsManager#setAmbientColor + * @since 3.0.0 + * + * @param {number} rgb - The integer RGB color of the ambient light. + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + setAmbientColor: function (rgb) + { + var color = Utils.getFloatsFromUintRGB(rgb); + + this.ambientColor.set(color[0], color[1], color[2]); + + return this; + }, + + /** + * Returns the maximum number of Lights allowed to appear at once. + * + * @method Phaser.GameObjects.LightsManager#getMaxVisibleLights + * @since 3.0.0 + * + * @return {number} The maximum number of Lights allowed to appear at once. + */ + getMaxVisibleLights: function () + { + return this.maxLights; + }, + + /** + * Get the number of Lights managed by this Lights Manager. + * + * @method Phaser.GameObjects.LightsManager#getLightCount + * @since 3.0.0 + * + * @return {number} The number of Lights managed by this Lights Manager. + */ + getLightCount: function () + { + return this.lights.length; + }, + + /** + * Add a Light. + * + * @method Phaser.GameObjects.LightsManager#addLight + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal position of the Light. + * @param {number} [y=0] - The vertical position of the Light. + * @param {number} [radius=100] - The radius of the Light. + * @param {number} [rgb=0xffffff] - The integer RGB color of the light. + * @param {number} [intensity=1] - The intensity of the Light. + * + * @return {Phaser.GameObjects.Light} The Light that was added. + */ + addLight: function (x, y, radius, rgb, intensity) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 128; } + if (rgb === undefined) { rgb = 0xffffff; } + if (intensity === undefined) { intensity = 1; } + + var color = Utils.getFloatsFromUintRGB(rgb); + + var light = new Light(x, y, radius, color[0], color[1], color[2], intensity); + + this.lights.push(light); + + return light; + }, + + /** + * Remove a Light. + * + * @method Phaser.GameObjects.LightsManager#removeLight + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Light} light - The Light to remove. + * + * @return {Phaser.GameObjects.LightsManager} This Lights Manager object. + */ + removeLight: function (light) + { + var index = this.lights.indexOf(light); + + if (index >= 0) + { + SpliceOne(this.lights, index); + } + + return this; + }, + + /** + * Shut down the Lights Manager. + * + * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and + * culled Lights. + * + * @method Phaser.GameObjects.LightsManager#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + this.lights.length = 0; + }, + + /** + * Destroy the Lights Manager. + * + * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. + * + * @method Phaser.GameObjects.LightsManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + } + +}); + +module.exports = LightsManager; + + +/***/ }), +/* 477 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(55); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Geom + */ + +var Geom = { + + Circle: __webpack_require__(1185), + Ellipse: __webpack_require__(1195), + Intersects: __webpack_require__(478), + Line: __webpack_require__(1215), + Mesh: __webpack_require__(1237), + Point: __webpack_require__(1240), + Polygon: __webpack_require__(1254), + Rectangle: __webpack_require__(496), + Triangle: __webpack_require__(1287) + +}; + +// Merge in the consts +Geom = Extend(false, Geom, CONST); + +module.exports = Geom; + + +/***/ }), +/* 478 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Geom.Intersects + */ + +module.exports = { + + CircleToCircle: __webpack_require__(228), + CircleToRectangle: __webpack_require__(150), + GetCircleToCircle: __webpack_require__(1205), + GetCircleToRectangle: __webpack_require__(1206), + GetLineToCircle: __webpack_require__(229), + GetLineToLine: __webpack_require__(479), + GetLineToPoints: __webpack_require__(480), + GetLineToPolygon: __webpack_require__(481), + GetLineToRectangle: __webpack_require__(231), + GetRaysFromPointToPolygon: __webpack_require__(1207), + GetRectangleIntersection: __webpack_require__(1208), + GetRectangleToRectangle: __webpack_require__(1209), + GetRectangleToTriangle: __webpack_require__(1210), + GetTriangleToCircle: __webpack_require__(1211), + GetTriangleToLine: __webpack_require__(486), + GetTriangleToTriangle: __webpack_require__(1212), + LineToCircle: __webpack_require__(230), + LineToLine: __webpack_require__(92), + LineToRectangle: __webpack_require__(482), + PointToLine: __webpack_require__(490), + PointToLineSegment: __webpack_require__(1213), + RectangleToRectangle: __webpack_require__(114), + RectangleToTriangle: __webpack_require__(483), + RectangleToValues: __webpack_require__(1214), + TriangleToCircle: __webpack_require__(485), + TriangleToLine: __webpack_require__(487), + TriangleToTriangle: __webpack_require__(488) + +}; + + +/***/ }), +/* 479 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); + +/** + * Checks for intersection between the two line segments and returns the intersection point as a Vector3, + * or `null` if the lines are parallel, or do not intersect. + * + * The `z` property of the Vector3 contains the intersection distance, which can be used to find + * the closest intersecting point from a group of line segments. + * + * @function Phaser.Geom.Intersects.GetLineToLine + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line1 - The first line segment to check. + * @param {Phaser.Geom.Line} line2 - The second line segment to check. + * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. + * + * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. + */ +var GetLineToLine = function (line1, line2, out) +{ + var x1 = line1.x1; + var y1 = line1.y1; + var x2 = line1.x2; + var y2 = line1.y2; + + var x3 = line2.x1; + var y3 = line2.y1; + var x4 = line2.x2; + var y4 = line2.y2; + + var dx1 = x2 - x1; + var dy1 = y2 - y1; + + var dx2 = x4 - x3; + var dy2 = y4 - y3; + + var denom = dy2 * dx1 - dx2 * dy1; + + // Make sure there is not a division by zero - this also indicates that the lines are parallel. + // If numA and numB were both equal to zero the lines would be on top of each other (coincidental). + // This check is not done because it is not necessary for this implementation (the parallel check accounts for this). + + if (dx1 === 0 || denom === 0) + { + return false; + } + + var T2 = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); + var T1 = (x3 + dx2 * T2 - x1) / dx1; + + // Intersects? + if (T1 < 0 || T2 < 0 || T2 > 1) + { + return null; + } + + if (out === undefined) + { + out = new Vector3(); + } + + return out.set( + x1 + dx1 * T1, + y1 + dy1 * T1, + T1 + ); +}; + +module.exports = GetLineToLine; + + +/***/ }), +/* 480 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); +var GetLineToLine = __webpack_require__(479); +var Line = __webpack_require__(45); + +// Temp calculation segment +var segment = new Line(); + +// Temp vec3 +var tempIntersect = new Vector3(); + +/** + * Checks for the closest point of intersection between a line segment and an array of points, where each pair + * of points are converted to line segments for the intersection tests. + * + * If no intersection is found, this function returns `null`. + * + * If intersection was found, a Vector3 is returned with the following properties: + * + * The `x` and `y` components contain the point of the intersection. + * The `z` component contains the closest distance. + * + * @function Phaser.Geom.Intersects.GetLineToPoints + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Math.Vector2[] | Phaser.Geom.Point[]} points - An array of points to check. + * @param {Phaser.Math.Vector3} [out] - A Vector3 to store the intersection results in. + * + * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. + */ +var GetLineToPoints = function (line, points, out) +{ + if (out === undefined) { out = new Vector3(); } + + var closestIntersect = false; + + // Reset our vec3s + out.set(); + tempIntersect.set(); + + var prev = points[0]; + + for (var i = 1; i < points.length; i++) + { + var current = points[i]; + + segment.setTo(prev.x, prev.y, current.x, current.y); + + prev = current; + + if (GetLineToLine(line, segment, tempIntersect)) + { + if (!closestIntersect || tempIntersect.z < out.z) + { + out.copy(tempIntersect); + + closestIntersect = true; + } + } + } + + return (closestIntersect) ? out : null; +}; + +module.exports = GetLineToPoints; + + +/***/ }), +/* 481 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(37); +var Vector4 = __webpack_require__(138); +var GetLineToPoints = __webpack_require__(480); + +// Temp vec3 +var tempIntersect = new Vector3(); + +/** + * Checks for the closest point of intersection between a line segment and an array of polygons. + * + * If no intersection is found, this function returns `null`. + * + * If intersection was found, a Vector4 is returned with the following properties: + * + * The `x` and `y` components contain the point of the intersection. + * The `z` component contains the closest distance. + * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. + * + * @function Phaser.Geom.Intersects.GetLineToPolygon + * @since 3.50.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check. + * @param {Phaser.Math.Vector4} [out] - A Vector4 to store the intersection results in. + * + * @return {Phaser.Math.Vector4} A Vector4 containing the intersection results, or `null`. + */ +var GetLineToPolygon = function (line, polygons, out) +{ + if (out === undefined) { out = new Vector4(); } + + if (!Array.isArray(polygons)) + { + polygons = [ polygons ]; + } + + var closestIntersect = false; + + // Reset our vec4s + out.set(); + tempIntersect.set(); + + for (var i = 0; i < polygons.length; i++) + { + if (GetLineToPoints(line, polygons[i].points, tempIntersect)) + { + if (!closestIntersect || tempIntersect.z < out.z) + { + out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); + + closestIntersect = true; + } + } + } + + return (closestIntersect) ? out : null; +}; + +module.exports = GetLineToPolygon; + + +/***/ }), +/* 482 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks for intersection between the Line and a Rectangle shape, or a rectangle-like + * object, with public `x`, `y`, `right` and `bottom` properties, such as a Sprite or Body. + * + * An intersection is considered valid if: + * + * The line starts within, or ends within, the Rectangle. + * The line segment intersects one of the 4 rectangle edges. + * + * The for the purposes of this function rectangles are considered 'solid'. + * + * @function Phaser.Geom.Intersects.LineToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The Line to check for intersection. + * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle to check for intersection. + * + * @return {boolean} `true` if the Line and the Rectangle intersect, `false` otherwise. + */ +var LineToRectangle = function (line, rect) +{ + var x1 = line.x1; + var y1 = line.y1; + + var x2 = line.x2; + var y2 = line.y2; + + var bx1 = rect.x; + var by1 = rect.y; + var bx2 = rect.right; + var by2 = rect.bottom; + + var t = 0; + + // If the start or end of the line is inside the rect then we assume + // collision, as rects are solid for our use-case. + + if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || + (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) + { + return true; + } + + if (x1 < bx1 && x2 >= bx1) + { + // Left edge + t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); + + if (t > by1 && t <= by2) + { + return true; + } + } + else if (x1 > bx2 && x2 <= bx2) + { + // Right edge + t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); + + if (t >= by1 && t <= by2) + { + return true; + } + } + + if (y1 < by1 && y2 >= by1) + { + // Top edge + t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) + { + return true; + } + } + else if (y1 > by2 && y2 <= by2) + { + // Bottom edge + t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) + { + return true; + } + } + + return false; +}; + +module.exports = LineToRectangle; + + +/***/ }), +/* 483 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToLine = __webpack_require__(92); +var Contains = __webpack_require__(56); +var ContainsArray = __webpack_require__(232); +var Decompose = __webpack_require__(484); + +/** + * Checks for intersection between Rectangle shape and Triangle shape. + * + * @function Phaser.Geom.Intersects.RectangleToTriangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. + * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. + * + * @return {boolean} A value of `true` if objects intersect; otherwise `false`. + */ +var RectangleToTriangle = function (rect, triangle) +{ + // First the cheapest ones: + + if ( + triangle.left > rect.right || + triangle.right < rect.left || + triangle.top > rect.bottom || + triangle.bottom < rect.top) + { + return false; + } + + var triA = triangle.getLineA(); + var triB = triangle.getLineB(); + var triC = triangle.getLineC(); + + // Are any of the triangle points within the rectangle? + + if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) + { + return true; + } + + if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) + { + return true; + } + + if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) + { + return true; + } + + // Cheap tests over, now to see if any of the lines intersect ... + + var rectA = rect.getLineA(); + var rectB = rect.getLineB(); + var rectC = rect.getLineC(); + var rectD = rect.getLineD(); + + if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) + { + return true; + } + + if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) + { + return true; + } + + if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) + { + return true; + } + + // None of the lines intersect, so are any rectangle points within the triangle? + + var points = Decompose(rect); + var within = ContainsArray(triangle, points, true); + + return (within.length > 0); +}; + +module.exports = RectangleToTriangle; + + +/***/ }), +/* 484 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Create an array of points for each corner of a Rectangle + * If an array is specified, each point object will be added to the end of the array, otherwise a new array will be created. + * + * @function Phaser.Geom.Rectangle.Decompose + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle object to be decomposed. + * @param {array} [out] - If provided, each point will be added to this array. + * + * @return {array} Will return the array you specified or a new array containing the points of the Rectangle. + */ +var Decompose = function (rect, out) +{ + if (out === undefined) { out = []; } + + out.push({ x: rect.x, y: rect.y }); + out.push({ x: rect.right, y: rect.y }); + out.push({ x: rect.right, y: rect.bottom }); + out.push({ x: rect.x, y: rect.bottom }); + + return out; +}; + +module.exports = Decompose; + + +/***/ }), +/* 485 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToCircle = __webpack_require__(230); +var Contains = __webpack_require__(112); + +/** + * Checks if a Triangle and a Circle intersect. + * + * A Circle intersects a Triangle if its center is located within it or if any of the Triangle's sides intersect the Circle. As such, the Triangle and the Circle are considered "solid" for the intersection. + * + * @function Phaser.Geom.Intersects.TriangleToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check for intersection. + * @param {Phaser.Geom.Circle} circle - The Circle to check for intersection. + * + * @return {boolean} `true` if the Triangle and the `Circle` intersect, otherwise `false`. + */ +var TriangleToCircle = function (triangle, circle) +{ + // First the cheapest ones: + + if ( + triangle.left > circle.right || + triangle.right < circle.left || + triangle.top > circle.bottom || + triangle.bottom < circle.top) + { + return false; + } + + if (Contains(triangle, circle.x, circle.y)) + { + return true; + } + + if (LineToCircle(triangle.getLineA(), circle)) + { + return true; + } + + if (LineToCircle(triangle.getLineB(), circle)) + { + return true; + } + + if (LineToCircle(triangle.getLineC(), circle)) + { + return true; + } + + return false; +}; + +module.exports = TriangleToCircle; + + +/***/ }), +/* 486 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); +var TriangleToLine = __webpack_require__(487); +var LineToLine = __webpack_require__(92); + +/** + * Checks if a Triangle and a Line intersect, and returns the intersection points as a Point object array. + * + * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". + * + * @function Phaser.Geom.Intersects.GetTriangleToLine + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. + * @param {Phaser.Geom.Line} line - The Line to check with. + * @param {array} [out] - An optional array in which to store the points of intersection. + * + * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. + */ +var GetTriangleToLine = function (triangle, line, out) +{ + if (out === undefined) { out = []; } + + if (TriangleToLine(triangle, line)) + { + var lineA = triangle.getLineA(); + var lineB = triangle.getLineB(); + var lineC = triangle.getLineC(); + + var output = [ new Point(), new Point(), new Point() ]; + + var result = [ + LineToLine(lineA, line, output[0]), + LineToLine(lineB, line, output[1]), + LineToLine(lineC, line, output[2]) + ]; + + for (var i = 0; i < 3; i++) + { + if (result[i]) { out.push(output[i]); } + } + } + + return out; +}; + +module.exports = GetTriangleToLine; + + +/***/ }), +/* 487 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToLine = __webpack_require__(92); + +/** + * Checks if a Triangle and a Line intersect. + * + * The Line intersects the Triangle if it starts inside of it, ends inside of it, or crosses any of the Triangle's sides. Thus, the Triangle is considered "solid". + * + * @function Phaser.Geom.Intersects.TriangleToLine + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check with. + * @param {Phaser.Geom.Line} line - The Line to check with. + * + * @return {boolean} `true` if the Triangle and the Line intersect, otherwise `false`. + */ +var TriangleToLine = function (triangle, line) +{ + // If the Triangle contains either the start or end point of the line, it intersects + if (triangle.contains(line.x1, line.y1) || triangle.contains(line.x2, line.y2)) + { + return true; + } + + // Now check the line against each line of the Triangle + if (LineToLine(triangle.getLineA(), line)) + { + return true; + } + + if (LineToLine(triangle.getLineB(), line)) + { + return true; + } + + if (LineToLine(triangle.getLineC(), line)) + { + return true; + } + + return false; +}; + +module.exports = TriangleToLine; + + +/***/ }), +/* 488 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ContainsArray = __webpack_require__(232); +var Decompose = __webpack_require__(489); +var LineToLine = __webpack_require__(92); + +/** + * Checks if two Triangles intersect. + * + * A Triangle intersects another Triangle if any pair of their lines intersects or if any point of one Triangle is within the other Triangle. Thus, the Triangles are considered "solid". + * + * @function Phaser.Geom.Intersects.TriangleToTriangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangleA - The first Triangle to check for intersection. + * @param {Phaser.Geom.Triangle} triangleB - The second Triangle to check for intersection. + * + * @return {boolean} `true` if the Triangles intersect, otherwise `false`. + */ +var TriangleToTriangle = function (triangleA, triangleB) +{ + // First the cheapest ones: + + if ( + triangleA.left > triangleB.right || + triangleA.right < triangleB.left || + triangleA.top > triangleB.bottom || + triangleA.bottom < triangleB.top) + { + return false; + } + + var lineAA = triangleA.getLineA(); + var lineAB = triangleA.getLineB(); + var lineAC = triangleA.getLineC(); + + var lineBA = triangleB.getLineA(); + var lineBB = triangleB.getLineB(); + var lineBC = triangleB.getLineC(); + + // Now check the lines against each line of TriangleB + if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) + { + return true; + } + + if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) + { + return true; + } + + if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) + { + return true; + } + + // Nope, so check to see if any of the points of triangleA are within triangleB + + var points = Decompose(triangleA); + var within = ContainsArray(triangleB, points, true); + + if (within.length > 0) + { + return true; + } + + // Finally check to see if any of the points of triangleB are within triangleA + + points = Decompose(triangleB); + within = ContainsArray(triangleA, points, true); + + if (within.length > 0) + { + return true; + } + + return false; +}; + +module.exports = TriangleToTriangle; + + +/***/ }), +/* 489 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Decomposes a Triangle into an array of its points. + * + * @function Phaser.Geom.Triangle.Decompose + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to decompose. + * @param {array} [out] - An array to store the points into. + * + * @return {array} The provided `out` array, or a new array if none was provided, with three objects with `x` and `y` properties representing each point of the Triangle appended to it. + */ +var Decompose = function (triangle, out) +{ + if (out === undefined) { out = []; } + + out.push({ x: triangle.x1, y: triangle.y1 }); + out.push({ x: triangle.x2, y: triangle.y2 }); + out.push({ x: triangle.x3, y: triangle.y3 }); + + return out; +}; + +module.exports = Decompose; + + +/***/ }), +/* 490 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @author Florian Mertens + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if the a Point falls between the two end-points of a Line, based on the given line thickness. + * + * Assumes that the line end points are circular, not square. + * + * @function Phaser.Geom.Intersects.PointToLine + * @since 3.0.0 + * + * @param {(Phaser.Geom.Point|any)} point - The point, or point-like object to check. + * @param {Phaser.Geom.Line} line - The line segment to test for intersection on. + * @param {number} [lineThickness=1] - The line thickness. Assumes that the line end points are circular. + * + * @return {boolean} `true` if the Point falls on the Line, otherwise `false`. + */ +var PointToLine = function (point, line, lineThickness) +{ + if (lineThickness === undefined) { lineThickness = 1; } + + var x1 = line.x1; + var y1 = line.y1; + + var x2 = line.x2; + var y2 = line.y2; + + var px = point.x; + var py = point.y; + + var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); + + if (L2 === 0) + { + return false; + } + + var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; + + // Assume line thickness is circular + if (r < 0) + { + // Outside line1 + return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); + } + else if ((r >= 0) && (r <= 1)) + { + // On the line segment + var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; + + return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); + } + else + { + // Outside line2 + return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); + } +}; + +module.exports = PointToLine; + + +/***/ }), +/* 491 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MATH_CONST = __webpack_require__(14); +var Wrap = __webpack_require__(66); +var Angle = __webpack_require__(93); + +/** + * Get the angle of the normal of the given line in radians. + * + * @function Phaser.Geom.Line.NormalAngle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to calculate the angle of the normal of. + * + * @return {number} The angle of the normal of the line in radians. + */ +var NormalAngle = function (line) +{ + var angle = Angle(line) - MATH_CONST.TAU; + + return Wrap(angle, -Math.PI, Math.PI); +}; + +module.exports = NormalAngle; + + +/***/ }), +/* 492 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var flip = true; + +var defaultModelName = 'untitled'; +var currentGroup = ''; +var currentMaterial = ''; + +/** + * @ignore + */ +function stripComments (line) +{ + var idx = line.indexOf('#'); + + return (idx > -1) ? line.substring(0, idx) : line; +} + +/** + * @ignore + */ +function currentModel (result) +{ + if (result.models.length === 0) + { + result.models.push({ + faces: [], + name: defaultModelName, + textureCoords: [], + vertexNormals: [], + vertices: [] + }); + } + + currentGroup = ''; + + return result.models[result.models.length - 1]; +} + +/** + * @ignore + */ +function parseObject (lineItems, result) +{ + var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName; + + result.models.push({ + faces: [], + name: modelName, + textureCoords: [], + vertexNormals: [], + vertices: [] + }); + + currentGroup = ''; +} + +/** + * @ignore + */ +function parseGroup (lineItems) +{ + if (lineItems.length === 2) + { + currentGroup = lineItems[1]; + } +} + +/** + * @ignore + */ +function parseVertexCoords (lineItems, result) +{ + var len = lineItems.length; + + var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + currentModel(result).vertices.push({ x: x, y: y, z: z }); +} + +/** + * @ignore + */ +function parseTextureCoords (lineItems, result) +{ + var len = lineItems.length; + + var u = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var v = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var w = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + if (isNaN(u)) + { + u = 0; + } + + if (isNaN(v)) + { + v = 0; + } + + if (isNaN(w)) + { + w = 0; + } + + if (flip) + { + v = 1 - v; + } + + currentModel(result).textureCoords.push({ u: u, v: v, w: w }); +} + +/** + * @ignore + */ +function parseVertexNormal (lineItems, result) +{ + var len = lineItems.length; + + var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; + + currentModel(result).vertexNormals.push({ x: x, y: y, z: z }); +} + +/** + * @ignore + */ +function parsePolygon (lineItems, result) +{ + var totalVertices = lineItems.length - 1; + + if (totalVertices < 3) + { + return; + } + + var face = { + group: currentGroup, + material: currentMaterial, + vertices: [] + }; + + for (var i = 0; i < totalVertices; i++) + { + var vertexString = lineItems[i + 1]; + var vertexValues = vertexString.split('/'); + var vvLen = vertexValues.length; + + if (vvLen < 1 || vvLen > 3) + { + continue; + } + + var vertexIndex = 0; + var textureCoordsIndex = 0; + var vertexNormalIndex = 0; + + vertexIndex = parseInt(vertexValues[0], 10); + + if (vvLen > 1 && vertexValues[1] !== '') + { + textureCoordsIndex = parseInt(vertexValues[1], 10); + } + + if (vvLen > 2) + { + vertexNormalIndex = parseInt(vertexValues[2], 10); + } + + if (vertexIndex !== 0) + { + // Negative vertex indices refer to the nth last defined vertex + // convert these to postive indices for simplicity + if (vertexIndex < 0) + { + vertexIndex = currentModel(result).vertices.length + 1 + vertexIndex; + } + + textureCoordsIndex -= 1; + vertexIndex -= 1; + vertexNormalIndex -= 1; + + face.vertices.push({ + textureCoordsIndex: textureCoordsIndex, + vertexIndex: vertexIndex, + vertexNormalIndex: vertexNormalIndex + }); + } + } + + currentModel(result).faces.push(face); +} + +/** + * @ignore + */ +function parseMtlLib (lineItems, result) +{ + if (lineItems.length >= 2) + { + result.materialLibraries.push(lineItems[1]); + } +} + +/** + * @ignore + */ +function parseUseMtl (lineItems) +{ + if (lineItems.length >= 2) + { + currentMaterial = lineItems[1]; + } +} + +/** + * Parses a Wavefront OBJ File, extracting the models from it and returning them in an array. + * + * The model data *must* be triangulated for a Mesh Game Object to be able to render it. + * + * @function Phaser.Geom.Mesh.ParseObj + * @since 3.50.0 + * + * @param {string} data - The OBJ File data as a raw string. + * @param {boolean} [flipUV=true] - Flip the UV coordinates? + * + * @return {Phaser.Types.Geom.Mesh.OBJData} The parsed model and material data. + */ +var ParseObj = function (data, flipUV) +{ + if (flipUV === undefined) { flipUV = true; } + + flip = flipUV; + + // Store results in here + var result = { + materials: {}, + materialLibraries: [], + models: [] + }; + + currentGroup = ''; + currentMaterial = ''; + + var lines = data.split('\n'); + + for (var i = 0; i < lines.length; i++) + { + var line = stripComments(lines[i]); + + var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); + + switch (lineItems[0].toLowerCase()) + { + case 'o': + // Start A New Model + parseObject(lineItems, result); + break; + + case 'g': + // Start a new polygon group + parseGroup(lineItems); + break; + + case 'v': + // Define a vertex for the current model + parseVertexCoords(lineItems, result); + break; + + case 'vt': + // Texture Coords + parseTextureCoords(lineItems, result); + break; + + case 'vn': + // Define a vertex normal for the current model + parseVertexNormal(lineItems, result); + break; + + case 'f': + // Define a Face/Polygon + parsePolygon(lineItems, result); + break; + + case 'mtllib': + // Reference to a material library file (.mtl) + parseMtlLib(lineItems, result); + break; + + case 'usemtl': + // Sets the current material to be applied to polygons defined from this point forward + parseUseMtl(lineItems); + break; + } + } + + return result; +}; + +module.exports = ParseObj; + + +/***/ }), +/* 493 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetColor = __webpack_require__(100); + +/** + * Takes a Wavefront Material file and extracts the diffuse reflectivity of the named + * materials, converts them to integer color values and returns them. + * + * This is used internally by the `addOBJ` and `addModel` methods, but is exposed for + * public consumption as well. + * + * Note this only works with diffuse values, specified in the `Kd r g b` format, where + * `g` and `b` are optional, but `r` is required. It does not support spectral rfl files, + * or any other material statement (such as `Ka` or `Ks`) + * + * @method Phaser.Geom.Mesh.ParseObjMaterial + * @since 3.50.0 + * + * @param {string} mtl - The OBJ MTL file as a raw string, i.e. loaded via `this.load.text`. + * + * @return {object} The parsed material colors, where each property of the object matches the material name. + */ +var ParseObjMaterial = function (mtl) +{ + var output = {}; + + var lines = mtl.split('\n'); + + var currentMaterial = ''; + + for (var i = 0; i < lines.length; i++) + { + var line = lines[i].trim(); + + if (line.indexOf('#') === 0 || line === '') + { + continue; + } + + var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); + + switch (lineItems[0].toLowerCase()) + { + case 'newmtl': + { + currentMaterial = lineItems[1]; + break; + } + + // The diffuse reflectivity of the current material + // Support r, [g], [b] format, where g and b are optional + case 'kd': + { + var r = Math.floor(lineItems[1] * 255); + var g = (lineItems.length >= 2) ? Math.floor(lineItems[2] * 255) : r; + var b = (lineItems.length >= 3) ? Math.floor(lineItems[3] * 255) : r; + + output[currentMaterial] = GetColor(r, g, b); + + break; + } + } + } + + return output; +}; + +module.exports = ParseObjMaterial; + + +/***/ }), +/* 494 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the magnitude of the point, which equivalent to the length of the line from the origin to this point. + * + * @function Phaser.Geom.Point.GetMagnitude + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - The point to calculate the magnitude for + * + * @return {number} The resulting magnitude + */ +var GetMagnitude = function (point) +{ + return Math.sqrt((point.x * point.x) + (point.y * point.y)); +}; + +module.exports = GetMagnitude; + + +/***/ }), +/* 495 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates the square of magnitude of given point.(Can be used for fast magnitude calculation of point) + * + * @function Phaser.Geom.Point.GetMagnitudeSq + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - Returns square of the magnitude/length of given point. + * + * @return {number} Returns square of the magnitude of given point. + */ +var GetMagnitudeSq = function (point) +{ + return (point.x * point.x) + (point.y * point.y); +}; + +module.exports = GetMagnitudeSq; + + +/***/ }), +/* 496 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); + +Rectangle.Area = __webpack_require__(1261); +Rectangle.Ceil = __webpack_require__(1262); +Rectangle.CeilAll = __webpack_require__(1263); +Rectangle.CenterOn = __webpack_require__(187); +Rectangle.Clone = __webpack_require__(1264); +Rectangle.Contains = __webpack_require__(56); +Rectangle.ContainsPoint = __webpack_require__(1265); +Rectangle.ContainsRect = __webpack_require__(497); +Rectangle.CopyFrom = __webpack_require__(1266); +Rectangle.Decompose = __webpack_require__(484); +Rectangle.Equals = __webpack_require__(1267); +Rectangle.FitInside = __webpack_require__(1268); +Rectangle.FitOutside = __webpack_require__(1269); +Rectangle.Floor = __webpack_require__(1270); +Rectangle.FloorAll = __webpack_require__(1271); +Rectangle.FromPoints = __webpack_require__(196); +Rectangle.FromXY = __webpack_require__(1272); +Rectangle.GetAspectRatio = __webpack_require__(234); +Rectangle.GetCenter = __webpack_require__(1273); +Rectangle.GetPoint = __webpack_require__(167); +Rectangle.GetPoints = __webpack_require__(300); +Rectangle.GetSize = __webpack_require__(1274); +Rectangle.Inflate = __webpack_require__(1275); +Rectangle.Intersection = __webpack_require__(1276); +Rectangle.MarchingAnts = __webpack_require__(310); +Rectangle.MergePoints = __webpack_require__(1277); +Rectangle.MergeRect = __webpack_require__(1278); +Rectangle.MergeXY = __webpack_require__(1279); +Rectangle.Offset = __webpack_require__(1280); +Rectangle.OffsetPoint = __webpack_require__(1281); +Rectangle.Overlaps = __webpack_require__(1282); +Rectangle.Perimeter = __webpack_require__(128); +Rectangle.PerimeterPoint = __webpack_require__(1283); +Rectangle.Random = __webpack_require__(170); +Rectangle.RandomOutside = __webpack_require__(1284); +Rectangle.SameDimensions = __webpack_require__(1285); +Rectangle.Scale = __webpack_require__(1286); +Rectangle.Union = __webpack_require__(435); + +module.exports = Rectangle; + + +/***/ }), +/* 497 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Tests if one rectangle fully contains another. + * + * @function Phaser.Geom.Rectangle.ContainsRect + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rectA - The first rectangle. + * @param {Phaser.Geom.Rectangle} rectB - The second rectangle. + * + * @return {boolean} True only if rectA fully contains rectB. + */ +var ContainsRect = function (rectA, rectB) +{ + // Volume check (if rectB volume > rectA then rectA cannot contain it) + if ((rectB.width * rectB.height) > (rectA.width * rectA.height)) + { + return false; + } + + return ( + (rectB.x > rectA.x && rectB.x < rectA.right) && + (rectB.right > rectA.x && rectB.right < rectA.right) && + (rectB.y > rectA.y && rectB.y < rectA.bottom) && + (rectB.bottom > rectA.y && rectB.bottom < rectA.bottom) + ); +}; + +module.exports = ContainsRect; + + +/***/ }), +/* 498 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); + +// The three medians (the lines drawn from the vertices to the bisectors of the opposite sides) +// meet in the centroid or center of mass (center of gravity). +// The centroid divides each median in a ratio of 2:1 + +/** + * Calculates the position of a Triangle's centroid, which is also its center of mass (center of gravity). + * + * The centroid is the point in a Triangle at which its three medians (the lines drawn from the vertices to the bisectors of the opposite sides) meet. It divides each one in a 2:1 ratio. + * + * @function Phaser.Geom.Triangle.Centroid + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. + * @param {(Phaser.Geom.Point|object)} [out] - An object to store the coordinates in. + * + * @return {(Phaser.Geom.Point|object)} The `out` object with modified `x` and `y` properties, or a new Point if none was provided. + */ +var Centroid = function (triangle, out) +{ + if (out === undefined) { out = new Point(); } + + out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; + out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; + + return out; +}; + +module.exports = Centroid; + + +/***/ }), +/* 499 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Moves each point (vertex) of a Triangle by a given offset, thus moving the entire Triangle by that offset. + * + * @function Phaser.Geom.Triangle.Offset + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to move. + * @param {number} x - The horizontal offset (distance) by which to move each point. Can be positive or negative. + * @param {number} y - The vertical offset (distance) by which to move each point. Can be positive or negative. + * + * @return {Phaser.Geom.Triangle} The modified Triangle. + */ +var Offset = function (triangle, x, y) +{ + triangle.x1 += x; + triangle.y1 += y; + + triangle.x2 += x; + triangle.y2 += y; + + triangle.x3 += x; + triangle.y3 += y; + + return triangle; +}; + +module.exports = Offset; + + +/***/ }), +/* 500 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(4); + +// The three angle bisectors of a triangle meet in one point called the incenter. +// It is the center of the incircle, the circle inscribed in the triangle. + +function getLength (x1, y1, x2, y2) +{ + var x = x1 - x2; + var y = y1 - y2; + var magnitude = (x * x) + (y * y); + + return Math.sqrt(magnitude); +} + +/** + * Calculates the position of the incenter of a Triangle object. This is the point where its three angle bisectors meet and it's also the center of the incircle, which is the circle inscribed in the triangle. + * + * @function Phaser.Geom.Triangle.InCenter + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to find the incenter of. + * @param {Phaser.Geom.Point} [out] - An optional Point in which to store the coordinates. + * + * @return {Phaser.Geom.Point} Point (x, y) of the center pixel of the triangle. + */ +var InCenter = function (triangle, out) +{ + if (out === undefined) { out = new Point(); } + + var x1 = triangle.x1; + var y1 = triangle.y1; + + var x2 = triangle.x2; + var y2 = triangle.y2; + + var x3 = triangle.x3; + var y3 = triangle.y3; + + var d1 = getLength(x3, y3, x2, y2); + var d2 = getLength(x1, y1, x3, y3); + var d3 = getLength(x2, y2, x1, y1); + + var p = d1 + d2 + d3; + + out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p; + out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p; + + return out; +}; + +module.exports = InCenter; + + +/***/ }), +/* 501 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Creates a new Pixel Perfect Handler function. + * + * Access via `InputPlugin.makePixelPerfect` rather than calling it directly. + * + * @function Phaser.Input.CreatePixelPerfectHandler + * @since 3.10.0 + * + * @param {Phaser.Textures.TextureManager} textureManager - A reference to the Texture Manager. + * @param {number} alphaTolerance - The alpha level that the pixel should be above to be included as a successful interaction. + * + * @return {function} The new Pixel Perfect Handler function. + */ +var CreatePixelPerfectHandler = function (textureManager, alphaTolerance) +{ + return function (hitArea, x, y, gameObject) + { + var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); + + return (alpha && alpha >= alphaTolerance); + }; +}; + +module.exports = CreatePixelPerfectHandler; + + +/***/ }), +/* 502 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Creates a new Interactive Object. + * + * This is called automatically by the Input Manager when you enable a Game Object for input. + * + * The resulting Interactive Object is mapped to the Game Object's `input` property. + * + * @function Phaser.Input.CreateInteractiveObject + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to which this Interactive Object is bound. + * @param {any} hitArea - The hit area for this Interactive Object. Typically a geometry shape, like a Rectangle or Circle. + * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - The 'contains' check callback that the hit area shape will use for all hit tests. + * + * @return {Phaser.Types.Input.InteractiveObject} The new Interactive Object. + */ +var CreateInteractiveObject = function (gameObject, hitArea, hitAreaCallback) +{ + return { + + gameObject: gameObject, + + enabled: true, + alwaysEnabled: false, + draggable: false, + dropZone: false, + cursor: false, + + target: null, + + camera: null, + + hitArea: hitArea, + hitAreaCallback: hitAreaCallback, + hitAreaDebug: null, + + // Has the dev specified their own shape, or is this bound to the texture size? + customHitArea: false, + + localX: 0, + localY: 0, + + // 0 = Not being dragged + // 1 = Being checked for dragging + // 2 = Being dragged + dragState: 0, + + dragStartX: 0, + dragStartY: 0, + dragStartXGlobal: 0, + dragStartYGlobal: 0, + + dragX: 0, + dragY: 0 + + }; +}; + +module.exports = CreateInteractiveObject; + + +/***/ }), +/* 503 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * Contains information about a specific Gamepad Axis. + * Axis objects are created automatically by the Gamepad as they are needed. + * + * @class Axis + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Axis belongs to. + * @param {number} index - The index of this Axis. + */ +var Axis = new Class({ + + initialize: + + function Axis (pad, index) + { + /** + * A reference to the Gamepad that this Axis belongs to. + * + * @name Phaser.Input.Gamepad.Axis#pad + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.0.0 + */ + this.pad = pad; + + /** + * An event emitter to use to emit the axis events. + * + * @name Phaser.Input.Gamepad.Axis#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = pad.events; + + /** + * The index of this Axis. + * + * @name Phaser.Input.Gamepad.Axis#index + * @type {number} + * @since 3.0.0 + */ + this.index = index; + + /** + * The raw axis value, between -1 and 1 with 0 being dead center. + * Use the method `getValue` to get a normalized value with the threshold applied. + * + * @name Phaser.Input.Gamepad.Axis#value + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.value = 0; + + /** + * Movement tolerance threshold below which axis values are ignored in `getValue`. + * + * @name Phaser.Input.Gamepad.Axis#threshold + * @type {number} + * @default 0.1 + * @since 3.0.0 + */ + this.threshold = 0.1; + }, + + /** + * Internal update handler for this Axis. + * Called automatically by the Gamepad as part of its update. + * + * @method Phaser.Input.Gamepad.Axis#update + * @private + * @since 3.0.0 + * + * @param {number} value - The value of the axis movement. + */ + update: function (value) + { + this.value = value; + }, + + /** + * Applies the `threshold` value to the axis and returns it. + * + * @method Phaser.Input.Gamepad.Axis#getValue + * @since 3.0.0 + * + * @return {number} The axis value, adjusted for the movement threshold. + */ + getValue: function () + { + return (Math.abs(this.value) < this.threshold) ? 0 : this.value; + }, + + /** + * Destroys this Axis instance and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Axis#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.pad = null; + this.events = null; + } + +}); + +module.exports = Axis; + + +/***/ }), +/* 504 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(236); + +/** + * @classdesc + * Contains information about a specific button on a Gamepad. + * Button objects are created automatically by the Gamepad as they are needed. + * + * @class Button + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.Gamepad} pad - A reference to the Gamepad that this Button belongs to. + * @param {number} index - The index of this Button. + */ +var Button = new Class({ + + initialize: + + function Button (pad, index) + { + /** + * A reference to the Gamepad that this Button belongs to. + * + * @name Phaser.Input.Gamepad.Button#pad + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.0.0 + */ + this.pad = pad; + + /** + * An event emitter to use to emit the button events. + * + * @name Phaser.Input.Gamepad.Button#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = pad.manager; + + /** + * The index of this Button. + * + * @name Phaser.Input.Gamepad.Button#index + * @type {number} + * @since 3.0.0 + */ + this.index = index; + + /** + * Between 0 and 1. + * + * @name Phaser.Input.Gamepad.Button#value + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.value = 0; + + /** + * Can be set for analogue buttons to enable a 'pressure' threshold, + * before a button is considered as being 'pressed'. + * + * @name Phaser.Input.Gamepad.Button#threshold + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.threshold = 1; + + /** + * Is the Button being pressed down or not? + * + * @name Phaser.Input.Gamepad.Button#pressed + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.pressed = false; + }, + + /** + * Internal update handler for this Button. + * Called automatically by the Gamepad as part of its update. + * + * @method Phaser.Input.Gamepad.Button#update + * @fires Phaser.Input.Gamepad.Events#BUTTON_DOWN + * @fires Phaser.Input.Gamepad.Events#BUTTON_UP + * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN + * @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP + * @private + * @since 3.0.0 + * + * @param {number} value - The value of the button. Between 0 and 1. + */ + update: function (value) + { + this.value = value; + + var pad = this.pad; + var index = this.index; + + if (value >= this.threshold) + { + if (!this.pressed) + { + this.pressed = true; + this.events.emit(Events.BUTTON_DOWN, pad, this, value); + this.pad.emit(Events.GAMEPAD_BUTTON_DOWN, index, value, this); + } + } + else if (this.pressed) + { + this.pressed = false; + this.events.emit(Events.BUTTON_UP, pad, this, value); + this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this); + } + }, + + /** + * Destroys this Button instance and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Button#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.pad = null; + this.events = null; + } + +}); + +module.exports = Button; + + +/***/ }), +/* 505 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Axis = __webpack_require__(503); +var Button = __webpack_require__(504); +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A single Gamepad. + * + * These are created, updated and managed by the Gamepad Plugin. + * + * @class Gamepad + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad.GamepadPlugin} manager - A reference to the Gamepad Plugin. + * @param {Phaser.Types.Input.Gamepad.Pad} pad - The Gamepad object, as extracted from GamepadEvent. + */ +var Gamepad = new Class({ + + Extends: EventEmitter, + + initialize: + + function Gamepad (manager, pad) + { + EventEmitter.call(this); + + /** + * A reference to the Gamepad Plugin. + * + * @name Phaser.Input.Gamepad.Gamepad#manager + * @type {Phaser.Input.Gamepad.GamepadPlugin} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * A reference to the native Gamepad object that is connected to the browser. + * + * @name Phaser.Input.Gamepad.Gamepad#pad + * @type {any} + * @since 3.10.0 + */ + this.pad = pad; + + /** + * A string containing some information about the controller. + * + * This is not strictly specified, but in Firefox it will contain three pieces of information + * separated by dashes (-): two 4-digit hexadecimal strings containing the USB vendor and + * product id of the controller, and the name of the controller as provided by the driver. + * In Chrome it will contain the name of the controller as provided by the driver, + * followed by vendor and product 4-digit hexadecimal strings. + * + * @name Phaser.Input.Gamepad.Gamepad#id + * @type {string} + * @since 3.0.0 + */ + this.id = pad.id; + + /** + * An integer that is unique for each Gamepad currently connected to the system. + * This can be used to distinguish multiple controllers. + * Note that disconnecting a device and then connecting a new device may reuse the previous index. + * + * @name Phaser.Input.Gamepad.Gamepad#index + * @type {number} + * @since 3.0.0 + */ + this.index = pad.index; + + var buttons = []; + + for (var i = 0; i < pad.buttons.length; i++) + { + buttons.push(new Button(this, i)); + } + + /** + * An array of Gamepad Button objects, corresponding to the different buttons available on the Gamepad. + * + * @name Phaser.Input.Gamepad.Gamepad#buttons + * @type {Phaser.Input.Gamepad.Button[]} + * @since 3.0.0 + */ + this.buttons = buttons; + + var axes = []; + + for (i = 0; i < pad.axes.length; i++) + { + axes.push(new Axis(this, i)); + } + + /** + * An array of Gamepad Axis objects, corresponding to the different axes available on the Gamepad, if any. + * + * @name Phaser.Input.Gamepad.Gamepad#axes + * @type {Phaser.Input.Gamepad.Axis[]} + * @since 3.0.0 + */ + this.axes = axes; + + /** + * The Gamepad's Haptic Actuator (Vibration / Rumble support). + * This is highly experimental and only set if both present on the device, + * and exposed by both the hardware and browser. + * + * @name Phaser.Input.Gamepad.Gamepad#vibration + * @type {GamepadHapticActuator} + * @since 3.10.0 + */ + this.vibration = pad.vibrationActuator; + + // https://w3c.github.io/gamepad/#remapping + + var _noButton = { value: 0, pressed: false }; + + /** + * A reference to the Left Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCLeft = (buttons[14]) ? buttons[14] : _noButton; + + /** + * A reference to the Right Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCRight = (buttons[15]) ? buttons[15] : _noButton; + + /** + * A reference to the Top Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCTop = (buttons[12]) ? buttons[12] : _noButton; + + /** + * A reference to the Bottom Button in the Left Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_LCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._LCBottom = (buttons[13]) ? buttons[13] : _noButton; + + /** + * A reference to the Left Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCLeft = (buttons[2]) ? buttons[2] : _noButton; + + /** + * A reference to the Right Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCRight = (buttons[1]) ? buttons[1] : _noButton; + + /** + * A reference to the Top Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCTop = (buttons[3]) ? buttons[3] : _noButton; + + /** + * A reference to the Bottom Button in the Right Cluster. + * + * @name Phaser.Input.Gamepad.Gamepad#_RCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._RCBottom = (buttons[0]) ? buttons[0] : _noButton; + + /** + * A reference to the Top Left Front Button (L1 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBLeftTop = (buttons[4]) ? buttons[4] : _noButton; + + /** + * A reference to the Bottom Left Front Button (L2 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBLeftBottom = (buttons[6]) ? buttons[6] : _noButton; + + /** + * A reference to the Top Right Front Button (R1 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBRightTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBRightTop = (buttons[5]) ? buttons[5] : _noButton; + + /** + * A reference to the Bottom Right Front Button (R2 Shoulder Button) + * + * @name Phaser.Input.Gamepad.Gamepad#_FBRightBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._FBRightBottom = (buttons[7]) ? buttons[7] : _noButton; + + var _noAxis = { value: 0 }; + + /** + * A reference to the Horizontal Axis for the Left Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_HAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._HAxisLeft = (axes[0]) ? axes[0] : _noAxis; + + /** + * A reference to the Vertical Axis for the Left Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_VAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._VAxisLeft = (axes[1]) ? axes[1] : _noAxis; + + /** + * A reference to the Horizontal Axis for the Right Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_HAxisRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._HAxisRight = (axes[2]) ? axes[2] : _noAxis; + + /** + * A reference to the Vertical Axis for the Right Stick. + * + * @name Phaser.Input.Gamepad.Gamepad#_VAxisRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 + */ + this._VAxisRight = (axes[3]) ? axes[3] : _noAxis; + + /** + * A Vector2 containing the most recent values from the Gamepad's left axis stick. + * This is updated automatically as part of the Gamepad.update cycle. + * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. + * The values are based on the Axis thresholds. + * If the Gamepad does not have a left axis stick, the values will always be zero. + * + * @name Phaser.Input.Gamepad.Gamepad#leftStick + * @type {Phaser.Math.Vector2} + * @since 3.10.0 + */ + this.leftStick = new Vector2(); + + /** + * A Vector2 containing the most recent values from the Gamepad's right axis stick. + * This is updated automatically as part of the Gamepad.update cycle. + * The H Axis is mapped to the `Vector2.x` property, and the V Axis to the `Vector2.y` property. + * The values are based on the Axis thresholds. + * If the Gamepad does not have a right axis stick, the values will always be zero. + * + * @name Phaser.Input.Gamepad.Gamepad#rightStick + * @type {Phaser.Math.Vector2} + * @since 3.10.0 + */ + this.rightStick = new Vector2(); + + /** + * When was this Gamepad created? Used to avoid duplicate event spamming in the update loop. + * + * @name Phaser.Input.Gamepad.Gamepad#_created + * @type {number} + * @private + * @since 3.50.0 + */ + this._created = performance.now(); + }, + + /** + * Gets the total number of axis this Gamepad claims to support. + * + * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal + * @since 3.10.0 + * + * @return {number} The total number of axes this Gamepad claims to support. + */ + getAxisTotal: function () + { + return this.axes.length; + }, + + /** + * Gets the value of an axis based on the given index. + * The index must be valid within the range of axes supported by this Gamepad. + * The return value will be a float between 0 and 1. + * + * @method Phaser.Input.Gamepad.Gamepad#getAxisValue + * @since 3.10.0 + * + * @param {number} index - The index of the axes to get the value for. + * + * @return {number} The value of the axis, between 0 and 1. + */ + getAxisValue: function (index) + { + return this.axes[index].getValue(); + }, + + /** + * Sets the threshold value of all axis on this Gamepad. + * The value is a float between 0 and 1 and is the amount below which the axis is considered as not having been moved. + * + * @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold + * @since 3.10.0 + * + * @param {number} value - A value between 0 and 1. + */ + setAxisThreshold: function (value) + { + for (var i = 0; i < this.axes.length; i++) + { + this.axes[i].threshold = value; + } + }, + + /** + * Gets the total number of buttons this Gamepad claims to have. + * + * @method Phaser.Input.Gamepad.Gamepad#getButtonTotal + * @since 3.10.0 + * + * @return {number} The total number of buttons this Gamepad claims to have. + */ + getButtonTotal: function () + { + return this.buttons.length; + }, + + /** + * Gets the value of a button based on the given index. + * The index must be valid within the range of buttons supported by this Gamepad. + * + * The return value will be either 0 or 1 for an analogue button, or a float between 0 and 1 + * for a pressure-sensitive digital button, such as the shoulder buttons on a Dual Shock. + * + * @method Phaser.Input.Gamepad.Gamepad#getButtonValue + * @since 3.10.0 + * + * @param {number} index - The index of the button to get the value for. + * + * @return {number} The value of the button, between 0 and 1. + */ + getButtonValue: function (index) + { + return this.buttons[index].value; + }, + + /** + * Returns if the button is pressed down or not. + * The index must be valid within the range of buttons supported by this Gamepad. + * + * @method Phaser.Input.Gamepad.Gamepad#isButtonDown + * @since 3.10.0 + * + * @param {number} index - The index of the button to get the value for. + * + * @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`. + */ + isButtonDown: function (index) + { + return this.buttons[index].pressed; + }, + + /** + * Internal update handler for this Gamepad. + * Called automatically by the Gamepad Manager as part of its update. + * + * @method Phaser.Input.Gamepad.Gamepad#update + * @private + * @since 3.0.0 + */ + update: function (pad) + { + if (pad.timestamp < this._created) + { + return; + } + + var i; + + // Sync the button values + + var localButtons = this.buttons; + var gamepadButtons = pad.buttons; + + var len = localButtons.length; + + for (i = 0; i < len; i++) + { + localButtons[i].update(gamepadButtons[i].value); + } + + // Sync the axis values + + var localAxes = this.axes; + var gamepadAxes = pad.axes; + + len = localAxes.length; + + for (i = 0; i < len; i++) + { + localAxes[i].update(gamepadAxes[i]); + } + + if (len >= 2) + { + this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue()); + + if (len >= 4) + { + this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue()); + } + } + }, + + /** + * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. + * + * @method Phaser.Input.Gamepad.Gamepad#destroy + * @since 3.10.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.manager = null; + this.pad = null; + + var i; + + for (i = 0; i < this.buttons.length; i++) + { + this.buttons[i].destroy(); + } + + for (i = 0; i < this.axes.length; i++) + { + this.axes[i].destroy(); + } + + this.buttons = []; + this.axes = []; + }, + + /** + * Is this Gamepad currently connected or not? + * + * @name Phaser.Input.Gamepad.Gamepad#connected + * @type {boolean} + * @default true + * @since 3.0.0 + */ + connected: { + + get: function () + { + return this.pad.connected; + } + + }, + + /** + * A timestamp containing the most recent time this Gamepad was updated. + * + * @name Phaser.Input.Gamepad.Gamepad#timestamp + * @type {number} + * @since 3.0.0 + */ + timestamp: { + + get: function () + { + return this.pad.timestamp; + } + + }, + + /** + * Is the Gamepad's Left button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad left button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#left + * @type {boolean} + * @since 3.10.0 + */ + left: { + + get: function () + { + return this._LCLeft.pressed; + } + + }, + + /** + * Is the Gamepad's Right button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad right button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#right + * @type {boolean} + * @since 3.10.0 + */ + right: { + + get: function () + { + return this._LCRight.pressed; + } + + }, + + /** + * Is the Gamepad's Up button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad up button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#up + * @type {boolean} + * @since 3.10.0 + */ + up: { + + get: function () + { + return this._LCTop.pressed; + } + + }, + + /** + * Is the Gamepad's Down button being pressed? + * If the Gamepad doesn't have this button it will always return false. + * This is the d-pad down button under standard Gamepad mapping. + * + * @name Phaser.Input.Gamepad.Gamepad#down + * @type {boolean} + * @since 3.10.0 + */ + down: { + + get: function () + { + return this._LCBottom.pressed; + } + + }, + + /** + * Is the Gamepad's bottom button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the X button. + * On an XBox controller it's the A button. + * + * @name Phaser.Input.Gamepad.Gamepad#A + * @type {boolean} + * @since 3.10.0 + */ + A: { + + get: function () + { + return this._RCBottom.pressed; + } + + }, + + /** + * Is the Gamepad's top button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Triangle button. + * On an XBox controller it's the Y button. + * + * @name Phaser.Input.Gamepad.Gamepad#Y + * @type {boolean} + * @since 3.10.0 + */ + Y: { + + get: function () + { + return this._RCTop.pressed; + } + + }, + + /** + * Is the Gamepad's left button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Square button. + * On an XBox controller it's the X button. + * + * @name Phaser.Input.Gamepad.Gamepad#X + * @type {boolean} + * @since 3.10.0 + */ + X: { + + get: function () + { + return this._RCLeft.pressed; + } + + }, + + /** + * Is the Gamepad's right button in the right button cluster being pressed? + * If the Gamepad doesn't have this button it will always return false. + * On a Dual Shock controller it's the Circle button. + * On an XBox controller it's the B button. + * + * @name Phaser.Input.Gamepad.Gamepad#B + * @type {boolean} + * @since 3.10.0 + */ + B: { + + get: function () + { + return this._RCRight.pressed; + } + + }, + + /** + * Returns the value of the Gamepad's top left shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the L1 button. + * On an XBox controller it's the LB button. + * + * @name Phaser.Input.Gamepad.Gamepad#L1 + * @type {number} + * @since 3.10.0 + */ + L1: { + + get: function () + { + return this._FBLeftTop.value; + } + + }, + + /** + * Returns the value of the Gamepad's bottom left shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the L2 button. + * On an XBox controller it's the LT button. + * + * @name Phaser.Input.Gamepad.Gamepad#L2 + * @type {number} + * @since 3.10.0 + */ + L2: { + + get: function () + { + return this._FBLeftBottom.value; + } + + }, + + /** + * Returns the value of the Gamepad's top right shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the R1 button. + * On an XBox controller it's the RB button. + * + * @name Phaser.Input.Gamepad.Gamepad#R1 + * @type {number} + * @since 3.10.0 + */ + R1: { + + get: function () + { + return this._FBRightTop.value; + } + + }, + + /** + * Returns the value of the Gamepad's bottom right shoulder button. + * If the Gamepad doesn't have this button it will always return zero. + * The value is a float between 0 and 1, corresponding to how depressed the button is. + * On a Dual Shock controller it's the R2 button. + * On an XBox controller it's the RT button. + * + * @name Phaser.Input.Gamepad.Gamepad#R2 + * @type {number} + * @since 3.10.0 + */ + R2: { + + get: function () + { + return this._FBRightBottom.value; + } + + } + +}); + +module.exports = Gamepad; + + +/***/ }), +/* 506 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(152); + +/** + * @classdesc + * A generic Key object which can be passed to the Process functions (and so on) + * keycode must be an integer + * + * @class Key + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Keyboard + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyboardPlugin} plugin - The Keyboard Plugin instance that owns this Key object. + * @param {number} keyCode - The keycode of this key. + */ +var Key = new Class({ + + Extends: EventEmitter, + + initialize: + + function Key (plugin, keyCode) + { + EventEmitter.call(this); + + /** + * The Keyboard Plugin instance that owns this Key object. + * + * @name Phaser.Input.Keyboard.Key#plugin + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.17.0 + */ + this.plugin = plugin; + + /** + * The keycode of this key. + * + * @name Phaser.Input.Keyboard.Key#keyCode + * @type {number} + * @since 3.0.0 + */ + this.keyCode = keyCode; + + /** + * The original DOM event. + * + * @name Phaser.Input.Keyboard.Key#originalEvent + * @type {KeyboardEvent} + * @since 3.0.0 + */ + this.originalEvent = undefined; + + /** + * Can this Key be processed? + * + * @name Phaser.Input.Keyboard.Key#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down. + * + * @name Phaser.Input.Keyboard.Key#isDown + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isDown = false; + + /** + * The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up. + * + * @name Phaser.Input.Keyboard.Key#isUp + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.isUp = true; + + /** + * The down state of the ALT key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#altKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.altKey = false; + + /** + * The down state of the CTRL key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#ctrlKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.ctrlKey = false; + + /** + * The down state of the SHIFT key, if pressed at the same time as this key. + * + * @name Phaser.Input.Keyboard.Key#shiftKey + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shiftKey = false; + + /** + * The down state of the Meta key, if pressed at the same time as this key. + * On a Mac the Meta Key is the Command key. On Windows keyboards, it's the Windows key. + * + * @name Phaser.Input.Keyboard.Key#metaKey + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.metaKey = false; + + /** + * The location of the modifier key. 0 for standard (or unknown), 1 for left, 2 for right, 3 for numpad. + * + * @name Phaser.Input.Keyboard.Key#location + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.location = 0; + + /** + * The timestamp when the key was last pressed down. + * + * @name Phaser.Input.Keyboard.Key#timeDown + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeDown = 0; + + /** + * The number of milliseconds this key was held down for in the previous down - up sequence. + * This value isn't updated every game step, only when the Key changes state. + * To get the current duration use the `getDuration` method. + * + * @name Phaser.Input.Keyboard.Key#duration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.duration = 0; + + /** + * The timestamp when the key was last released. + * + * @name Phaser.Input.Keyboard.Key#timeUp + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeUp = 0; + + /** + * When a key is held down should it continuously fire the `down` event each time it repeats? + * + * By default it will emit the `down` event just once, but if you wish to receive the event + * for each repeat as well, enable this property. + * + * @name Phaser.Input.Keyboard.Key#emitOnRepeat + * @type {boolean} + * @default false + * @since 3.16.0 + */ + this.emitOnRepeat = false; + + /** + * If a key is held down this holds down the number of times the key has 'repeated'. + * + * @name Phaser.Input.Keyboard.Key#repeats + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeats = 0; + + /** + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) + * + * @name Phaser.Input.Keyboard.Key#_justDown + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._justDown = false; + + /** + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) + * + * @name Phaser.Input.Keyboard.Key#_justUp + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._justUp = false; + + /** + * Internal tick counter. + * + * @name Phaser.Input.Keyboard.Key#_tick + * @type {number} + * @private + * @since 3.11.0 + */ + this._tick = -1; + }, + + /** + * Controls if this Key will continuously emit a `down` event while being held down (true), + * or emit the event just once, on first press, and then skip future events (false). + * + * @method Phaser.Input.Keyboard.Key#setEmitOnRepeat + * @since 3.16.0 + * + * @param {boolean} value - Emit `down` events on repeated key down actions, or just once? + * + * @return {this} This Key instance. + */ + setEmitOnRepeat: function (value) + { + this.emitOnRepeat = value; + + return this; + }, + + /** + * Processes the Key Down action for this Key. + * Called automatically by the Keyboard Plugin. + * + * @method Phaser.Input.Keyboard.Key#onDown + * @fires Phaser.Input.Keyboard.Events#DOWN + * @since 3.16.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard event. + */ + onDown: function (event) + { + this.originalEvent = event; + + if (!this.enabled) + { + return; + } + + this.altKey = event.altKey; + this.ctrlKey = event.ctrlKey; + this.shiftKey = event.shiftKey; + this.metaKey = event.metaKey; + this.location = event.location; + + this.repeats++; + + if (!this.isDown) + { + this.isDown = true; + this.isUp = false; + this.timeDown = event.timeStamp; + this.duration = 0; + this._justDown = true; + this._justUp = false; + + this.emit(Events.DOWN, this, event); + } + else if (this.emitOnRepeat) + { + this.emit(Events.DOWN, this, event); + } + }, + + /** + * Processes the Key Up action for this Key. + * Called automatically by the Keyboard Plugin. + * + * @method Phaser.Input.Keyboard.Key#onUp + * @fires Phaser.Input.Keyboard.Events#UP + * @since 3.16.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard event. + */ + onUp: function (event) + { + this.originalEvent = event; + + if (!this.enabled) + { + return; + } + + this.isDown = false; + this.isUp = true; + this.timeUp = event.timeStamp; + this.duration = this.timeUp - this.timeDown; + this.repeats = 0; + + this._justDown = false; + this._justUp = true; + this._tick = -1; + + this.emit(Events.UP, this, event); + }, + + /** + * Resets this Key object back to its default un-pressed state. + * + * @method Phaser.Input.Keyboard.Key#reset + * @since 3.6.0 + * + * @return {this} This Key instance. + */ + reset: function () + { + this.preventDefault = true; + this.enabled = true; + this.isDown = false; + this.isUp = true; + this.altKey = false; + this.ctrlKey = false; + this.shiftKey = false; + this.metaKey = false; + this.timeDown = 0; + this.duration = 0; + this.timeUp = 0; + this.repeats = 0; + this._justDown = false; + this._justUp = false; + this._tick = -1; + + return this; + }, + + /** + * Returns the duration, in ms, that the Key has been held down for. + * + * If the key is not currently down it will return zero. + * + * The get the duration the Key was held down for in the previous up-down cycle, + * use the `Key.duration` property value instead. + * + * @method Phaser.Input.Keyboard.Key#getDuration + * @since 3.17.0 + * + * @return {number} The duration, in ms, that the Key has been held down for if currently down. + */ + getDuration: function () + { + if (this.isDown) + { + return (this.plugin.game.loop.time - this.timeDown); + } + else + { + return 0; + } + }, + + /** + * Removes any bound event handlers and removes local references. + * + * @method Phaser.Input.Keyboard.Key#destroy + * @since 3.16.0 + */ + destroy: function () + { + this.removeAllListeners(); + + this.originalEvent = null; + + this.plugin = null; + } + +}); + +module.exports = Key; + + +/***/ }), +/* 507 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(152); +var GetFastValue = __webpack_require__(2); +var ProcessKeyCombo = __webpack_require__(508); +var ResetKeyCombo = __webpack_require__(510); + +/** + * @classdesc + * A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them + * it will emit a `keycombomatch` event from the Keyboard Manager. + * + * The keys to be listened for can be defined as: + * + * A string (i.e. 'ATARI') + * An array of either integers (key codes) or strings, or a mixture of both + * An array of objects (such as Key objects) with a public 'keyCode' property + * + * For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter) + * you could pass the following array of key codes: + * + * ```javascript + * this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true }); + * + * this.input.keyboard.on('keycombomatch', function (event) { + * console.log('Konami Code entered!'); + * }); + * ``` + * + * Or, to listen for the user entering the word PHASER: + * + * ```javascript + * this.input.keyboard.createCombo('PHASER'); + * ``` + * + * @class KeyCombo + * @memberof Phaser.Input.Keyboard + * @constructor + * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyboardPlugin} keyboardPlugin - A reference to the Keyboard Plugin. + * @param {(string|number[]|object[])} keys - The keys that comprise this combo. + * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. + */ +var KeyCombo = new Class({ + + initialize: + + function KeyCombo (keyboardPlugin, keys, config) + { + if (config === undefined) { config = {}; } + + // Can't have a zero or single length combo (string or array based) + if (keys.length < 2) + { + return false; + } + + /** + * A reference to the Keyboard Manager + * + * @name Phaser.Input.Keyboard.KeyCombo#manager + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.0.0 + */ + this.manager = keyboardPlugin; + + /** + * A flag that controls if this Key Combo is actively processing keys or not. + * + * @name Phaser.Input.Keyboard.KeyCombo#enabled + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enabled = true; + + /** + * An array of the keycodes that comprise this combo. + * + * @name Phaser.Input.Keyboard.KeyCombo#keyCodes + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.keyCodes = []; + + // if 'keys' is a string we need to get the keycode of each character in it + + for (var i = 0; i < keys.length; i++) + { + var char = keys[i]; + + if (typeof char === 'string') + { + this.keyCodes.push(char.toUpperCase().charCodeAt(0)); + } + else if (typeof char === 'number') + { + this.keyCodes.push(char); + } + else if (char.hasOwnProperty('keyCode')) + { + this.keyCodes.push(char.keyCode); + } + } + + /** + * The current keyCode the combo is waiting for. + * + * @name Phaser.Input.Keyboard.KeyCombo#current + * @type {number} + * @since 3.0.0 + */ + this.current = this.keyCodes[0]; + + /** + * The current index of the key being waited for in the 'keys' string. + * + * @name Phaser.Input.Keyboard.KeyCombo#index + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.index = 0; + + /** + * The length of this combo (in keycodes) + * + * @name Phaser.Input.Keyboard.KeyCombo#size + * @type {number} + * @since 3.0.0 + */ + this.size = this.keyCodes.length; + + /** + * The time the previous key in the combo was matched. + * + * @name Phaser.Input.Keyboard.KeyCombo#timeLastMatched + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeLastMatched = 0; + + /** + * Has this Key Combo been matched yet? + * + * @name Phaser.Input.Keyboard.KeyCombo#matched + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.matched = false; + + /** + * The time the entire combo was matched. + * + * @name Phaser.Input.Keyboard.KeyCombo#timeMatched + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeMatched = 0; + + /** + * If they press the wrong key do we reset the combo? + * + * @name Phaser.Input.Keyboard.KeyCombo#resetOnWrongKey + * @type {boolean} + * @default 0 + * @since 3.0.0 + */ + this.resetOnWrongKey = GetFastValue(config, 'resetOnWrongKey', true); + + /** + * The max delay in ms between each key press. Above this the combo is reset. 0 means disabled. + * + * @name Phaser.Input.Keyboard.KeyCombo#maxKeyDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxKeyDelay = GetFastValue(config, 'maxKeyDelay', 0); + + /** + * If previously matched and they press the first key of the combo again, will it reset? + * + * @name Phaser.Input.Keyboard.KeyCombo#resetOnMatch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.resetOnMatch = GetFastValue(config, 'resetOnMatch', false); + + /** + * If the combo matches, will it delete itself? + * + * @name Phaser.Input.Keyboard.KeyCombo#deleteOnMatch + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.deleteOnMatch = GetFastValue(config, 'deleteOnMatch', false); + + var _this = this; + + var onKeyDownHandler = function (event) + { + if (_this.matched || !_this.enabled) + { + return; + } + + var matched = ProcessKeyCombo(event, _this); + + if (matched) + { + _this.manager.emit(Events.COMBO_MATCH, _this, event); + + if (_this.resetOnMatch) + { + ResetKeyCombo(_this); + } + else if (_this.deleteOnMatch) + { + _this.destroy(); + } + } + }; + + /** + * The internal Key Down handler. + * + * @name Phaser.Input.Keyboard.KeyCombo#onKeyDown + * @private + * @type {KeyboardKeydownCallback} + * @fires Phaser.Input.Keyboard.Events#COMBO_MATCH + * @since 3.0.0 + */ + this.onKeyDown = onKeyDownHandler; + + this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown); + }, + + /** + * How far complete is this combo? A value between 0 and 1. + * + * @name Phaser.Input.Keyboard.KeyCombo#progress + * @type {number} + * @readonly + * @since 3.0.0 + */ + progress: { + + get: function () + { + return this.index / this.size; + } + + }, + + /** + * Destroys this Key Combo and all of its references. + * + * @method Phaser.Input.Keyboard.KeyCombo#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enabled = false; + this.keyCodes = []; + + this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown); + + this.manager = null; + } + +}); + +module.exports = KeyCombo; + + +/***/ }), +/* 508 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AdvanceKeyCombo = __webpack_require__(509); + +/** + * Used internally by the KeyCombo class. + * + * @function Phaser.Input.Keyboard.ProcessKeyCombo + * @private + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native Keyboard Event. + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to be processed. + * + * @return {boolean} `true` if the combo was matched, otherwise `false`. + */ +var ProcessKeyCombo = function (event, combo) +{ + if (combo.matched) + { + return true; + } + + var comboMatched = false; + var keyMatched = false; + + if (event.keyCode === combo.current) + { + // Key was correct + + if (combo.index > 0 && combo.maxKeyDelay > 0) + { + // We have to check to see if the delay between + // the new key and the old one was too long (if enabled) + + var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; + + // Check if they pressed it in time or not + if (event.timeStamp <= timeLimit) + { + keyMatched = true; + comboMatched = AdvanceKeyCombo(event, combo); + } + } + else + { + keyMatched = true; + + // We don't check the time for the first key pressed, so just advance it + comboMatched = AdvanceKeyCombo(event, combo); + } + } + + if (!keyMatched && combo.resetOnWrongKey) + { + // Wrong key was pressed + combo.index = 0; + combo.current = combo.keyCodes[0]; + } + + if (comboMatched) + { + combo.timeLastMatched = event.timeStamp; + combo.matched = true; + combo.timeMatched = event.timeStamp; + } + + return comboMatched; +}; + +module.exports = ProcessKeyCombo; + + +/***/ }), +/* 509 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Used internally by the KeyCombo class. + * Return `true` if it reached the end of the combo, `false` if not. + * + * @function Phaser.Input.Keyboard.AdvanceKeyCombo + * @private + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native Keyboard Event. + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. + * + * @return {boolean} `true` if it reached the end of the combo, `false` if not. + */ +var AdvanceKeyCombo = function (event, combo) +{ + combo.timeLastMatched = event.timeStamp; + combo.index++; + + if (combo.index === combo.size) + { + return true; + } + else + { + combo.current = combo.keyCodes[combo.index]; + return false; + } +}; + +module.exports = AdvanceKeyCombo; + + +/***/ }), +/* 510 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Used internally by the KeyCombo class. + * + * @function Phaser.Input.Keyboard.ResetKeyCombo + * @private + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo to reset. + * + * @return {Phaser.Input.Keyboard.KeyCombo} The KeyCombo. + */ +var ResetKeyCombo = function (combo) +{ + combo.current = combo.keyCodes[0]; + combo.index = 0; + combo.timeLastMatched = 0; + combo.matched = false; + combo.timeMatched = 0; + + return combo; +}; + +module.exports = ResetKeyCombo; + + +/***/ }), +/* 511 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MergeXHRSettings = __webpack_require__(237); + +/** + * 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; + + +/***/ }), +/* 512 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var HTML5AudioFile = __webpack_require__(513); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Audio File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. + * + * @class AudioFile + * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {any} [urlConfig] - The absolute or relative URL to load this file from in a config object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @param {AudioContext} [audioContext] - The AudioContext this file will use to process itself. + */ +var AudioFile = new Class({ + + Extends: File, + + initialize: + + // URL is an object created by AudioFile.findAudioURL + function AudioFile (loader, key, urlConfig, xhrSettings, audioContext) + { + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + audioContext = GetFastValue(config, 'context', audioContext); + } + + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: urlConfig.type, + responseType: 'arraybuffer', + key: key, + url: urlConfig.url, + xhrSettings: xhrSettings, + config: { context: audioContext } + }; + + 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.AudioFile#onProcess + * @since 3.0.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + var _this = this; + + // interesting read https://github.com/WebAudio/web-audio-api/issues/1305 + this.config.context.decodeAudioData(this.xhrLoader.response, + function (audioBuffer) + { + _this.data = audioBuffer; + + _this.onProcessComplete(); + }, + function (e) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + _this.key + ' - ', e ? e.message : null); + + _this.onProcessError(); + } + ); + + this.config.context = null; + } + +}); + +AudioFile.create = function (loader, key, urls, config, xhrSettings) +{ + var game = loader.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + // url may be inside key, which may be an object + if (IsPlainObject(key)) + { + urls = GetFastValue(key, 'url', []); + config = GetFastValue(key, 'config', {}); + } + + var urlConfig = AudioFile.getAudioURL(game, urls); + + if (!urlConfig) + { + return null; + } + + // https://developers.google.com/web/updates/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs + // var stream = GetFastValue(config, 'stream', false); + + if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + { + return new AudioFile(loader, key, urlConfig, xhrSettings, game.sound.context); + } + else + { + return new HTML5AudioFile(loader, key, urlConfig, config); + } +}; + +AudioFile.getAudioURL = function (game, urls) +{ + if (!Array.isArray(urls)) + { + urls = [ urls ]; + } + + for (var i = 0; i < urls.length; i++) + { + var url = GetFastValue(urls[i], 'url', urls[i]); + + if (url.indexOf('blob:') === 0 || url.indexOf('data:') === 0) + { + return { + url: url, + type: '' + }; + } + + var audioType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); + + audioType = GetFastValue(urls[i], 'type', (audioType) ? audioType[1] : '').toLowerCase(); + + if (game.device.audio[audioType]) + { + return { + url: url, + type: audioType + }; + } + } + + return null; +}; + +/** + * Adds an Audio or HTML5Audio file, or array of audio 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.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); + * } + * ``` + * + * 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 Audio Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Audio 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 Audio Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.audio({ + * key: 'title', + * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ] + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.AudioFileConfig` for more details. + * + * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. + * + * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats. + * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on + * browser support. + * + * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded. + * + * Note: The ability to load this type of file will only be available if the Audio 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#audio + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.AudioFileConfig|Phaser.Types.Loader.FileTypes.AudioFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {(string|string[])} [urls] - The absolute or relative URL to load the audio files from. + * @param {any} [config] - An object containing an `instances` property for HTML5Audio. Defaults to 1. + * @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('audio', function (key, urls, config, xhrSettings) +{ + var game = this.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + // Sounds are disabled, so skip loading audio + return this; + } + + var audioFile; + + 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 + audioFile = AudioFile.create(this, key[i]); + + if (audioFile) + { + this.addFile(audioFile); + } + } + } + else + { + audioFile = AudioFile.create(this, key, urls, config, xhrSettings); + + if (audioFile) + { + this.addFile(audioFile); + } + } + + return this; +}); + +module.exports = AudioFile; + + +/***/ }), +/* 513 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Events = __webpack_require__(91); +var File = __webpack_require__(23); +var GetFastValue = __webpack_require__(2); +var GetURL = __webpack_require__(153); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Audio File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. + * + * @class HTML5AudioFile + * @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.AudioFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string} [urlConfig] - The absolute or relative URL to load this file from. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var HTML5AudioFile = new Class({ + + Extends: File, + + initialize: + + function HTML5AudioFile (loader, key, urlConfig, audioConfig) + { + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + audioConfig = GetFastValue(config, 'config', audioConfig); + } + + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: urlConfig.type, + key: key, + url: urlConfig.url, + config: audioConfig + }; + + File.call(this, loader, fileConfig); + + // New properties specific to this class + this.locked = 'ontouchstart' in window; + this.loaded = false; + this.filesLoaded = 0; + this.filesTotal = 0; + }, + + /** + * Called when the file finishes loading. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad + * @since 3.0.0 + */ + onLoad: function () + { + if (this.loaded) + { + return; + } + + this.loaded = true; + + this.loader.nextFile(this, true); + }, + + /** + * Called if the file errors while loading. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onError + * @since 3.0.0 + */ + onError: function () + { + for (var i = 0; i < this.data.length; i++) + { + var audio = this.data[i]; + + audio.oncanplaythrough = null; + audio.onerror = null; + } + + this.loader.nextFile(this, false); + }, + + /** + * Called during the file load progress. Is sent a DOM ProgressEvent. + * + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress + * @fires Phaser.Loader.Events#FILE_PROGRESS + * @since 3.0.0 + */ + onProgress: function (event) + { + var audio = event.target; + + audio.oncanplaythrough = null; + audio.onerror = null; + + this.filesLoaded++; + + this.percentComplete = Math.min((this.filesLoaded / this.filesTotal), 1); + + this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); + + if (this.filesLoaded === this.filesTotal) + { + this.onLoad(); + } + }, + + /** + * 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.FileTypes.HTML5AudioFile#load + * @since 3.0.0 + */ + load: function () + { + this.data = []; + + var instances = (this.config && this.config.instances) || 1; + + this.filesTotal = instances; + this.filesLoaded = 0; + this.percentComplete = 0; + + for (var i = 0; i < instances; i++) + { + var audio = new Audio(); + + if (!audio.dataset) + { + audio.dataset = {}; + } + + audio.dataset.name = this.key + ('0' + i).slice(-2); + audio.dataset.used = 'false'; + + if (this.locked) + { + audio.dataset.locked = 'true'; + } + else + { + audio.dataset.locked = 'false'; + + audio.preload = 'auto'; + audio.oncanplaythrough = this.onProgress.bind(this); + audio.onerror = this.onError.bind(this); + } + + this.data.push(audio); + } + + for (i = 0; i < this.data.length; i++) + { + audio = this.data[i]; + audio.src = GetURL(this, this.loader.baseURL); + + if (!this.locked) + { + audio.load(); + } + } + + if (this.locked) + { + // This is super-dangerous but works. Race condition potential high. + // Is there another way? + setTimeout(this.onLoad.bind(this)); + } + } + +}); + +module.exports = HTML5AudioFile; + + +/***/ }), +/* 514 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(20); +var File = __webpack_require__(23); +var FileTypesManager = __webpack_require__(8); +var GetFastValue = __webpack_require__(2); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * A single Script File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#script method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#script. + * + * @class ScriptFile + * @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.ScriptFileConfig)} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var ScriptFile = new Class({ + + Extends: File, + + initialize: + + function ScriptFile (loader, key, url, xhrSettings) + { + var extension = 'js'; + + 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: 'script', + cache: false, + 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.ScriptFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = document.createElement('script'); + this.data.language = 'javascript'; + this.data.type = 'text/javascript'; + this.data.defer = false; + this.data.text = this.xhrLoader.responseText; + + document.head.appendChild(this.data); + + this.onProcessComplete(); + } + +}); + +/** + * Adds a Script file, or array of Script 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.script('aliens', 'lib/aliens.js'); + * } + * ``` + * + * 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 and not already in-use by another file in the Loader. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.script({ + * key: 'aliens', + * url: 'lib/aliens.js' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.ScriptFileConfig` for more details. + * + * Once the file has finished loading it will automatically be converted into a script element + * via `document.createElement('script')`. It will have its language set to JavaScript, `defer` set to + * false and then the resulting element will be appended to `document.head`. Any code then in the + * script will be executed. + * + * 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.js". It will always add `.js` 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 Script 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#script + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.ScriptFileConfig|Phaser.Types.Loader.FileTypes.ScriptFileConfig[])} 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 `.js`, i.e. if `key` was "alien" then the URL will be "alien.js". + * @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('script', 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 ScriptFile(this, key[i])); + } + } + else + { + this.addFile(new ScriptFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = ScriptFile; + + +/***/ }), +/* 515 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeImage = __webpack_require__(516); +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var PhysicsGroup = __webpack_require__(518); +var StaticPhysicsGroup = __webpack_require__(519); + +/** + * @classdesc + * The Arcade Physics Factory allows you to easily create Arcade Physics enabled Game Objects. + * Objects that are created by this Factory are automatically added to the physics world. + * + * @class Factory + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics World instance. + */ +var Factory = new Class({ + + initialize: + + function Factory (world) + { + /** + * A reference to the Arcade Physics World. + * + * @name Phaser.Physics.Arcade.Factory#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * A reference to the Scene this Arcade Physics instance belongs to. + * + * @name Phaser.Physics.Arcade.Factory#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = world.scene; + + /** + * A reference to the Scene.Systems this Arcade Physics instance belongs to. + * + * @name Phaser.Physics.Arcade.Factory#sys + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.sys = world.scene.sys; + }, + + /** + * Creates a new Arcade Physics Collider object. + * + * @method Phaser.Physics.Arcade.Factory#collider + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for collision. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + collider: function (object1, object2, collideCallback, processCallback, callbackContext) + { + return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext); + }, + + /** + * Creates a new Arcade Physics Collider Overlap object. + * + * @method Phaser.Physics.Arcade.Factory#overlap + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object1 - The first object to check for overlap. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object2 - The second object to check for overlap. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + overlap: function (object1, object2, collideCallback, processCallback, callbackContext) + { + return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext); + }, + + /** + * Adds an Arcade Physics Body to the given Game Object. + * + * @method Phaser.Physics.Arcade.Factory#existing + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - A Game Object. + * @param {boolean} [isStatic=false] - Create a Static body (true) or Dynamic body (false). + * + * @return {Phaser.Types.Physics.Arcade.GameObjectWithBody} The Game Object. + */ + existing: function (gameObject, isStatic) + { + var type = (isStatic) ? CONST.STATIC_BODY : CONST.DYNAMIC_BODY; + + this.world.enableBody(gameObject, type); + + return gameObject; + }, + + /** + * Creates a new Arcade Image object with a Static body. + * + * @method Phaser.Physics.Arcade.Factory#staticImage + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.ImageWithStaticBody} The Image object that was created. + */ + staticImage: function (x, y, key, frame) + { + var image = new ArcadeImage(this.scene, x, y, key, frame); + + this.sys.displayList.add(image); + + this.world.enableBody(image, CONST.STATIC_BODY); + + return image; + }, + + /** + * Creates a new Arcade Image object with a Dynamic body. + * + * @method Phaser.Physics.Arcade.Factory#image + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.ImageWithDynamicBody} The Image object that was created. + */ + image: function (x, y, key, frame) + { + var image = new ArcadeImage(this.scene, x, y, key, frame); + + this.sys.displayList.add(image); + + this.world.enableBody(image, CONST.DYNAMIC_BODY); + + return image; + }, + + /** + * Creates a new Arcade Sprite object with a Static body. + * + * @method Phaser.Physics.Arcade.Factory#staticSprite + * @since 3.0.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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created. + */ + staticSprite: function (x, y, key, frame) + { + var sprite = new ArcadeSprite(this.scene, x, y, key, frame); + + this.sys.displayList.add(sprite); + this.sys.updateList.add(sprite); + + this.world.enableBody(sprite, CONST.STATIC_BODY); + + return sprite; + }, + + /** + * Creates a new Arcade Sprite object with a Dynamic body. + * + * @method Phaser.Physics.Arcade.Factory#sprite + * @since 3.0.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 Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Types.Physics.Arcade.SpriteWithDynamicBody} The Sprite object that was created. + */ + sprite: function (x, y, key, frame) + { + var sprite = new ArcadeSprite(this.scene, x, y, key, frame); + + this.sys.displayList.add(sprite); + this.sys.updateList.add(sprite); + + this.world.enableBody(sprite, CONST.DYNAMIC_BODY); + + return sprite; + }, + + /** + * Creates a Static Physics Group object. + * All Game Objects created by this Group will automatically be static Arcade Physics objects. + * + * @method Phaser.Physics.Arcade.Factory#staticGroup + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + * + * @return {Phaser.Physics.Arcade.StaticGroup} The Static Group object that was created. + */ + staticGroup: function (children, config) + { + return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config)); + }, + + /** + * Creates a Physics Group object. + * All Game Objects created by this Group will automatically be dynamic Arcade Physics objects. + * + * @method Phaser.Physics.Arcade.Factory#group + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + * + * @return {Phaser.Physics.Arcade.Group} The Group object that was created. + */ + group: function (children, config) + { + return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config)); + }, + + /** + * Destroys this Factory. + * + * @method Phaser.Physics.Arcade.Factory#destroy + * @since 3.5.0 + */ + destroy: function () + { + this.world = null; + this.scene = null; + this.sys = null; + } + +}); + +module.exports = Factory; + + +/***/ }), +/* 516 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(240); +var Image = __webpack_require__(124); + +/** + * @classdesc + * An Arcade Physics Image is an Image with an Arcade Physics body and related components. + * The body can be dynamic or static. + * + * The main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image. + * + * @class Image + * @extends Phaser.GameObjects.Image + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @extends Phaser.Physics.Arcade.Components.Acceleration + * @extends Phaser.Physics.Arcade.Components.Angular + * @extends Phaser.Physics.Arcade.Components.Bounce + * @extends Phaser.Physics.Arcade.Components.Debug + * @extends Phaser.Physics.Arcade.Components.Drag + * @extends Phaser.Physics.Arcade.Components.Enable + * @extends Phaser.Physics.Arcade.Components.Friction + * @extends Phaser.Physics.Arcade.Components.Gravity + * @extends Phaser.Physics.Arcade.Components.Immovable + * @extends Phaser.Physics.Arcade.Components.Mass + * @extends Phaser.Physics.Arcade.Components.Pushable + * @extends Phaser.Physics.Arcade.Components.Size + * @extends Phaser.Physics.Arcade.Components.Velocity + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Tint + * @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 - 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|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + */ +var ArcadeImage = new Class({ + + Extends: Image, + + Mixins: [ + Components.Acceleration, + Components.Angular, + Components.Bounce, + Components.Debug, + Components.Drag, + Components.Enable, + Components.Friction, + Components.Gravity, + Components.Immovable, + Components.Mass, + Components.Pushable, + Components.Size, + Components.Velocity + ], + + initialize: + + function ArcadeImage (scene, x, y, texture, frame) + { + Image.call(this, scene, x, y, texture, frame); + + /** + * This Game Object's Physics Body. + * + * @name Phaser.Physics.Arcade.Image#body + * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} + * @default null + * @since 3.0.0 + */ + this.body = null; + } + +}); + +module.exports = ArcadeImage; + + +/***/ }), +/* 517 */ +/***/ (function(module, exports, __webpack_require__) { + +var OverlapRect = __webpack_require__(241); +var Circle = __webpack_require__(62); +var CircleToCircle = __webpack_require__(228); +var CircleToRectangle = __webpack_require__(150); + +/** + * This method will search the given circular area and return an array of all physics bodies that + * overlap with it. It can return either Dynamic, Static bodies or a mixture of both. + * + * A body only has to intersect with the search area to be considered, it doesn't have to be fully + * contained within it. + * + * If Arcade Physics is set to use the RTree (which it is by default) then the search is rather fast, + * otherwise the search is O(N) for Dynamic Bodies. + * + * @function Phaser.Physics.Arcade.Components.OverlapCirc + * @since 3.21.0 + * + * @param {number} x - The x coordinate of the center of the area to search within. + * @param {number} y - The y coordinate of the center of the area to search within. + * @param {number} radius - The radius of the area to search within. + * @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies? + * @param {boolean} [includeStatic=false] - Should the search include Static Bodies? + * + * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. + */ +var OverlapCirc = function (world, x, y, radius, includeDynamic, includeStatic) +{ + var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); + + if (bodiesInRect.length === 0) + { + return bodiesInRect; + } + + var area = new Circle(x, y, radius); + var circFromBody = new Circle(); + var bodiesInArea = []; + + for (var i = 0; i < bodiesInRect.length; i++) + { + var body = bodiesInRect[i]; + + if (body.isCircle) + { + circFromBody.setTo(body.center.x, body.center.y, body.halfWidth); + + if (CircleToCircle(area, circFromBody)) + { + bodiesInArea.push(body); + } + } + else if (CircleToRectangle(area, body)) + { + bodiesInArea.push(body); + } + } + + return bodiesInArea; +}; + +module.exports = OverlapCirc; + + +/***/ }), +/* 518 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var GetFastValue = __webpack_require__(2); +var Group = __webpack_require__(110); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * An Arcade Physics Group object. + * + * The primary use of a Physics Group is a way to collect together physics enable objects + * that share the same intrinsic structure into a single pool. They can they be easily + * compared against other Groups, or Game Objects. + * + * All Game Objects created by, or added to this Group will automatically be given **dynamic** + * Arcade Physics bodies (if they have no body already) and the bodies will receive the + * Groups {@link Phaser.Physics.Arcade.Group#defaults default values}. + * + * You should not pass objects into this Group that should not receive a body. For example, + * do not add basic Geometry or Tilemap Layers into a Group, as they will not behave in the + * way you may expect. Groups should all ideally have objects of the same type in them. + * + * If you wish to create a Group filled with Static Bodies, please see {@link Phaser.Physics.Arcade.StaticGroup}. + * + * @class Group + * @extends Phaser.GameObjects.Group + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The physics simulation. + * @param {Phaser.Scene} scene - The scene this group belongs to. + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + */ +var PhysicsGroup = new Class({ + + Extends: Group, + + initialize: + + function PhysicsGroup (world, scene, children, config) + { + if (!children && !config) + { + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + else if (IsPlainObject(children)) + { + // children is a plain object, so swizzle them: + config = children; + children = null; + + config.internalCreateCallback = this.createCallbackHandler; + config.internalRemoveCallback = this.removeCallbackHandler; + } + else if (Array.isArray(children) && IsPlainObject(children[0])) + { + // children is an array of plain objects (i.e., configs) + config = children[0]; + + var _this = this; + + children.forEach(function (singleConfig) + { + singleConfig.internalCreateCallback = _this.createCallbackHandler; + singleConfig.internalRemoveCallback = _this.removeCallbackHandler; + }); + + children = null; + } + else + { + // config is not defined and children is not a plain object nor an array of plain objects + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + + /** + * The physics simulation. + * + * @name Phaser.Physics.Arcade.Group#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The class to create new Group members from. + * + * This should be either `Phaser.Physics.Arcade.Image`, `Phaser.Physics.Arcade.Sprite`, or a class extending one of those. + * + * @name Phaser.Physics.Arcade.Group#classType + * @type {Function} + * @default ArcadeSprite + * @since 3.0.0 + */ + config.classType = GetFastValue(config, 'classType', ArcadeSprite); + + /** + * The physics type of the Group's members. + * + * @name Phaser.Physics.Arcade.Group#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.DYNAMIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.DYNAMIC_BODY; + + /** + * Default physics properties applied to Game Objects added to the Group or created by the Group. Derived from the `config` argument. + * + * You can remove the default values by setting this property to `{}`. + * + * @name Phaser.Physics.Arcade.Group#defaults + * @type {Phaser.Types.Physics.Arcade.PhysicsGroupDefaults} + * @since 3.0.0 + */ + this.defaults = { + setCollideWorldBounds: GetFastValue(config, 'collideWorldBounds', false), + setBoundsRectangle: GetFastValue(config, 'customBoundsRectangle', null), + setAccelerationX: GetFastValue(config, 'accelerationX', 0), + setAccelerationY: GetFastValue(config, 'accelerationY', 0), + setAllowDrag: GetFastValue(config, 'allowDrag', true), + setAllowGravity: GetFastValue(config, 'allowGravity', true), + setAllowRotation: GetFastValue(config, 'allowRotation', true), + setBounceX: GetFastValue(config, 'bounceX', 0), + setBounceY: GetFastValue(config, 'bounceY', 0), + setDragX: GetFastValue(config, 'dragX', 0), + setDragY: GetFastValue(config, 'dragY', 0), + setEnable: GetFastValue(config, 'enable', true), + setGravityX: GetFastValue(config, 'gravityX', 0), + setGravityY: GetFastValue(config, 'gravityY', 0), + setFrictionX: GetFastValue(config, 'frictionX', 0), + setFrictionY: GetFastValue(config, 'frictionY', 0), + setMaxVelocityX: GetFastValue(config, 'maxVelocityX', 10000), + setMaxVelocityY: GetFastValue(config, 'maxVelocityY', 10000), + setVelocityX: GetFastValue(config, 'velocityX', 0), + setVelocityY: GetFastValue(config, 'velocityY', 0), + setAngularVelocity: GetFastValue(config, 'angularVelocity', 0), + setAngularAcceleration: GetFastValue(config, 'angularAcceleration', 0), + setAngularDrag: GetFastValue(config, 'angularDrag', 0), + setMass: GetFastValue(config, 'mass', 1), + setImmovable: GetFastValue(config, 'immovable', false) + }; + + Group.call(this, scene, children, config); + + /** + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.Physics.Arcade.Group#type + * @type {string} + * @default 'PhysicsGroup' + * @since 3.21.0 + */ + this.type = 'PhysicsGroup'; + }, + + /** + * Enables a Game Object's Body and assigns `defaults`. Called when a Group member is added or created. + * + * @method Phaser.Physics.Arcade.Group#createCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object being added. + */ + createCallbackHandler: function (child) + { + if (!child.body) + { + this.world.enableBody(child, CONST.DYNAMIC_BODY); + } + + var body = child.body; + + for (var key in this.defaults) + { + body[key](this.defaults[key]); + } + }, + + /** + * Disables a Game Object's Body. Called when a Group member is removed. + * + * @method Phaser.Physics.Arcade.Group#removeCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object being removed. + */ + removeCallbackHandler: function (child) + { + if (child.body) + { + this.world.disableBody(child); + } + }, + + /** + * Sets the velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocity + * @since 3.0.0 + * + * @param {number} x - The horizontal velocity. + * @param {number} y - The vertical velocity. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x, y), the second (x + step, y + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocity: function (x, y, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.set(x + (i * step), y + (i * step)); + } + + return this; + }, + + /** + * Sets the horizontal velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocityX + * @since 3.0.0 + * + * @param {number} value - The velocity value. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x), the second (x + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocityX: function (value, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.x = value + (i * step); + } + + return this; + }, + + /** + * Sets the vertical velocity of each Group member. + * + * @method Phaser.Physics.Arcade.Group#setVelocityY + * @since 3.0.0 + * + * @param {number} value - The velocity value. + * @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (y), the second (y + step), and so on. + * + * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + */ + setVelocityY: function (value, step) + { + if (step === undefined) { step = 0; } + + var items = this.getChildren(); + + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.y = value + (i * step); + } + + return this; + } + +}); + +module.exports = PhysicsGroup; + + +/***/ }), +/* 519 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeSprite = __webpack_require__(155); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var GetFastValue = __webpack_require__(2); +var Group = __webpack_require__(110); +var IsPlainObject = __webpack_require__(7); + +/** + * @classdesc + * An Arcade Physics Static Group object. + * + * All Game Objects created by or added to this Group will automatically be given static Arcade Physics bodies, if they have no body. + * + * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Group}. + * + * @class StaticGroup + * @extends Phaser.GameObjects.Group + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The physics simulation. + * @param {Phaser.Scene} scene - The scene this group belongs to. + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument. + * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group. + */ +var StaticPhysicsGroup = new Class({ + + Extends: Group, + + initialize: + + function StaticPhysicsGroup (world, scene, children, config) + { + if (!children && !config) + { + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler, + createMultipleCallback: this.createMultipleCallbackHandler, + classType: ArcadeSprite + }; + } + else if (IsPlainObject(children)) + { + // children is a plain object, so swizzle them: + config = children; + children = null; + + config.internalCreateCallback = this.createCallbackHandler; + config.internalRemoveCallback = this.removeCallbackHandler; + config.createMultipleCallback = this.createMultipleCallbackHandler; + config.classType = GetFastValue(config, 'classType', ArcadeSprite); + } + else if (Array.isArray(children) && IsPlainObject(children[0])) + { + // children is an array of plain objects + config = children; + children = null; + + config.forEach(function (singleConfig) + { + singleConfig.internalCreateCallback = this.createCallbackHandler; + singleConfig.internalRemoveCallback = this.removeCallbackHandler; + singleConfig.createMultipleCallback = this.createMultipleCallbackHandler; + singleConfig.classType = GetFastValue(singleConfig, 'classType', ArcadeSprite); + }); + } + else + { + // config is not defined and children is not a plain object nor an array of plain objects + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; + } + + /** + * The physics simulation. + * + * @name Phaser.Physics.Arcade.StaticGroup#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The scene this group belongs to. + * + * @name Phaser.Physics.Arcade.StaticGroup#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.STATIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.STATIC_BODY; + + Group.call(this, scene, children, config); + + /** + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.Physics.Arcade.StaticGroup#type + * @type {string} + * @default 'StaticPhysicsGroup' + * @since 3.21.0 + */ + this.type = 'StaticPhysicsGroup'; + }, + + /** + * Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation. + * + * @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The new group member. + * + * @see Phaser.Physics.Arcade.World#enableBody + */ + createCallbackHandler: function (child) + { + if (!child.body) + { + this.world.enableBody(child, CONST.STATIC_BODY); + } + }, + + /** + * Disables the group member's physics body, removing it from the simulation. + * + * @method Phaser.Physics.Arcade.StaticGroup#removeCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The group member being removed. + * + * @see Phaser.Physics.Arcade.World#disableBody + */ + removeCallbackHandler: function (child) + { + if (child.body) + { + this.world.disableBody(child); + } + }, + + /** + * Refreshes the group. + * + * @method Phaser.Physics.Arcade.StaticGroup#createMultipleCallbackHandler + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject[]} entries - The newly created group members. + * + * @see Phaser.Physics.Arcade.StaticGroup#refresh + */ + createMultipleCallbackHandler: function () + { + this.refresh(); + }, + + /** + * Resets each Body to the position of its parent Game Object. + * Body sizes aren't changed (use {@link Phaser.Physics.Arcade.Components.Enable#refreshBody} for that). + * + * @method Phaser.Physics.Arcade.StaticGroup#refresh + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.StaticGroup} This group. + * + * @see Phaser.Physics.Arcade.StaticBody#reset + */ + refresh: function () + { + var children = this.children.entries; + + for (var i = 0; i < children.length; i++) + { + children[i].body.reset(); + } + + return this; + } + +}); + +module.exports = StaticPhysicsGroup; + + +/***/ }), +/* 520 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AngleBetweenPoints = __webpack_require__(344); +var Body = __webpack_require__(521); +var Clamp = __webpack_require__(18); +var Class = __webpack_require__(0); +var Collider = __webpack_require__(522); +var CONST = __webpack_require__(60); +var DistanceBetween = __webpack_require__(48); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(242); +var FuzzyEqual = __webpack_require__(123); +var FuzzyGreaterThan = __webpack_require__(348); +var FuzzyLessThan = __webpack_require__(349); +var GetOverlapX = __webpack_require__(243); +var GetOverlapY = __webpack_require__(244); +var GetTilesWithinWorldXY = __webpack_require__(523); +var GetValue = __webpack_require__(6); +var MATH_CONST = __webpack_require__(14); +var ProcessQueue = __webpack_require__(208); +var ProcessTileCallbacks = __webpack_require__(524); +var Rectangle = __webpack_require__(10); +var RTree = __webpack_require__(525); +var SeparateTile = __webpack_require__(526); +var SeparateX = __webpack_require__(531); +var SeparateY = __webpack_require__(532); +var Set = __webpack_require__(148); +var StaticBody = __webpack_require__(533); +var TileIntersectsBody = __webpack_require__(245); +var TransformMatrix = __webpack_require__(25); +var Vector2 = __webpack_require__(3); +var Wrap = __webpack_require__(66); + +/** + * @classdesc + * The Arcade Physics World. + * + * The World is responsible for creating, managing, colliding and updating all of the bodies within it. + * + * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. + * + * @class World + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this World instance belongs. + * @param {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} config - An Arcade Physics Configuration object. + */ +var World = new Class({ + + Extends: EventEmitter, + + initialize: + + function World (scene, config) + { + EventEmitter.call(this); + + /** + * The Scene this simulation belongs to. + * + * @name Phaser.Physics.Arcade.World#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; + + /** + * Dynamic Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#bodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.bodies = new Set(); + + /** + * Static Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#staticBodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.staticBodies = new Set(); + + /** + * Static Bodies marked for deletion. + * + * @name Phaser.Physics.Arcade.World#pendingDestroy + * @type {Phaser.Structs.Set.<(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)>} + * @since 3.1.0 + */ + this.pendingDestroy = new Set(); + + /** + * This simulation's collision processors. + * + * @name Phaser.Physics.Arcade.World#colliders + * @type {Phaser.Structs.ProcessQueue.} + * @since 3.0.0 + */ + this.colliders = new ProcessQueue(); + + /** + * Acceleration of Bodies due to gravity, in pixels per second. + * + * @name Phaser.Physics.Arcade.World#gravity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.gravity = new Vector2(GetValue(config, 'gravity.x', 0), GetValue(config, 'gravity.y', 0)); + + /** + * A boundary constraining Bodies. + * + * @name Phaser.Physics.Arcade.World#bounds + * @type {Phaser.Geom.Rectangle} + * @since 3.0.0 + */ + this.bounds = new Rectangle( + GetValue(config, 'x', 0), + GetValue(config, 'y', 0), + GetValue(config, 'width', scene.sys.scale.width), + GetValue(config, 'height', scene.sys.scale.height) + ); + + /** + * The boundary edges that Bodies can collide with. + * + * @name Phaser.Physics.Arcade.World#checkCollision + * @type {Phaser.Types.Physics.Arcade.CheckCollisionObject} + * @since 3.0.0 + */ + this.checkCollision = { + up: GetValue(config, 'checkCollision.up', true), + down: GetValue(config, 'checkCollision.down', true), + left: GetValue(config, 'checkCollision.left', true), + right: GetValue(config, 'checkCollision.right', true) + }; + + /** + * The number of physics steps to be taken per second. + * + * This property is read-only. Use the `setFPS` method to modify it at run-time. + * + * @name Phaser.Physics.Arcade.World#fps + * @readonly + * @type {number} + * @default 60 + * @since 3.10.0 + */ + this.fps = GetValue(config, 'fps', 60); + + /** + * Should Physics use a fixed update time-step (true) or sync to the render fps (false)?. + * False value of this property disables fps and timeScale properties. + * + * @name Phaser.Physics.Arcade.World#fixedStep + * @type {boolean} + * @default true + * @since 3.23.0 + */ + this.fixedStep = GetValue(config, 'fixedStep', true); + + /** + * The amount of elapsed ms since the last frame. + * + * @name Phaser.Physics.Arcade.World#_elapsed + * @private + * @type {number} + * @since 3.10.0 + */ + this._elapsed = 0; + + /** + * Internal frame time value. + * + * @name Phaser.Physics.Arcade.World#_frameTime + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTime = 1 / this.fps; + + /** + * Internal frame time ms value. + * + * @name Phaser.Physics.Arcade.World#_frameTimeMS + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTimeMS = 1000 * this._frameTime; + + /** + * The number of steps that took place in the last frame. + * + * @name Phaser.Physics.Arcade.World#stepsLastFrame + * @readonly + * @type {number} + * @since 3.10.0 + */ + this.stepsLastFrame = 0; + + /** + * Scaling factor applied to the frame rate. + * + * - 1.0 = normal speed + * - 2.0 = half speed + * - 0.5 = double speed + * + * @name Phaser.Physics.Arcade.World#timeScale + * @type {number} + * @default 1 + * @since 3.10.0 + */ + this.timeScale = GetValue(config, 'timeScale', 1); + + /** + * The maximum absolute difference of a Body's per-step velocity and its overlap with another Body that will result in separation on *each axis*. + * Larger values favor separation. + * Smaller values favor no separation. + * + * @name Phaser.Physics.Arcade.World#OVERLAP_BIAS + * @type {number} + * @default 4 + * @since 3.0.0 + */ + this.OVERLAP_BIAS = GetValue(config, 'overlapBias', 4); + + /** + * The maximum absolute value of a Body's overlap with a tile that will result in separation on *each axis*. + * Larger values favor separation. + * Smaller values favor no separation. + * The optimum value may be similar to the tile size. + * + * @name Phaser.Physics.Arcade.World#TILE_BIAS + * @type {number} + * @default 16 + * @since 3.0.0 + */ + this.TILE_BIAS = GetValue(config, 'tileBias', 16); + + /** + * Always separate overlapping Bodies horizontally before vertically. + * False (the default) means Bodies are first separated on the axis of greater gravity, or the vertical axis if neither is greater. + * + * @name Phaser.Physics.Arcade.World#forceX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.forceX = GetValue(config, 'forceX', false); + + /** + * Whether the simulation advances with the game loop. + * + * @name Phaser.Physics.Arcade.World#isPaused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isPaused = GetValue(config, 'isPaused', false); + + /** + * Temporary total of colliding Bodies. + * + * @name Phaser.Physics.Arcade.World#_total + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._total = 0; + + /** + * Enables the debug display. + * + * @name Phaser.Physics.Arcade.World#drawDebug + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.drawDebug = GetValue(config, 'debug', false); + + /** + * The graphics object drawing the debug display. + * + * @name Phaser.Physics.Arcade.World#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.0.0 + */ + this.debugGraphic; + + /** + * Default debug display settings for new Bodies. + * + * @name Phaser.Physics.Arcade.World#defaults + * @type {Phaser.Types.Physics.Arcade.ArcadeWorldDefaults} + * @since 3.0.0 + */ + this.defaults = { + debugShowBody: GetValue(config, 'debugShowBody', true), + debugShowStaticBody: GetValue(config, 'debugShowStaticBody', true), + debugShowVelocity: GetValue(config, 'debugShowVelocity', true), + bodyDebugColor: GetValue(config, 'debugBodyColor', 0xff00ff), + staticBodyDebugColor: GetValue(config, 'debugStaticBodyColor', 0x0000ff), + velocityDebugColor: GetValue(config, 'debugVelocityColor', 0x00ff00) + }; + + /** + * The maximum number of items per node on the RTree. + * + * This is ignored if `useTree` is `false`. If you have a large number of bodies in + * your world then you may find search performance improves by increasing this value, + * to allow more items per node and less node division. + * + * @name Phaser.Physics.Arcade.World#maxEntries + * @type {number} + * @default 16 + * @since 3.0.0 + */ + this.maxEntries = GetValue(config, 'maxEntries', 16); + + /** + * Should this Arcade Physics World use an RTree for Dynamic bodies? + * + * An RTree is a fast way of spatially sorting of all the bodies in the world. + * However, at certain limits, the cost of clearing and inserting the bodies into the + * tree every frame becomes more expensive than the search speed gains it provides. + * + * If you have a large number of dynamic bodies in your world then it may be best to + * disable the use of the RTree by setting this property to `false` in the physics config. + * + * The number it can cope with depends on browser and device, but a conservative estimate + * of around 5,000 bodies should be considered the max before disabling it. + * + * This only applies to dynamic bodies. Static bodies are always kept in an RTree, + * because they don't have to be cleared every frame, so you benefit from the + * massive search speeds all the time. + * + * @name Phaser.Physics.Arcade.World#useTree + * @type {boolean} + * @default true + * @since 3.10.0 + */ + this.useTree = GetValue(config, 'useTree', true); + + /** + * The spatial index of Dynamic Bodies. + * + * @name Phaser.Physics.Arcade.World#tree + * @type {Phaser.Structs.RTree} + * @since 3.0.0 + */ + this.tree = new RTree(this.maxEntries); + + /** + * The spatial index of Static Bodies. + * + * @name Phaser.Physics.Arcade.World#staticTree + * @type {Phaser.Structs.RTree} + * @since 3.0.0 + */ + this.staticTree = new RTree(this.maxEntries); + + /** + * Recycled input for tree searches. + * + * @name Phaser.Physics.Arcade.World#treeMinMax + * @type {Phaser.Types.Physics.Arcade.ArcadeWorldTreeMinMax} + * @since 3.0.0 + */ + this.treeMinMax = { minX: 0, minY: 0, maxX: 0, maxY: 0 }; + + /** + * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. + * + * @name Phaser.Physics.Arcade.World#_tempMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix = new TransformMatrix(); + + /** + * A temporary Transform Matrix used by bodies for calculations without them needing their own local copy. + * + * @name Phaser.Physics.Arcade.World#_tempMatrix2 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.12.0 + */ + this._tempMatrix2 = new TransformMatrix(); + + if (this.drawDebug) + { + this.createDebugGraphic(); + } + }, + + /** + * Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group. + * + * The difference between this and the `enableBody` method is that you can pass arrays or Groups + * to this method. + * + * You can specify if the bodies are to be Dynamic or Static. A dynamic body can move via velocity and + * acceleration. A static body remains fixed in place and as such is able to use an optimized search + * tree, making it ideal for static elements such as level objects. You can still collide and overlap + * with static bodies. + * + * Normally, rather than calling this method directly, you'd use the helper methods available in the + * Arcade Physics Factory, such as: + * + * ```javascript + * this.physics.add.image(x, y, textureKey); + * this.physics.add.sprite(x, y, textureKey); + * ``` + * + * Calling factory methods encapsulates the creation of a Game Object and the creation of its + * body at the same time. If you are creating custom classes then you can pass them to this + * method to have their bodies created. + * + * @method Phaser.Physics.Arcade.World#enable + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to create the bodies. + * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. + */ + enable: function (object, bodyType) + { + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } + + if (!Array.isArray(object)) + { + object = [ object ]; + } + + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; + + if (entry.isParent) + { + var children = entry.getChildren(); + + for (var c = 0; c < children.length; c++) + { + var child = children[c]; + + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.enable(child, bodyType); + } + else + { + this.enableBody(child, bodyType); + } + } + } + else + { + this.enableBody(entry, bodyType); + } + } + }, + + /** + * Creates an Arcade Physics Body on a single Game Object. + * + * If the Game Object already has a body, this method will simply add it back into the simulation. + * + * You can specify if the body is Dynamic or Static. A dynamic body can move via velocity and + * acceleration. A static body remains fixed in place and as such is able to use an optimized search + * tree, making it ideal for static elements such as level objects. You can still collide and overlap + * with static bodies. + * + * Normally, rather than calling this method directly, you'd use the helper methods available in the + * Arcade Physics Factory, such as: + * + * ```javascript + * this.physics.add.image(x, y, textureKey); + * this.physics.add.sprite(x, y, textureKey); + * ``` + * + * Calling factory methods encapsulates the creation of a Game Object and the creation of its + * body at the same time. If you are creating custom classes then you can pass them to this + * method to have their bodies created. + * + * @method Phaser.Physics.Arcade.World#enableBody + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} object - The Game Object on which to create the body. + * @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`. + * + * @return {Phaser.GameObjects.GameObject} The Game Object on which the body was created. + */ + enableBody: function (object, bodyType) + { + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } + + if (!object.body) + { + if (bodyType === CONST.DYNAMIC_BODY) + { + object.body = new Body(this, object); + } + else if (bodyType === CONST.STATIC_BODY) + { + object.body = new StaticBody(this, object); + } + } + + this.add(object.body); + + return object; + }, + + /** + * Adds an existing Arcade Physics Body or StaticBody to the simulation. + * + * The body is enabled and added to the local search trees. + * + * @method Phaser.Physics.Arcade.World#add + * @since 3.10.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be added to the simulation. + * + * @return {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} The Body that was added to the simulation. + */ + add: function (body) + { + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.bodies.set(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.set(body); + + this.staticTree.insert(body); + } + + body.enable = true; + + return body; + }, + + /** + * Disables the Arcade Physics Body of a Game Object, an array of Game Objects, or the children of a Group. + * + * The difference between this and the `disableBody` method is that you can pass arrays or Groups + * to this method. + * + * The body itself is not deleted, it just has its `enable` property set to false, which + * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. + * + * @method Phaser.Physics.Arcade.World#disable + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to disable the bodies. + */ + disable: function (object) + { + if (!Array.isArray(object)) + { + object = [ object ]; + } + + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; + + if (entry.isParent) + { + var children = entry.getChildren(); + + for (var c = 0; c < children.length; c++) + { + var child = children[c]; + + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.disable(child); + } + else + { + this.disableBody(child.body); + } + } + } + else + { + this.disableBody(entry.body); + } + } + }, + + /** + * Disables an existing Arcade Physics Body or StaticBody and removes it from the simulation. + * + * The body is disabled and removed from the local search trees. + * + * The body itself is not deleted, it just has its `enable` property set to false, which + * means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`. + * + * @method Phaser.Physics.Arcade.World#disableBody + * @since 3.0.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be disabled. + */ + disableBody: function (body) + { + this.remove(body); + + body.enable = false; + }, + + /** + * Removes an existing Arcade Physics Body or StaticBody from the simulation. + * + * The body is disabled and removed from the local search trees. + * + * The body itself is not deleted, it just has its `enabled` property set to false, which + * means you can re-enable it again at any point by passing it to enable `enable` or `add`. + * + * @method Phaser.Physics.Arcade.World#remove + * @since 3.0.0 + * + * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation. + */ + remove: function (body) + { + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.tree.remove(body); + this.bodies.delete(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.delete(body); + this.staticTree.remove(body); + } + }, + + /** + * Creates a Graphics Game Object that the world will use to render the debug display to. + * + * This is called automatically when the World is instantiated if the `debug` config property + * was set to `true`. However, you can call it at any point should you need to display the + * debug Graphic from a fixed point. + * + * You can control which objects are drawn to the Graphics object, and the colors they use, + * by setting the debug properties in the physics config. + * + * You should not typically use this in a production game. Use it to aid during debugging. + * + * @method Phaser.Physics.Arcade.World#createDebugGraphic + * @since 3.0.0 + * + * @return {Phaser.GameObjects.Graphics} The Graphics object that was created for use by the World. + */ + createDebugGraphic: function () + { + var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); + + graphic.setDepth(Number.MAX_VALUE); + + this.debugGraphic = graphic; + + this.drawDebug = true; + + return graphic; + }, + + /** + * Sets the position, size and properties of the World boundary. + * + * The World boundary is an invisible rectangle that defines the edges of the World. + * If a Body is set to collide with the world bounds then it will automatically stop + * when it reaches any of the edges. You can optionally set which edges of the boundary + * should be checked against. + * + * @method Phaser.Physics.Arcade.World#setBounds + * @since 3.0.0 + * + * @param {number} x - The top-left x coordinate of the boundary. + * @param {number} y - The top-left y coordinate of the boundary. + * @param {number} width - The width of the boundary. + * @param {number} height - The height of the boundary. + * @param {boolean} [checkLeft] - Should bodies check against the left edge of the boundary? + * @param {boolean} [checkRight] - Should bodies check against the right edge of the boundary? + * @param {boolean} [checkUp] - Should bodies check against the top edge of the boundary? + * @param {boolean} [checkDown] - Should bodies check against the bottom edge of the boundary? + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + setBounds: function (x, y, width, height, checkLeft, checkRight, checkUp, checkDown) + { + this.bounds.setTo(x, y, width, height); + + if (checkLeft !== undefined) + { + this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); + } + + return this; + }, + + /** + * Enables or disables collisions on each edge of the World boundary. + * + * @method Phaser.Physics.Arcade.World#setBoundsCollision + * @since 3.0.0 + * + * @param {boolean} [left=true] - Should bodies check against the left edge of the boundary? + * @param {boolean} [right=true] - Should bodies check against the right edge of the boundary? + * @param {boolean} [up=true] - Should bodies check against the top edge of the boundary? + * @param {boolean} [down=true] - Should bodies check against the bottom edge of the boundary? + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + setBoundsCollision: function (left, right, up, down) + { + if (left === undefined) { left = true; } + if (right === undefined) { right = true; } + if (up === undefined) { up = true; } + if (down === undefined) { down = true; } + + this.checkCollision.left = left; + this.checkCollision.right = right; + this.checkCollision.up = up; + this.checkCollision.down = down; + + return this; + }, + + /** + * Pauses the simulation. + * + * A paused simulation does not update any existing bodies, or run any Colliders. + * + * However, you can still enable and disable bodies within it, or manually run collide or overlap + * checks. + * + * @method Phaser.Physics.Arcade.World#pause + * @fires Phaser.Physics.Arcade.Events#PAUSE + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + pause: function () + { + this.isPaused = true; + + this.emit(Events.PAUSE); + + return this; + }, + + /** + * Resumes the simulation, if paused. + * + * @method Phaser.Physics.Arcade.World#resume + * @fires Phaser.Physics.Arcade.Events#RESUME + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + resume: function () + { + this.isPaused = false; + + this.emit(Events.RESUME); + + return this; + }, + + /** + * Creates a new Collider object and adds it to the simulation. + * + * A Collider is a way to automatically perform collision checks between two objects, + * calling the collide and process callbacks if they occur. + * + * Colliders are run as part of the World update, after all of the Bodies have updated. + * + * By creating a Collider you don't need then call `World.collide` in your `update` loop, + * as it will be handled for you automatically. + * + * @method Phaser.Physics.Arcade.World#addCollider + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#collide + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + addCollider: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); + + this.colliders.add(collider); + + return collider; + }, + + /** + * Creates a new Overlap Collider object and adds it to the simulation. + * + * A Collider is a way to automatically perform overlap checks between two objects, + * calling the collide and process callbacks if they occur. + * + * Colliders are run as part of the World update, after all of the Bodies have updated. + * + * By creating a Collider you don't need then call `World.overlap` in your `update` loop, + * as it will be handled for you automatically. + * + * @method Phaser.Physics.Arcade.World#addOverlap + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap. + * @param {ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects overlap. Must return a boolean. + * @param {*} [callbackContext] - The scope in which to call the callbacks. + * + * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + */ + addOverlap: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); + + this.colliders.add(collider); + + return collider; + }, + + /** + * Removes a Collider from the simulation so it is no longer processed. + * + * This method does not destroy the Collider. If you wish to add it back at a later stage you can call + * `World.colliders.add(Collider)`. + * + * If you no longer need the Collider you can call the `Collider.destroy` method instead, which will + * automatically clear all of its references and then remove it from the World. If you call destroy on + * a Collider you _don't_ need to pass it to this method too. + * + * @method Phaser.Physics.Arcade.World#removeCollider + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Collider} collider - The Collider to remove from the simulation. + * + * @return {Phaser.Physics.Arcade.World} This World object. + */ + removeCollider: function (collider) + { + this.colliders.remove(collider); + + return this; + }, + + /** + * Sets the frame rate to run the simulation at. + * + * The frame rate value is used to simulate a fixed update time step. This fixed + * time step allows for a straightforward implementation of a deterministic game state. + * + * This frame rate is independent of the frequency at which the game is rendering. The + * higher you set the fps, the more physics simulation steps will occur per game step. + * Conversely, the lower you set it, the less will take place. + * + * You can optionally advance the simulation directly yourself by calling the `step` method. + * + * @method Phaser.Physics.Arcade.World#setFPS + * @since 3.10.0 + * + * @param {number} framerate - The frame rate to advance the simulation at. + * + * @return {this} This World object. + */ + setFPS: function (framerate) + { + this.fps = framerate; + this._frameTime = 1 / this.fps; + this._frameTimeMS = 1000 * this._frameTime; + + return this; + }, + + /** + * Advances the simulation based on the elapsed time and fps rate. + * + * This is called automatically by your Scene and does not need to be invoked directly. + * + * @method Phaser.Physics.Arcade.World#update + * @fires Phaser.Physics.Arcade.Events#WORLD_STEP + * @since 3.0.0 + * + * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + update: function (time, delta) + { + if (this.isPaused || this.bodies.size === 0) + { + return; + } + + var i; + var fixedDelta = this._frameTime; + var msPerFrame = this._frameTimeMS * this.timeScale; + + this._elapsed += delta; + + // Update all active bodies + var body; + var bodies = this.bodies.entries; + + // Will a step happen this frame? + var willStep = (this._elapsed >= msPerFrame); + + if (!this.fixedStep) + { + fixedDelta = delta * 0.001; + willStep = true; + this._elapsed = 0; + } + + for (i = 0; i < bodies.length; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.preUpdate(willStep, fixedDelta); + } + } + + // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs + if (willStep) + { + this._elapsed -= msPerFrame; + this.stepsLastFrame = 1; + + // Optionally populate our dynamic collision tree + if (this.useTree) + { + this.tree.clear(); + this.tree.load(bodies); + } + + // Process any colliders + var colliders = this.colliders.update(); + + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; + + if (collider.active) + { + collider.update(); + } + } + + this.emit(Events.WORLD_STEP, fixedDelta); + } + + // Process any additional steps this frame + while (this._elapsed >= msPerFrame) + { + this._elapsed -= msPerFrame; + + this.step(fixedDelta); + } + }, + + /** + * Advances the simulation by a time increment. + * + * @method Phaser.Physics.Arcade.World#step + * @fires Phaser.Physics.Arcade.Events#WORLD_STEP + * @since 3.10.0 + * + * @param {number} delta - The delta time amount, in seconds, by which to advance the simulation. + */ + step: function (delta) + { + // Update all active bodies + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.update(delta); + } + } + + // Optionally populate our dynamic collision tree + if (this.useTree) + { + this.tree.clear(); + this.tree.load(bodies); + } + + // Process any colliders + var colliders = this.colliders.update(); + + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; + + if (collider.active) + { + collider.update(); + } + } + + this.emit(Events.WORLD_STEP, delta); + + this.stepsLastFrame++; + }, + + /** + * Updates bodies, draws the debug display, and handles pending queue operations. + * + * @method Phaser.Physics.Arcade.World#postUpdate + * @since 3.0.0 + */ + postUpdate: function () + { + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; + + var dynamic = this.bodies; + var staticBodies = this.staticBodies; + + // We don't need to postUpdate if there wasn't a step this frame + if (this.stepsLastFrame) + { + this.stepsLastFrame = 0; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.enable) + { + body.postUpdate(); + } + } + } + + if (this.drawDebug) + { + var graphics = this.debugGraphic; + + graphics.clear(); + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } + } + + bodies = staticBodies.entries; + len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } + } + } + + var pending = this.pendingDestroy; + + if (pending.size > 0) + { + var dynamicTree = this.tree; + var staticTree = this.staticTree; + + bodies = pending.entries; + len = bodies.length; + + for (i = 0; i < len; i++) + { + body = bodies[i]; + + if (body.physicsType === CONST.DYNAMIC_BODY) + { + dynamicTree.remove(body); + dynamic.delete(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + staticTree.remove(body); + staticBodies.delete(body); + } + + body.world = undefined; + body.gameObject = undefined; + } + + pending.clear(); + } + }, + + /** + * Calculates a Body's velocity and updates its position. + * + * @method Phaser.Physics.Arcade.World#updateMotion + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to be updated. + * @param {number} delta - The delta value to be used in the motion calculations, in seconds. + */ + updateMotion: function (body, delta) + { + if (body.allowRotation) + { + this.computeAngularVelocity(body, delta); + } + + this.computeVelocity(body, delta); + }, + + /** + * Calculates a Body's angular velocity. + * + * @method Phaser.Physics.Arcade.World#computeAngularVelocity + * @since 3.10.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. + * @param {number} delta - The delta value to be used in the calculation, in seconds. + */ + computeAngularVelocity: function (body, delta) + { + var velocity = body.angularVelocity; + var acceleration = body.angularAcceleration; + var drag = body.angularDrag; + var max = body.maxAngular; + + if (acceleration) + { + velocity += acceleration * delta; + } + else if (body.allowDrag && drag) + { + drag *= delta; + + if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) + { + velocity -= drag; + } + else if (FuzzyLessThan(velocity + drag, 0, 0.1)) + { + velocity += drag; + } + else + { + velocity = 0; + } + } + + velocity = Clamp(velocity, -max, max); + + var velocityDelta = velocity - body.angularVelocity; + + body.angularVelocity += velocityDelta; + body.rotation += (body.angularVelocity * delta); + }, + + /** + * Calculates a Body's per-axis velocity. + * + * @method Phaser.Physics.Arcade.World#computeVelocity + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for. + * @param {number} delta - The delta value to be used in the calculation, in seconds. + */ + computeVelocity: function (body, delta) + { + var velocityX = body.velocity.x; + var accelerationX = body.acceleration.x; + var dragX = body.drag.x; + var maxX = body.maxVelocity.x; + + var velocityY = body.velocity.y; + var accelerationY = body.acceleration.y; + var dragY = body.drag.y; + var maxY = body.maxVelocity.y; + + var speed = body.speed; + var maxSpeed = body.maxSpeed; + var allowDrag = body.allowDrag; + var useDamping = body.useDamping; + + if (body.allowGravity) + { + velocityX += (this.gravity.x + body.gravity.x) * delta; + velocityY += (this.gravity.y + body.gravity.y) * delta; + } + + if (accelerationX) + { + velocityX += accelerationX * delta; + } + else if (allowDrag && dragX) + { + if (useDamping) + { + // Damping based deceleration + dragX = Math.pow(dragX, delta); + + velocityX *= dragX; + + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityX = 0; + } + } + else + { + // Linear deceleration + dragX *= delta; + + if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) + { + velocityX -= dragX; + } + else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) + { + velocityX += dragX; + } + else + { + velocityX = 0; + } + } + } + + if (accelerationY) + { + velocityY += accelerationY * delta; + } + else if (allowDrag && dragY) + { + if (useDamping) + { + // Damping based deceleration + dragY = Math.pow(dragY, delta); + + velocityY *= dragY; + + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityY = 0; + } + } + else + { + // Linear deceleration + dragY *= delta; + + if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) + { + velocityY -= dragY; + } + else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) + { + velocityY += dragY; + } + else + { + velocityY = 0; + } + } + } + + velocityX = Clamp(velocityX, -maxX, maxX); + velocityY = Clamp(velocityY, -maxY, maxY); + + body.velocity.set(velocityX, velocityY); + + if (maxSpeed > -1 && speed > maxSpeed) + { + body.velocity.normalize().scale(maxSpeed); + speed = maxSpeed; + } + + body.speed = speed; + }, + + /** + * Separates two Bodies. + * + * @method Phaser.Physics.Arcade.World#separate + * @fires Phaser.Physics.Arcade.Events#COLLIDE + * @fires Phaser.Physics.Arcade.Events#OVERLAP + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. + * @param {ArcadePhysicsCallback} [processCallback] - The process callback. + * @param {*} [callbackContext] - The context in which to invoke the callback. + * @param {boolean} [overlapOnly] - If this a collide or overlap check? + * @param {boolean} [intersects] - Assert that the bodies intersect and should not be tested before separation. + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects) + { + if ( + !intersects && + !body1.enable || + !body2.enable || + body1.checkCollision.none || + body2.checkCollision.none || + !this.intersects(body1, body2)) + { + return false; + } + + // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort. + if (processCallback && processCallback.call(callbackContext, body1.gameObject, body2.gameObject) === false) + { + return false; + } + + // Circle vs. Circle quick bail out + if (body1.isCircle && body2.isCircle) + { + return this.separateCircle(body1, body2, overlapOnly); + } + + // We define the behavior of bodies in a collision circle and rectangle + // If a collision occurs in the corner points of the rectangle, the body behave like circles + + // Either body1 or body2 is a circle + if (body1.isCircle !== body2.isCircle) + { + var bodyRect = (body1.isCircle) ? body2 : body1; + var bodyCircle = (body1.isCircle) ? body1 : body2; + + var rect = { + x: bodyRect.x, + y: bodyRect.y, + right: bodyRect.right, + bottom: bodyRect.bottom + }; + + var circle = bodyCircle.center; + + if (circle.y < rect.y || circle.y > rect.bottom) + { + if (circle.x < rect.x || circle.x > rect.right) + { + return this.separateCircle(body1, body2, overlapOnly); + } + } + } + + var resultX = false; + var resultY = false; + + // Do we separate on x first or y first or both? + if (overlapOnly) + { + // No separation but we need to calculate overlapX, overlapY, etc. + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + else if (this.forceX || Math.abs(this.gravity.y + body1.gravity.y) < Math.abs(this.gravity.x + body1.gravity.x)) + { + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + } + else + { + resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + } + } + + var result = (resultX || resultY); + + if (result) + { + if (overlapOnly) + { + if (body1.onOverlap || body2.onOverlap) + { + this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); + } + } + else if (body1.onCollide || body2.onCollide) + { + this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); + } + } + + return result; + }, + + /** + * Separates two Bodies, when both are circular. + * + * @method Phaser.Physics.Arcade.World#separateCircle + * @fires Phaser.Physics.Arcade.Events#COLLIDE + * @fires Phaser.Physics.Arcade.Events#OVERLAP + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated. + * @param {boolean} [overlapOnly] - If this a collide or overlap check? + * @param {number} [bias] - A small value added to the calculations. + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separateCircle: function (body1, body2, overlapOnly, bias) + { + // Set the bounding box overlap values into the bodies themselves (hence we don't use the return values here) + GetOverlapX(body1, body2, false, bias); + GetOverlapY(body1, body2, false, bias); + + var overlap = 0; + + if (body1.isCircle !== body2.isCircle) + { + var rect = { + x: (body2.isCircle) ? body1.position.x : body2.position.x, + y: (body2.isCircle) ? body1.position.y : body2.position.y, + right: (body2.isCircle) ? body1.right : body2.right, + bottom: (body2.isCircle) ? body1.bottom : body2.bottom + }; + + var circle = { + x: (body1.isCircle) ? body1.center.x : body2.center.x, + y: (body1.isCircle) ? body1.center.y : body2.center.y, + radius: (body1.isCircle) ? body1.halfWidth : body2.halfWidth + }; + + if (circle.y < rect.y) + { + if (circle.x < rect.x) + { + overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.y) - circle.radius; + } + else if (circle.x > rect.right) + { + overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.y) - circle.radius; + } + } + else if (circle.y > rect.bottom) + { + if (circle.x < rect.x) + { + overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.bottom) - circle.radius; + } + else if (circle.x > rect.right) + { + overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.bottom) - circle.radius; + } + } + + overlap *= -1; + } + else + { + overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y); + } + + body1.overlapR = overlap; + body2.overlapR = overlap; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1.immovable && body2.immovable) || body1.customSeparateX || body2.customSeparateX) + { + if (overlap !== 0 && (body1.onOverlap || body2.onOverlap)) + { + this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); + } + + // return true if there was some overlap, otherwise false + return (overlap !== 0); + } + + var dx = body1.center.x - body2.center.x; + var dy = body1.center.y - body2.center.y; + var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + var nx = ((body2.center.x - body1.center.x) / d) || 0; + var ny = ((body2.center.y - body1.center.y) / d) || 0; + var p = 2 * (body1.velocity.x * nx + body1.velocity.y * ny - body2.velocity.x * nx - body2.velocity.y * ny) / (body1.mass + body2.mass); + + if (body1.immovable || body2.immovable) + { + p *= 2; + } + + if (!body1.immovable) + { + body1.velocity.x = (body1.velocity.x - p / body1.mass * nx); + body1.velocity.y = (body1.velocity.y - p / body1.mass * ny); + } + + if (!body2.immovable) + { + body2.velocity.x = (body2.velocity.x + p / body2.mass * nx); + body2.velocity.y = (body2.velocity.y + p / body2.mass * ny); + } + + if (!body1.immovable && !body2.immovable) + { + overlap /= 2; + } + + // Note: This is inadequate for circle-rectangle separation + + var angle = AngleBetweenPoints(body1.center, body2.center); + var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle); + var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle); + + if (!body1.immovable) + { + body1.x -= overlapX; + body1.y -= overlapY; + + body1.updateCenter(); + } + + if (!body2.immovable) + { + body2.x += overlapX; + body2.y += overlapY; + + body2.updateCenter(); + } + + body1.velocity.x *= body1.bounce.x; + body1.velocity.y *= body1.bounce.y; + body2.velocity.x *= body2.bounce.x; + body2.velocity.y *= body2.bounce.y; + + if (body1.onCollide || body2.onCollide) + { + this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); + } + + return true; + }, + + /** + * Checks to see if two Bodies intersect at all. + * + * @method Phaser.Physics.Arcade.World#intersects + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first body to check. + * @param {Phaser.Physics.Arcade.Body} body2 - The second body to check. + * + * @return {boolean} True if the two bodies intersect, otherwise false. + */ + intersects: function (body1, body2) + { + if (body1 === body2) + { + return false; + } + + if (!body1.isCircle && !body2.isCircle) + { + // Rect vs. Rect + return !( + body1.right <= body2.position.x || + body1.bottom <= body2.position.y || + body1.position.x >= body2.right || + body1.position.y >= body2.bottom + ); + } + else if (body1.isCircle) + { + if (body2.isCircle) + { + // Circle vs. Circle + return DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y) <= (body1.halfWidth + body2.halfWidth); + } + else + { + // Circle vs. Rect + return this.circleBodyIntersects(body1, body2); + } + } + else + { + // Rect vs. Circle + return this.circleBodyIntersects(body2, body1); + } + }, + + /** + * Tests if a circular Body intersects with another Body. + * + * @method Phaser.Physics.Arcade.World#circleBodyIntersects + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} circle - The circular body to test. + * @param {Phaser.Physics.Arcade.Body} body - The rectangular body to test. + * + * @return {boolean} True if the two bodies intersect, otherwise false. + */ + circleBodyIntersects: function (circle, body) + { + var x = Clamp(circle.center.x, body.left, body.right); + var y = Clamp(circle.center.y, body.top, body.bottom); + + var dx = (circle.center.x - x) * (circle.center.x - x); + var dy = (circle.center.y - y) * (circle.center.y - y); + + return (dx + dy) <= (circle.halfWidth * circle.halfWidth); + }, + + /** + * Tests if Game Objects overlap. + * + * See details in {@link Phaser.Physics.Arcade.World#collide}. + * + * @method Phaser.Physics.Arcade.World#overlap + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `overlapCallback` will only be called if this callback returns `true`. + * @param {*} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if at least one Game Object overlaps another. + * + * @see Phaser.Physics.Arcade.World#collide + */ + overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) + { + if (overlapCallback === undefined) { overlapCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = overlapCallback; } + + return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true); + }, + + /** + * Performs a collision check and separation between the two physics enabled objects given, which can be single + * Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups. + * + * If you don't require separation then use {@link Phaser.Physics.Arcade.World#overlap} instead. + * + * If two Groups or arrays are passed, each member of one will be tested against each member of the other. + * + * If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members. + * + * If **only** one Array is passed, the array is iterated and every element in it is tested against the others. + * + * Two callbacks can be provided; they receive the colliding game objects as arguments. + * If an overlap is detected, the `processCallback` is called first. It can cancel the collision by returning false. + * Next the objects are separated and `collideCallback` is invoked. + * + * Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable + * for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other. + * The separation that stops two objects penetrating may create a new penetration against a different object. If you + * require a high level of stability please consider using an alternative physics system, such as Matter.js. + * + * @method Phaser.Physics.Arcade.World#collide + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} `true` if any overlapping Game Objects were separated, otherwise `false`. + */ + collide: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); + }, + + /** + * Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideObjects + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideObjects: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) + { + var i; + var j; + + if (object1.isParent && object1.physicsType === undefined) + { + object1 = object1.children.entries; + } + + if (object2 && object2.isParent && object2.physicsType === undefined) + { + object2 = object2.children.entries; + } + + var object1isArray = Array.isArray(object1); + var object2isArray = Array.isArray(object2); + + this._total = 0; + + if (!object1isArray && !object2isArray) + { + // Neither of them are arrays - do this first as it's the most common use-case + this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (!object1isArray && object2isArray) + { + // Object 2 is an Array + for (i = 0; i < object2.length; i++) + { + this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + else if (object1isArray && !object2isArray) + { + // Object 1 is an Array + if (!object2) + { + // Special case for array vs. self + for (i = 0; i < object1.length; i++) + { + var child = object1[i]; + + for (j = i + 1; j < object1.length; j++) + { + if (i === j) + { + continue; + } + + this.collideHandler(child, object1[j], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + else + { + for (i = 0; i < object1.length; i++) + { + this.collideHandler(object1[i], object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + else + { + // They're both arrays + for (i = 0; i < object1.length; i++) + { + for (j = 0; j < object2.length; j++) + { + this.collideHandler(object1[i], object2[j], collideCallback, processCallback, callbackContext, overlapOnly); + } + } + } + + return (this._total > 0); + }, + + /** + * Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead. + * + * @method Phaser.Physics.Arcade.World#collideHandler + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object or array of objects to check, or `undefined`. + * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) + { + // Collide Group with Self + // Only collide valid objects + if (object2 === undefined && object1.isParent) + { + return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + + // If neither of the objects are set then bail out + if (!object1 || !object2) + { + return false; + } + + // A Body + if (object1.body) + { + if (object2.body) + { + return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isTilemap) + { + return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + + // GROUPS + else if (object1.isParent) + { + if (object2.body) + { + return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isTilemap) + { + return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + + // TILEMAP LAYERS + else if (object1.isTilemap) + { + if (object2.body) + { + return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + }, + + /** + * Internal handler for Sprite vs. Sprite collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsSprite + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite1 - The first object to check for collision. + * @param {Phaser.GameObjects.GameObject} sprite2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) + { + if (!sprite1.body || !sprite2.body) + { + return false; + } + + if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite1, sprite2); + } + + this._total++; + } + + return true; + }, + + /** + * Internal handler for Sprite vs. Group collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsGroup + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.GameObjects.Group} group - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. + */ + collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) + { + var bodyA = sprite.body; + + if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) + { + return; + } + + // Does sprite collide with anything? + + var i; + var len; + var bodyB; + + if (this.useTree || group.physicsType === CONST.STATIC_BODY) + { + var minMax = this.treeMinMax; + + minMax.minX = bodyA.left; + minMax.minY = bodyA.top; + minMax.maxX = bodyA.right; + minMax.maxY = bodyA.bottom; + + var results = (group.physicsType === CONST.DYNAMIC_BODY) ? this.tree.search(minMax) : this.staticTree.search(minMax); + + len = results.length; + + for (i = 0; i < len; i++) + { + bodyB = results[i]; + + if (bodyA === bodyB || !bodyB.enable || bodyB.checkCollision.none || !group.contains(bodyB.gameObject)) + { + // Skip if comparing against itself, or if bodyB isn't collidable, or if bodyB isn't actually part of the Group + continue; + } + + if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); + } + + this._total++; + } + } + } + else + { + var children = group.getChildren(); + var skipIndex = group.children.entries.indexOf(sprite); + + len = children.length; + + for (i = 0; i < len; i++) + { + bodyB = children[i].body; + + if (!bodyB || i === skipIndex || !bodyB.enable) + { + continue; + } + + if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); + } + + this._total++; + } + } + } + }, + + /** + * Internal handler for Group vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Group} group - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + { + var children = group.getChildren(); + + if (children.length === 0) + { + return false; + } + + var didCollide = false; + + for (var i = 0; i < children.length; i++) + { + if (children[i].body) + { + if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) + { + didCollide = true; + } + } + } + + return didCollide; + }, + + /** + * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. + * + * You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform + * tile filtering and culling for you, as well as handle the interesting face collision automatically. + * + * This method is offered for those who would like to check for collision with specific Tiles in a layer, without + * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions + * on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, + * you should filter them before passing them to this method. + * + * Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have + * say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the + * tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on + * dynamic maps, this method can prove very useful. + * + * @method Phaser.Physics.Arcade.World#collideTiles + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) + { + if (!sprite.body.enable || tiles.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); + } + }, + + /** + * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. + * + * You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform + * tile filtering and culling for you, as well as handle the interesting face collision automatically. + * + * This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without + * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap + * tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method, + * you should filter them before passing them to this method. + * + * @method Phaser.Physics.Arcade.World#overlapTiles + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + overlapTiles: function (sprite, tiles, collideCallback, processCallback, callbackContext) + { + if (!sprite.body.enable || tiles.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); + } + }, + + /** + * Internal handler for Sprite vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsTilemapLayer + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + { + var body = sprite.body; + + if (!body.enable || body.checkCollision.none) + { + return false; + } + + var x = body.position.x; + var y = body.position.y; + var w = body.width; + var h = body.height; + + var layerData = tilemapLayer.layer; + + if (layerData.tileWidth > layerData.baseTileWidth) + { + // The x origin of a tile is the left side, so x and width need to be adjusted. + var xDiff = (layerData.tileWidth - layerData.baseTileWidth) * tilemapLayer.scaleX; + x -= xDiff; + w += xDiff; + } + + if (layerData.tileHeight > layerData.baseTileHeight) + { + // The y origin of a tile is the bottom side, so just the height needs to be adjusted. + var yDiff = (layerData.tileHeight - layerData.baseTileHeight) * tilemapLayer.scaleY; + h += yDiff; + } + + var mapData = GetTilesWithinWorldXY(x, y, w, h, null, tilemapLayer.scene.cameras.main, tilemapLayer.layer); + + if (mapData.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); + } + }, + + /** + * Internal handler for Sprite vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler + * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @private + * @since 3.17.0 + * + * @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} [overlapOnly] - Whether this is a collision or overlap check. + * @param {boolean} [isLayer] - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) + { + var body = sprite.body; + + var tile; + var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 }; + var tilemapLayer; + var collision = false; + + for (var i = 0; i < tiles.length; i++) + { + tile = tiles[i]; + + tilemapLayer = tile.tilemapLayer; + + var point = tilemapLayer.tileToWorldXY(tile.x, tile.y); + + tileWorldRect.left = point.x; + tileWorldRect.top = point.y; + + // If the maps base tile size differs from the layer tile size, only the top of the rect + // needs to be adjusted since its origin is (0, 1). + if (tile.baseHeight !== tile.height) + { + tileWorldRect.top -= (tile.height - tile.baseHeight) * tilemapLayer.scaleY; + } + + tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; + tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; + + if (TileIntersectsBody(tileWorldRect, body) + && (!processCallback || processCallback.call(callbackContext, sprite, tile)) + && ProcessTileCallbacks(tile, sprite) + && (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS, isLayer))) + { + this._total++; + + collision = true; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, tile); + } + + if (overlapOnly && body.onOverlap) + { + this.emit(Events.TILE_OVERLAP, sprite, tile, body); + } + else if (body.onCollide) + { + this.emit(Events.TILE_COLLIDE, sprite, tile, body); + } + } + } + + return collision; + }, + + /** + * Internal helper for Group vs. Group collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. + * + * @method Phaser.Physics.Arcade.World#collideGroupVsGroup + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Group} group1 - The first object to check for collision. + * @param {Phaser.GameObjects.Group} group2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`. + * @param {any} [callbackContext] - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Whether this is a collision or overlap check. + * + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + */ + collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) + { + if (group1.length === 0 || group2.length === 0) + { + return; + } + + var children = group1.getChildren(); + + for (var i = 0; i < children.length; i++) + { + this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); + } + }, + + /** + * Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}. + * + * If the object is outside any boundary edge (left, top, right, bottom), it will be moved to the same offset from the opposite edge (the interior). + * + * @method Phaser.Physics.Arcade.World#wrap + * @since 3.3.0 + * + * @param {any} object - A Game Object, a Group, an object with `x` and `y` coordinates, or an array of such objects. + * @param {number} [padding=0] - An amount added to each boundary edge during the operation. + */ + wrap: function (object, padding) + { + if (object.body) + { + this.wrapObject(object, padding); + } + else if (object.getChildren) + { + this.wrapArray(object.getChildren(), padding); + } + else if (Array.isArray(object)) + { + this.wrapArray(object, padding); + } + else + { + this.wrapObject(object, padding); + } + }, + + /** + * Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. + * + * @method Phaser.Physics.Arcade.World#wrapArray + * @since 3.3.0 + * + * @param {Array.<*>} objects - An array of objects to be wrapped. + * @param {number} [padding=0] - An amount added to the boundary. + */ + wrapArray: function (objects, padding) + { + for (var i = 0; i < objects.length; i++) + { + this.wrapObject(objects[i], padding); + } + }, + + /** + * Wrap an object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. + * + * @method Phaser.Physics.Arcade.World#wrapObject + * @since 3.3.0 + * + * @param {*} object - A Game Object, a Physics Body, or any object with `x` and `y` coordinates + * @param {number} [padding=0] - An amount added to the boundary. + */ + wrapObject: function (object, padding) + { + if (padding === undefined) { padding = 0; } + + object.x = Wrap(object.x, this.bounds.left - padding, this.bounds.right + padding); + object.y = Wrap(object.y, this.bounds.top - padding, this.bounds.bottom + padding); + }, + + /** + * Shuts down the simulation, clearing physics data and removing listeners. + * + * @method Phaser.Physics.Arcade.World#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + this.tree.clear(); + this.staticTree.clear(); + this.bodies.clear(); + this.staticBodies.clear(); + this.colliders.destroy(); + + this.removeAllListeners(); + }, + + /** + * Shuts down the simulation and disconnects it from the current scene. + * + * @method Phaser.Physics.Arcade.World#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + + this.scene = null; + } + +}); + +module.exports = World; + + +/***/ }), +/* 521 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @author Benjamin D. Richards + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var Events = __webpack_require__(242); +var RadToDeg = __webpack_require__(193); +var Rectangle = __webpack_require__(10); +var RectangleContains = __webpack_require__(56); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A Dynamic Arcade Body. + * + * Its static counterpart is {@link Phaser.Physics.Arcade.StaticBody}. + * + * @class Body + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Body belongs to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. + */ +var Body = new Class({ + + initialize: + + function Body (world, gameObject) + { + var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; + var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; + + /** + * The Arcade Physics simulation this Body belongs to. + * + * @name Phaser.Physics.Arcade.Body#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The Game Object this Body belongs to. + * + * @name Phaser.Physics.Arcade.Body#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = gameObject; + + /** + * Transformations applied to this Body. + * + * @name Phaser.Physics.Arcade.Body#transform + * @type {object} + * @since 3.4.0 + */ + this.transform = { + x: gameObject.x, + y: gameObject.y, + rotation: gameObject.angle, + scaleX: gameObject.scaleX, + scaleY: gameObject.scaleY, + displayOriginX: gameObject.displayOriginX, + displayOriginY: gameObject.displayOriginY + }; + + /** + * Whether the Body is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugShowBody + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowBody = world.defaults.debugShowBody; + + /** + * Whether the Body's velocity is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugShowVelocity + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowVelocity = world.defaults.debugShowVelocity; + + /** + * The color of this Body on the debug display. + * + * @name Phaser.Physics.Arcade.Body#debugBodyColor + * @type {number} + * @since 3.0.0 + */ + this.debugBodyColor = world.defaults.bodyDebugColor; + + /** + * Whether this Body is updated by the physics simulation. + * + * @name Phaser.Physics.Arcade.Body#enable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enable = true; + + /** + * Whether this Body is circular (true) or rectangular (false). + * + * @name Phaser.Physics.Arcade.Body#isCircle + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setCircle + */ + this.isCircle = false; + + /** + * If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels. + * The true radius is equal to `halfWidth`. + * + * @name Phaser.Physics.Arcade.Body#radius + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setCircle + */ + this.radius = 0; + + /** + * The offset of this Body's position from its Game Object's position, in source pixels. + * + * @name Phaser.Physics.Arcade.Body#offset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setOffset + */ + this.offset = new Vector2(); + + /** + * The position of this Body within the simulation. + * + * @name Phaser.Physics.Arcade.Body#position + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.position = new Vector2( + gameObject.x - gameObject.scaleX * gameObject.displayOriginX, + gameObject.y - gameObject.scaleY * gameObject.displayOriginY + ); + + /** + * The position of this Body during the previous step. + * + * @name Phaser.Physics.Arcade.Body#prev + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.prev = this.position.clone(); + + /** + * The position of this Body during the previous frame. + * + * @name Phaser.Physics.Arcade.Body#prevFrame + * @type {Phaser.Math.Vector2} + * @since 3.20.0 + */ + this.prevFrame = this.position.clone(); + + /** + * Whether this Body's `rotation` is affected by its angular acceleration and angular velocity. + * + * @name Phaser.Physics.Arcade.Body#allowRotation + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.allowRotation = true; + + /** + * This body's rotation, in degrees, based on its angular acceleration and angular velocity. + * The Body's rotation controls the `angle` of its Game Object. + * It doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle. + * + * @name Phaser.Physics.Arcade.Body#rotation + * @type {number} + * @since 3.0.0 + */ + this.rotation = gameObject.angle; + + /** + * The Body rotation, in degrees, during the previous step. + * + * @name Phaser.Physics.Arcade.Body#preRotation + * @type {number} + * @since 3.0.0 + */ + this.preRotation = gameObject.angle; + + /** + * The width of the Body, in pixels. + * If the Body is circular, this is also the diameter. + * If you wish to change the width use the `Body.setSize` method. + * + * @name Phaser.Physics.Arcade.Body#width + * @type {number} + * @readonly + * @default 64 + * @since 3.0.0 + */ + this.width = width; + + /** + * The height of the Body, in pixels. + * If the Body is circular, this is also the diameter. + * If you wish to change the height use the `Body.setSize` method. + * + * @name Phaser.Physics.Arcade.Body#height + * @type {number} + * @readonly + * @default 64 + * @since 3.0.0 + */ + this.height = height; + + /** + * The unscaled width of the Body, in source pixels, as set by setSize(). + * The default is the width of the Body's Game Object's texture frame. + * + * @name Phaser.Physics.Arcade.Body#sourceWidth + * @type {number} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setSize + */ + this.sourceWidth = width; + + /** + * The unscaled height of the Body, in source pixels, as set by setSize(). + * The default is the height of the Body's Game Object's texture frame. + * + * @name Phaser.Physics.Arcade.Body#sourceHeight + * @type {number} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#setSize + */ + this.sourceHeight = height; + + if (gameObject.frame) + { + this.sourceWidth = gameObject.frame.realWidth; + this.sourceHeight = gameObject.frame.realHeight; + } + + /** + * Half the Body's width, in pixels. + * + * @name Phaser.Physics.Arcade.Body#halfWidth + * @type {number} + * @since 3.0.0 + */ + this.halfWidth = Math.abs(width / 2); + + /** + * Half the Body's height, in pixels. + * + * @name Phaser.Physics.Arcade.Body#halfHeight + * @type {number} + * @since 3.0.0 + */ + this.halfHeight = Math.abs(height / 2); + + /** + * The center of the Body. + * The midpoint of its `position` (top-left corner) and its bottom-right corner. + * + * @name Phaser.Physics.Arcade.Body#center + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + /** + * The Body's velocity, in pixels per second. + * + * @name Phaser.Physics.Arcade.Body#velocity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.velocity = new Vector2(); + + /** + * The Body's change in position (due to velocity) at the last step, in pixels. + * + * The size of this value depends on the simulation's step rate. + * + * @name Phaser.Physics.Arcade.Body#newVelocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.newVelocity = new Vector2(); + + /** + * The Body's absolute maximum change in position, in pixels per step. + * + * @name Phaser.Physics.Arcade.Body#deltaMax + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.deltaMax = new Vector2(); + + /** + * The Body's change in velocity, in pixels per second squared. + * + * @name Phaser.Physics.Arcade.Body#acceleration + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.acceleration = new Vector2(); + + /** + * Whether this Body's velocity is affected by its `drag`. + * + * @name Phaser.Physics.Arcade.Body#allowDrag + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.allowDrag = true; + + /** + * When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared. + * + * When `useDamping` is true, this is a damping multiplier between 0 and 1. + * A value of 0 means the Body stops instantly. + * A value of 0.01 mean the Body loses 99% of its velocity per second. + * A value of 0.1 means the Body loses 90% of its velocity per second. + * A value of 1 means the Body loses no velocity. + * + * The x and y components are applied separately. + * + * Drag is applied only when `acceleration` is zero. + * + * @name Phaser.Physics.Arcade.Body#drag + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.drag = new Vector2(); + + /** + * Whether this Body's position is affected by gravity (local or world). + * + * @name Phaser.Physics.Arcade.Body#allowGravity + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#gravity + * @see Phaser.Physics.Arcade.World#gravity + */ + this.allowGravity = true; + + /** + * Acceleration due to gravity (specific to this Body), in pixels per second squared. + * Total gravity is the sum of this vector and the simulation's `gravity`. + * + * @name Phaser.Physics.Arcade.Body#gravity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#gravity + */ + this.gravity = new Vector2(); + + /** + * Rebound following a collision, relative to 1. + * + * @name Phaser.Physics.Arcade.Body#bounce + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.bounce = new Vector2(); + + /** + * Rebound following a collision with the world boundary, relative to 1. + * If null, `bounce` is used instead. + * + * @name Phaser.Physics.Arcade.Body#worldBounce + * @type {?Phaser.Math.Vector2} + * @default null + * @since 3.0.0 + */ + this.worldBounce = null; + + /** + * The rectangle used for world boundary collisions. + * + * By default it is set to the world boundary rectangle. Or, if this Body was + * created by a Physics Group, then whatever rectangle that Group defined. + * + * You can also change it by using the `Body.setBoundsRectangle` method. + * + * @name Phaser.Physics.Arcade.Body#customBoundsRectangle + * @type {Phaser.Geom.Rectangle} + * @since 3.20 + */ + this.customBoundsRectangle = world.bounds; + + // If true this Body will dispatch events + + /** + * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). + * + * @name Phaser.Physics.Arcade.Body#onWorldBounds + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#WORLD_BOUNDS + */ + this.onWorldBounds = false; + + /** + * Whether the simulation emits a `collide` event when this Body collides with another. + * + * @name Phaser.Physics.Arcade.Body#onCollide + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#COLLIDE + */ + this.onCollide = false; + + /** + * Whether the simulation emits an `overlap` event when this Body overlaps with another. + * + * @name Phaser.Physics.Arcade.Body#onOverlap + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.Physics.Arcade.World#OVERLAP + */ + this.onOverlap = false; + + /** + * The Body's absolute maximum velocity, in pixels per second. + * The horizontal and vertical components are applied separately. + * + * @name Phaser.Physics.Arcade.Body#maxVelocity + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.maxVelocity = new Vector2(10000, 10000); + + /** + * The maximum speed this Body is allowed to reach, in pixels per second. + * + * If not negative it limits the scalar value of speed. + * + * Any negative value means no maximum is being applied (the default). + * + * @name Phaser.Physics.Arcade.Body#maxSpeed + * @type {number} + * @default -1 + * @since 3.16.0 + */ + this.maxSpeed = -1; + + /** + * If this Body is `immovable` and in motion, `friction` is the proportion of this Body's motion received by the riding Body on each axis, relative to 1. + * The horizontal component (x) is applied only when two colliding Bodies are separated vertically. + * The vertical component (y) is applied only when two colliding Bodies are separated horizontally. + * The default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all. + * + * @name Phaser.Physics.Arcade.Body#friction + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.friction = new Vector2(1, 0); + + /** + * If this Body is using `drag` for deceleration this property controls how the drag is applied. + * If set to `true` drag will use a damping effect rather than a linear approach. If you are + * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in + * the game Asteroids) then you will get a far smoother and more visually correct deceleration + * by using damping, avoiding the axis-drift that is prone with linear deceleration. + * + * If you enable this property then you should use far smaller `drag` values than with linear, as + * they are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow + * deceleration. + * + * @name Phaser.Physics.Arcade.Body#useDamping + * @type {boolean} + * @default false + * @since 3.10.0 + */ + this.useDamping = false; + + /** + * The rate of change of this Body's `rotation`, in degrees per second. + * + * @name Phaser.Physics.Arcade.Body#angularVelocity + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularVelocity = 0; + + /** + * The Body's angular acceleration (change in angular velocity), in degrees per second squared. + * + * @name Phaser.Physics.Arcade.Body#angularAcceleration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularAcceleration = 0; + + /** + * Loss of angular velocity due to angular movement, in degrees per second. + * + * Angular drag is applied only when angular acceleration is zero. + * + * @name Phaser.Physics.Arcade.Body#angularDrag + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angularDrag = 0; + + /** + * The Body's maximum angular velocity, in degrees per second. + * + * @name Phaser.Physics.Arcade.Body#maxAngular + * @type {number} + * @default 1000 + * @since 3.0.0 + */ + this.maxAngular = 1000; + + /** + * The Body's inertia, relative to a default unit (1). + * With `bounce`, this affects the exchange of momentum (velocities) during collisions. + * + * @name Phaser.Physics.Arcade.Body#mass + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.mass = 1; + + /** + * The calculated angle of this Body's velocity vector, in radians, during the last step. + * + * @name Phaser.Physics.Arcade.Body#angle + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angle = 0; + + /** + * The calculated magnitude of the Body's velocity, in pixels per second, during the last step. + * + * @name Phaser.Physics.Arcade.Body#speed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.speed = 0; + + /** + * The direction of the Body's velocity, as calculated during the last step. + * This is a numeric constant value (FACING_UP, FACING_DOWN, FACING_LEFT, FACING_RIGHT). + * If the Body is moving on both axes, this describes motion on the vertical axis only. + * + * @name Phaser.Physics.Arcade.Body#facing + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.FACING_UP + * @see Phaser.Physics.Arcade.FACING_DOWN + * @see Phaser.Physics.Arcade.FACING_LEFT + * @see Phaser.Physics.Arcade.FACING_RIGHT + */ + this.facing = CONST.FACING_NONE; + + /** + * Whether this Body can be moved by collisions with another Body. + * + * @name Phaser.Physics.Arcade.Body#immovable + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.immovable = false; + + /** + * Sets if this Body can be pushed by another Body. + * + * A body that cannot be pushed will reflect back all of the velocity it is given to the + * colliding body. If that body is also not pushable, then the separation will be split + * between them evenly. + * + * If you want your body to never move or seperate at all, see the `setImmovable` method. + * + * By default, Dynamic Bodies are always pushable. + * + * @name Phaser.Physics.Arcade.Body#pushable + * @type {boolean} + * @default true + * @since 3.50.0 + * @see Phaser.GameObjects.Components.Pushable#setPushable + */ + this.pushable = true; + + /** + * Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity. + * + * @name Phaser.Physics.Arcade.Body#moves + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.moves = true; + + /** + * A flag disabling the default horizontal separation of colliding bodies. + * Pass your own `collideCallback` to the collider. + * + * @name Phaser.Physics.Arcade.Body#customSeparateX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateX = false; + + /** + * A flag disabling the default vertical separation of colliding bodies. + * Pass your own `collideCallback` to the collider. + * + * @name Phaser.Physics.Arcade.Body#customSeparateY + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateY = false; + + /** + * The amount of horizontal overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.Body#overlapX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapX = 0; + + /** + * The amount of vertical overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.Body#overlapY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapY = 0; + + /** + * The amount of overlap (before separation), if this Body is circular and colliding with another circular body. + * + * @name Phaser.Physics.Arcade.Body#overlapR + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapR = 0; + + /** + * Whether this Body is overlapped with another and both are not moving, on at least one axis. + * + * @name Phaser.Physics.Arcade.Body#embedded + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.embedded = false; + + /** + * Whether this Body interacts with the world boundary. + * + * @name Phaser.Physics.Arcade.Body#collideWorldBounds + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.collideWorldBounds = false; + + /** + * Whether this Body is checked for collisions and for which directions. + * You can set `checkCollision.none = true` to disable collision checks. + * + * @name Phaser.Physics.Arcade.Body#checkCollision + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; + + /** + * Whether this Body is colliding with a Body or Static Body and in which direction. + * In a collision where both bodies have zero velocity, `embedded` will be set instead. + * + * @name Phaser.Physics.Arcade.Body#touching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#blocked + * @see Phaser.Physics.Arcade.Body#embedded + */ + this.touching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This Body's `touching` value during the previous step. + * + * @name Phaser.Physics.Arcade.Body#wasTouching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#touching + */ + this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * Whether this Body is colliding with a Static Body, a tile, or the world boundary. + * In a collision with a Static Body, if this Body has zero velocity then `embedded` will be set instead. + * + * @name Phaser.Physics.Arcade.Body#blocked + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#embedded + * @see Phaser.Physics.Arcade.Body#touching + */ + this.blocked = { none: true, up: false, down: false, left: false, right: false }; + + /** + * Whether to automatically synchronize this Body's dimensions to the dimensions of its Game Object's visual bounds. + * + * @name Phaser.Physics.Arcade.Body#syncBounds + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Components.GetBounds#getBounds + */ + this.syncBounds = false; + + /** + * The Body's physics type (dynamic or static). + * + * @name Phaser.Physics.Arcade.Body#physicsType + * @type {number} + * @readonly + * @default Phaser.Physics.Arcade.DYNAMIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.DYNAMIC_BODY; + + /** + * Cached horizontal scale of the Body's Game Object. + * + * @name Phaser.Physics.Arcade.Body#_sx + * @type {number} + * @private + * @since 3.0.0 + */ + this._sx = gameObject.scaleX; + + /** + * Cached vertical scale of the Body's Game Object. + * + * @name Phaser.Physics.Arcade.Body#_sy + * @type {number} + * @private + * @since 3.0.0 + */ + this._sy = gameObject.scaleY; + + /** + * The calculated change in the Body's horizontal position during the last step. + * + * @name Phaser.Physics.Arcade.Body#_dx + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._dx = 0; + + /** + * The calculated change in the Body's vertical position during the last step. + * + * @name Phaser.Physics.Arcade.Body#_dy + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._dy = 0; + + /** + * The final calculated change in the Body's horizontal position as of `postUpdate`. + * + * @name Phaser.Physics.Arcade.Body#_tx + * @type {number} + * @private + * @default 0 + * @since 3.22.0 + */ + this._tx = 0; + + /** + * The final calculated change in the Body's vertical position as of `postUpdate`. + * + * @name Phaser.Physics.Arcade.Body#_ty + * @type {number} + * @private + * @default 0 + * @since 3.22.0 + */ + this._ty = 0; + + /** + * Stores the Game Object's bounds. + * + * @name Phaser.Physics.Arcade.Body#_bounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.0.0 + */ + this._bounds = new Rectangle(); + }, + + /** + * Updates the Body's `transform`, `width`, `height`, and `center` from its Game Object. + * The Body's `position` isn't changed. + * + * @method Phaser.Physics.Arcade.Body#updateBounds + * @since 3.0.0 + */ + updateBounds: function () + { + var sprite = this.gameObject; + + // Container? + + var transform = this.transform; + + if (sprite.parentContainer) + { + var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2); + + transform.x = matrix.tx; + transform.y = matrix.ty; + transform.rotation = RadToDeg(matrix.rotation); + transform.scaleX = matrix.scaleX; + transform.scaleY = matrix.scaleY; + transform.displayOriginX = sprite.displayOriginX; + transform.displayOriginY = sprite.displayOriginY; + } + else + { + transform.x = sprite.x; + transform.y = sprite.y; + transform.rotation = sprite.angle; + transform.scaleX = sprite.scaleX; + transform.scaleY = sprite.scaleY; + transform.displayOriginX = sprite.displayOriginX; + transform.displayOriginY = sprite.displayOriginY; + } + + var recalc = false; + + if (this.syncBounds) + { + var b = sprite.getBounds(this._bounds); + + this.width = b.width; + this.height = b.height; + recalc = true; + } + else + { + var asx = Math.abs(transform.scaleX); + var asy = Math.abs(transform.scaleY); + + if (this._sx !== asx || this._sy !== asy) + { + this.width = this.sourceWidth * asx; + this.height = this.sourceHeight * asy; + this._sx = asx; + this._sy = asy; + recalc = true; + } + } + + if (recalc) + { + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + this.updateCenter(); + } + }, + + /** + * Updates the Body's `center` from its `position`, `width`, and `height`. + * + * @method Phaser.Physics.Arcade.Body#updateCenter + * @since 3.0.0 + */ + updateCenter: function () + { + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + }, + + /** + * Updates the Body's `position`, `width`, `height`, and `center` from its Game Object and `offset`. + * + * You don't need to call this for Dynamic Bodies, as it happens automatically during the physics step. + * But you could use it if you have modified the Body offset or Game Object transform and need to immediately + * read the Body's new `position` or `center`. + * + * To resynchronize the Body with its Game Object, use `reset()` instead. + * + * @method Phaser.Physics.Arcade.Body#updateFromGameObject + * @since 3.24.0 + */ + updateFromGameObject: function () + { + this.updateBounds(); + + var transform = this.transform; + + this.position.x = transform.x + transform.scaleX * (this.offset.x - transform.displayOriginX); + this.position.y = transform.y + transform.scaleY * (this.offset.y - transform.displayOriginY); + + this.updateCenter(); + }, + + /** + * Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states. + * + * This method is only called if the physics world is going to run a step this frame. + * + * @method Phaser.Physics.Arcade.Body#resetFlags + * @since 3.18.0 + * + * @param {boolean} [clear=false] - Set the `wasTouching` values to their defaults. + */ + resetFlags: function (clear) + { + if (clear === undefined) + { + clear = false; + } + + // Store and reset collision flags + var wasTouching = this.wasTouching; + var touching = this.touching; + var blocked = this.blocked; + + if (clear) + { + wasTouching.none = true; + wasTouching.up = false; + wasTouching.down = false; + wasTouching.left = false; + wasTouching.right = false; + } + else + { + wasTouching.none = touching.none; + wasTouching.up = touching.up; + wasTouching.down = touching.down; + wasTouching.left = touching.left; + wasTouching.right = touching.right; + } + + touching.none = true; + touching.up = false; + touching.down = false; + touching.left = false; + touching.right = false; + + blocked.none = true; + blocked.up = false; + blocked.down = false; + blocked.left = false; + blocked.right = false; + + this.overlapR = 0; + this.overlapX = 0; + this.overlapY = 0; + + this.embedded = false; + }, + + /** + * Syncs the position body position with the parent Game Object. + * + * This method is called every game frame, regardless if the world steps or not. + * + * @method Phaser.Physics.Arcade.Body#preUpdate + * @since 3.17.0 + * + * @param {boolean} willStep - Will this Body run an update as well? + * @param {number} delta - The delta time, in seconds, elapsed since the last frame. + */ + preUpdate: function (willStep, delta) + { + if (willStep) + { + this.resetFlags(); + } + + this.updateFromGameObject(); + + this.rotation = this.transform.rotation; + this.preRotation = this.rotation; + + if (this.moves) + { + this.prev.x = this.position.x; + this.prev.y = this.position.y; + this.prevFrame.x = this.position.x; + this.prevFrame.y = this.position.y; + } + + if (willStep) + { + this.update(delta); + } + }, + + /** + * Performs a single physics step and updates the body velocity, angle, speed and other properties. + * + * This method can be called multiple times per game frame, depending on the physics step rate. + * + * The results are synced back to the Game Object in `postUpdate`. + * + * @method Phaser.Physics.Arcade.Body#update + * @fires Phaser.Physics.Arcade.Events#WORLD_BOUNDS + * @since 3.0.0 + * + * @param {number} delta - The delta time, in seconds, elapsed since the last frame. + */ + update: function (delta) + { + this.prev.x = this.position.x; + this.prev.y = this.position.y; + + if (this.moves) + { + this.world.updateMotion(this, delta); + + var vx = this.velocity.x; + var vy = this.velocity.y; + + this.newVelocity.set(vx * delta, vy * delta); + + this.position.add(this.newVelocity); + + this.updateCenter(); + + this.angle = Math.atan2(vy, vx); + this.speed = Math.sqrt(vx * vx + vy * vy); + + // Now the update will throw collision checks at the Body + // And finally we'll integrate the new position back to the Sprite in postUpdate + + if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) + { + this.world.emit(Events.WORLD_BOUNDS, this, this.blocked.up, this.blocked.down, this.blocked.left, this.blocked.right); + } + } + + this._dx = this.position.x - this.prev.x; + this._dy = this.position.y - this.prev.y; + }, + + /** + * Feeds the Body results back into the parent Game Object. + * + * This method is called every game frame, regardless if the world steps or not. + * + * @method Phaser.Physics.Arcade.Body#postUpdate + * @since 3.0.0 + */ + postUpdate: function () + { + var dx = this.position.x - this.prevFrame.x; + var dy = this.position.y - this.prevFrame.y; + + if (this.moves) + { + var mx = this.deltaMax.x; + var my = this.deltaMax.y; + + if (mx !== 0 && dx !== 0) + { + if (dx < 0 && dx < -mx) + { + dx = -mx; + } + else if (dx > 0 && dx > mx) + { + dx = mx; + } + } + + if (my !== 0 && dy !== 0) + { + if (dy < 0 && dy < -my) + { + dy = -my; + } + else if (dy > 0 && dy > my) + { + dy = my; + } + } + + this.gameObject.x += dx; + this.gameObject.y += dy; + } + + if (dx < 0) + { + this.facing = CONST.FACING_LEFT; + } + else if (dx > 0) + { + this.facing = CONST.FACING_RIGHT; + } + + if (dy < 0) + { + this.facing = CONST.FACING_UP; + } + else if (dy > 0) + { + this.facing = CONST.FACING_DOWN; + } + + if (this.allowRotation) + { + this.gameObject.angle += this.deltaZ(); + } + + this._tx = dx; + this._ty = dy; + }, + + /** + * Sets a custom collision boundary rectangle. Use if you want to have a custom + * boundary instead of the world boundaries. + * + * @method Phaser.Physics.Arcade.Body#setBoundsRectangle + * @since 3.20 + * + * @param {?Phaser.Geom.Rectangle} [bounds] - The new boundary rectangle. Pass `null` to use the World bounds. + * + * @return {this} This Body object. + */ + setBoundsRectangle: function (bounds) + { + this.customBoundsRectangle = (!bounds) ? this.world.bounds : bounds; + + return this; + }, + + /** + * Checks for collisions between this Body and the world boundary and separates them. + * + * @method Phaser.Physics.Arcade.Body#checkWorldBounds + * @since 3.0.0 + * + * @return {boolean} True if this Body is colliding with the world boundary. + */ + checkWorldBounds: function () + { + var pos = this.position; + var bounds = this.customBoundsRectangle; + var check = this.world.checkCollision; + + var bx = (this.worldBounce) ? -this.worldBounce.x : -this.bounce.x; + var by = (this.worldBounce) ? -this.worldBounce.y : -this.bounce.y; + + var wasSet = false; + + if (pos.x < bounds.x && check.left) + { + pos.x = bounds.x; + this.velocity.x *= bx; + this.blocked.left = true; + wasSet = true; + } + else if (this.right > bounds.right && check.right) + { + pos.x = bounds.right - this.width; + this.velocity.x *= bx; + this.blocked.right = true; + wasSet = true; + } + + if (pos.y < bounds.y && check.up) + { + pos.y = bounds.y; + this.velocity.y *= by; + this.blocked.up = true; + wasSet = true; + } + else if (this.bottom > bounds.bottom && check.down) + { + pos.y = bounds.bottom - this.height; + this.velocity.y *= by; + this.blocked.down = true; + wasSet = true; + } + + if (wasSet) + { + this.blocked.none = false; + this.updateCenter(); + } + + return wasSet; + }, + + /** + * Sets the offset of the Body's position from its Game Object's position. + * The Body's `position` isn't changed until the next `preUpdate`. + * + * @method Phaser.Physics.Arcade.Body#setOffset + * @since 3.0.0 + * + * @param {number} x - The horizontal offset, in source pixels. + * @param {number} [y=x] - The vertical offset, in source pixels. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setOffset: function (x, y) + { + if (y === undefined) { y = x; } + + this.offset.set(x, y); + + return this; + }, + + /** + * Sizes and positions this Body, as a rectangle. + * Modifies the Body `offset` if `center` is true (the default). + * Resets the width and height to match current frame, if no width and height provided and a frame is found. + * + * @method Phaser.Physics.Arcade.Body#setSize + * @since 3.0.0 + * + * @param {number} [width] - The width of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. + * @param {number} [height] - The height of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. + * @param {boolean} [center=true] - Modify the Body's `offset`, placing the Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setSize: function (width, height, center) + { + if (center === undefined) { center = true; } + + var gameObject = this.gameObject; + + if (!width && gameObject.frame) + { + width = gameObject.frame.realWidth; + } + + if (!height && gameObject.frame) + { + height = gameObject.frame.realHeight; + } + + this.sourceWidth = width; + this.sourceHeight = height; + + this.width = this.sourceWidth * this._sx; + this.height = this.sourceHeight * this._sy; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.updateCenter(); + + if (center && gameObject.getCenter) + { + var ox = (gameObject.width - width) / 2; + var oy = (gameObject.height - height) / 2; + + this.offset.set(ox, oy); + } + + this.isCircle = false; + this.radius = 0; + + return this; + }, + + /** + * Sizes and positions this Body, as a circle. + * + * @method Phaser.Physics.Arcade.Body#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the Body, in source pixels. + * @param {number} [offsetX] - The horizontal offset of the Body from its Game Object, in source pixels. + * @param {number} [offsetY] - The vertical offset of the Body from its Game Object, in source pixels. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setCircle: function (radius, offsetX, offsetY) + { + if (offsetX === undefined) { offsetX = this.offset.x; } + if (offsetY === undefined) { offsetY = this.offset.y; } + + if (radius > 0) + { + this.isCircle = true; + this.radius = radius; + + this.sourceWidth = radius * 2; + this.sourceHeight = radius * 2; + + this.width = this.sourceWidth * this._sx; + this.height = this.sourceHeight * this._sy; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.offset.set(offsetX, offsetY); + + this.updateCenter(); + } + else + { + this.isCircle = false; + } + + return this; + }, + + /** + * Sets this Body's parent Game Object to the given coordinates and resets this Body at the new coordinates. + * If the Body had any velocity or acceleration it is lost as a result of calling this. + * + * @method Phaser.Physics.Arcade.Body#reset + * @since 3.0.0 + * + * @param {number} x - The horizontal position to place the Game Object. + * @param {number} y - The vertical position to place the Game Object. + */ + reset: function (x, y) + { + this.stop(); + + var gameObject = this.gameObject; + + gameObject.setPosition(x, y); + + if (gameObject.getTopLeft) + { + gameObject.getTopLeft(this.position); + } + else + { + this.position.set(x, y); + } + + this.prev.copy(this.position); + this.prevFrame.copy(this.position); + + this.rotation = gameObject.angle; + this.preRotation = gameObject.angle; + + this.updateBounds(); + this.updateCenter(); + this.resetFlags(true); + }, + + /** + * Sets acceleration, velocity, and speed to zero. + * + * @method Phaser.Physics.Arcade.Body#stop + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + stop: function () + { + this.velocity.set(0); + this.acceleration.set(0); + this.speed = 0; + this.angularVelocity = 0; + this.angularAcceleration = 0; + + return this; + }, + + /** + * Copies the coordinates of this Body's edges into an object. + * + * @method Phaser.Physics.Arcade.Body#getBounds + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into. + * + * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}. + */ + getBounds: function (obj) + { + obj.x = this.x; + obj.y = this.y; + obj.right = this.right; + obj.bottom = this.bottom; + + return obj; + }, + + /** + * Tests if the coordinates are within this Body. + * + * @method Phaser.Physics.Arcade.Body#hitTest + * @since 3.0.0 + * + * @param {number} x - The horizontal coordinate. + * @param {number} y - The vertical coordinate. + * + * @return {boolean} True if (x, y) is within this Body. + */ + hitTest: function (x, y) + { + if (!this.isCircle) + { + return RectangleContains(this, x, y); + } + + // Check if x/y are within the bounds first + if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) + { + var dx = (this.center.x - x) * (this.center.x - x); + var dy = (this.center.y - y) * (this.center.y - y); + + return (dx + dy) <= (this.radius * this.radius); + } + + return false; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving down. + * + * @method Phaser.Physics.Arcade.Body#onFloor + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onFloor: function () + { + return this.blocked.down; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving up. + * + * @method Phaser.Physics.Arcade.Body#onCeiling + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onCeiling: function () + { + return this.blocked.up; + }, + + /** + * Whether this Body is touching a tile or the world boundary while moving left or right. + * + * @method Phaser.Physics.Arcade.Body#onWall + * @since 3.0.0 + * @see Phaser.Physics.Arcade.Body#blocked + * + * @return {boolean} True if touching. + */ + onWall: function () + { + return (this.blocked.left || this.blocked.right); + }, + + /** + * The absolute (non-negative) change in this Body's horizontal position from the previous step. + * + * @method Phaser.Physics.Arcade.Body#deltaAbsX + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaAbsX: function () + { + return (this._dx > 0) ? this._dx : -this._dx; + }, + + /** + * The absolute (non-negative) change in this Body's vertical position from the previous step. + * + * @method Phaser.Physics.Arcade.Body#deltaAbsY + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaAbsY: function () + { + return (this._dy > 0) ? this._dy : -this._dy; + }, + + /** + * The change in this Body's horizontal position from the previous step. + * This value is set during the Body's update phase. + * + * As a Body can update multiple times per step this may not hold the final + * delta value for the Body. In this case, please see the `deltaXFinal` method. + * + * @method Phaser.Physics.Arcade.Body#deltaX + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaX: function () + { + return this._dx; + }, + + /** + * The change in this Body's vertical position from the previous step. + * This value is set during the Body's update phase. + * + * As a Body can update multiple times per step this may not hold the final + * delta value for the Body. In this case, please see the `deltaYFinal` method. + * + * @method Phaser.Physics.Arcade.Body#deltaY + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaY: function () + { + return this._dy; + }, + + /** + * The change in this Body's horizontal position from the previous game update. + * + * This value is set during the `postUpdate` phase and takes into account the + * `deltaMax` and final position of the Body. + * + * Because this value is not calculated until `postUpdate`, you must listen for it + * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will + * not be calculated by that point. If you _do_ use these values in `update` they + * will represent the delta from the _previous_ game frame. + * + * @method Phaser.Physics.Arcade.Body#deltaXFinal + * @since 3.22.0 + * + * @return {number} The final delta x value. + */ + deltaXFinal: function () + { + return this._tx; + }, + + /** + * The change in this Body's vertical position from the previous game update. + * + * This value is set during the `postUpdate` phase and takes into account the + * `deltaMax` and final position of the Body. + * + * Because this value is not calculated until `postUpdate`, you must listen for it + * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will + * not be calculated by that point. If you _do_ use these values in `update` they + * will represent the delta from the _previous_ game frame. + * + * @method Phaser.Physics.Arcade.Body#deltaYFinal + * @since 3.22.0 + * + * @return {number} The final delta y value. + */ + deltaYFinal: function () + { + return this._ty; + }, + + /** + * The change in this Body's rotation from the previous step, in degrees. + * + * @method Phaser.Physics.Arcade.Body#deltaZ + * @since 3.0.0 + * + * @return {number} The delta value. + */ + deltaZ: function () + { + return this.rotation - this.preRotation; + }, + + /** + * Disables this Body and marks it for deletion by the simulation. + * + * @method Phaser.Physics.Arcade.Body#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enable = false; + + if (this.world) + { + this.world.pendingDestroy.set(this); + } + }, + + /** + * Draws this Body and its velocity, if enabled. + * + * @method Phaser.Physics.Arcade.Body#drawDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to draw on. + */ + drawDebug: function (graphic) + { + var pos = this.position; + + var x = pos.x + this.halfWidth; + var y = pos.y + this.halfHeight; + + if (this.debugShowBody) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor); + + if (this.isCircle) + { + graphic.strokeCircle(x, y, this.width / 2); + } + else + { + // Only draw the sides where checkCollision is true, similar to debugger in layer + if (this.checkCollision.up) + { + graphic.lineBetween(pos.x, pos.y, pos.x + this.width, pos.y); + } + + if (this.checkCollision.right) + { + graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); + } + + if (this.checkCollision.down) + { + graphic.lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height); + } + + if (this.checkCollision.left) + { + graphic.lineBetween(pos.x, pos.y, pos.x, pos.y + this.height); + } + } + } + + if (this.debugShowVelocity) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.world.defaults.velocityDebugColor, 1); + graphic.lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2); + } + }, + + /** + * Whether this Body will be drawn to the debug display. + * + * @method Phaser.Physics.Arcade.Body#willDrawDebug + * @since 3.0.0 + * + * @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled. + */ + willDrawDebug: function () + { + return (this.debugShowBody || this.debugShowVelocity); + }, + + /** + * Sets whether this Body collides with the world boundary. + * + * Optionally also sets the World Bounce and `onWorldBounds` values. + * + * @method Phaser.Physics.Arcade.Body#setCollideWorldBounds + * @since 3.0.0 + * + * @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`. + * @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value. + * @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value. + * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setCollideWorldBounds: function (value, bounceX, bounceY, onWorldBounds) + { + if (value === undefined) { value = true; } + + this.collideWorldBounds = value; + + var setBounceX = (bounceX !== undefined); + var setBounceY = (bounceY !== undefined); + + if (setBounceX || setBounceY) + { + if (!this.worldBounce) + { + this.worldBounce = new Vector2(); + } + + if (setBounceX) + { + this.worldBounce.x = bounceX; + } + + if (setBounceY) + { + this.worldBounce.y = bounceY; + } + } + + if (onWorldBounds !== undefined) + { + this.onWorldBounds = onWorldBounds; + } + + return this; + }, + + /** + * Sets the Body's velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocity + * @since 3.0.0 + * + * @param {number} x - The horizontal velocity, in pixels per second. + * @param {number} [y=x] - The vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocity: function (x, y) + { + this.velocity.set(x, y); + + x = this.velocity.x; + y = this.velocity.y; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's horizontal velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocityX + * @since 3.0.0 + * + * @param {number} value - The velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocityX: function (value) + { + this.velocity.x = value; + + var x = value; + var y = this.velocity.y; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's vertical velocity. + * + * @method Phaser.Physics.Arcade.Body#setVelocityY + * @since 3.0.0 + * + * @param {number} value - The velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setVelocityY: function (value) + { + this.velocity.y = value; + + var x = this.velocity.x; + var y = value; + + this.speed = Math.sqrt(x * x + y * y); + + return this; + }, + + /** + * Sets the Body's maximum velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocity + * @since 3.10.0 + * + * @param {number} x - The horizontal velocity, in pixels per second. + * @param {number} [y=x] - The vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocity: function (x, y) + { + this.maxVelocity.set(x, y); + + return this; + }, + + /** + * Sets the Body's maximum horizontal velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocityX + * @since 3.50.0 + * + * @param {number} value - The maximum horizontal velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocityX: function (value) + { + this.maxVelocity.x = value; + + return this; + }, + + /** + * Sets the Body's maximum vertical velocity. + * + * @method Phaser.Physics.Arcade.Body#setMaxVelocityY + * @since 3.50.0 + * + * @param {number} value - The maximum vertical velocity, in pixels per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxVelocityY: function (value) + { + this.maxVelocity.y = value; + + return this; + }, + + /** + * Sets the maximum speed the Body can move. + * + * @method Phaser.Physics.Arcade.Body#setMaxSpeed + * @since 3.16.0 + * + * @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMaxSpeed: function (value) + { + this.maxSpeed = value; + + return this; + }, + + /** + * Sets the Body's bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounce + * @since 3.0.0 + * + * @param {number} x - The horizontal bounce, relative to 1. + * @param {number} y - The vertical bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounce: function (x, y) + { + this.bounce.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounceX + * @since 3.0.0 + * + * @param {number} value - The bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounceX: function (value) + { + this.bounce.x = value; + + return this; + }, + + /** + * Sets the Body's vertical bounce. + * + * @method Phaser.Physics.Arcade.Body#setBounceY + * @since 3.0.0 + * + * @param {number} value - The bounce, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setBounceY: function (value) + { + this.bounce.y = value; + + return this; + }, + + /** + * Sets the Body's acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAcceleration + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAcceleration: function (x, y) + { + this.acceleration.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAccelerationX + * @since 3.0.0 + * + * @param {number} value - The acceleration, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAccelerationX: function (value) + { + this.acceleration.x = value; + + return this; + }, + + /** + * Sets the Body's vertical acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAccelerationY + * @since 3.0.0 + * + * @param {number} value - The acceleration, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAccelerationY: function (value) + { + this.acceleration.y = value; + + return this; + }, + + /** + * Enables or disables drag. + * + * @method Phaser.Physics.Arcade.Body#setAllowDrag + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowDrag + * + * @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowDrag: function (value) + { + if (value === undefined) { value = true; } + + this.allowDrag = value; + + return this; + }, + + /** + * Enables or disables gravity's effect on this Body. + * + * @method Phaser.Physics.Arcade.Body#setAllowGravity + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowGravity + * + * @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowGravity: function (value) + { + if (value === undefined) { value = true; } + + this.allowGravity = value; + + return this; + }, + + /** + * Enables or disables rotation. + * + * @method Phaser.Physics.Arcade.Body#setAllowRotation + * @since 3.9.0 + * @see Phaser.Physics.Arcade.Body#allowRotation + * + * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAllowRotation: function (value) + { + if (value === undefined) { value = true; } + + this.allowRotation = value; + + return this; + }, + + /** + * Sets the Body's drag. + * + * @method Phaser.Physics.Arcade.Body#setDrag + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDrag: function (x, y) + { + this.drag.set(x, y); + + return this; + }, + + /** + * If this Body is using `drag` for deceleration this property controls how the drag is applied. + * If set to `true` drag will use a damping effect rather than a linear approach. If you are + * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in + * the game Asteroids) then you will get a far smoother and more visually correct deceleration + * by using damping, avoiding the axis-drift that is prone with linear deceleration. + * + * If you enable this property then you should use far smaller `drag` values than with linear, as + * they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow + * deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately. + * + * @method Phaser.Physics.Arcade.Body#setDamping + * @since 3.50.0 + * + * @param {boolean} value - `true` to use damping, or `false` to use drag. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDamping: function (value) + { + this.useDamping = value; + + return this; + }, + + /** + * Sets the Body's horizontal drag. + * + * @method Phaser.Physics.Arcade.Body#setDragX + * @since 3.0.0 + * + * @param {number} value - The drag, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDragX: function (value) + { + this.drag.x = value; + + return this; + }, + + /** + * Sets the Body's vertical drag. + * + * @method Phaser.Physics.Arcade.Body#setDragY + * @since 3.0.0 + * + * @param {number} value - The drag, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setDragY: function (value) + { + this.drag.y = value; + + return this; + }, + + /** + * Sets the Body's gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravity + * @since 3.0.0 + * + * @param {number} x - The horizontal component, in pixels per second squared. + * @param {number} y - The vertical component, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravity: function (x, y) + { + this.gravity.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravityX + * @since 3.0.0 + * + * @param {number} value - The gravity, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravityX: function (value) + { + this.gravity.x = value; + + return this; + }, + + /** + * Sets the Body's vertical gravity. + * + * @method Phaser.Physics.Arcade.Body#setGravityY + * @since 3.0.0 + * + * @param {number} value - The gravity, in pixels per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGravityY: function (value) + { + this.gravity.y = value; + + return this; + }, + + /** + * Sets the Body's friction. + * + * @method Phaser.Physics.Arcade.Body#setFriction + * @since 3.0.0 + * + * @param {number} x - The horizontal component, relative to 1. + * @param {number} y - The vertical component, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFriction: function (x, y) + { + this.friction.set(x, y); + + return this; + }, + + /** + * Sets the Body's horizontal friction. + * + * @method Phaser.Physics.Arcade.Body#setFrictionX + * @since 3.0.0 + * + * @param {number} value - The friction value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFrictionX: function (value) + { + this.friction.x = value; + + return this; + }, + + /** + * Sets the Body's vertical friction. + * + * @method Phaser.Physics.Arcade.Body#setFrictionY + * @since 3.0.0 + * + * @param {number} value - The friction value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setFrictionY: function (value) + { + this.friction.y = value; + + return this; + }, + + /** + * Sets the Body's angular velocity. + * + * @method Phaser.Physics.Arcade.Body#setAngularVelocity + * @since 3.0.0 + * + * @param {number} value - The velocity, in degrees per second. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularVelocity: function (value) + { + this.angularVelocity = value; + + return this; + }, + + /** + * Sets the Body's angular acceleration. + * + * @method Phaser.Physics.Arcade.Body#setAngularAcceleration + * @since 3.0.0 + * + * @param {number} value - The acceleration, in degrees per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularAcceleration: function (value) + { + this.angularAcceleration = value; + + return this; + }, + + /** + * Sets the Body's angular drag. + * + * @method Phaser.Physics.Arcade.Body#setAngularDrag + * @since 3.0.0 + * + * @param {number} value - The drag, in degrees per second squared. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setAngularDrag: function (value) + { + this.angularDrag = value; + + return this; + }, + + /** + * Sets the Body's mass. + * + * @method Phaser.Physics.Arcade.Body#setMass + * @since 3.0.0 + * + * @param {number} value - The mass value, relative to 1. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setMass: function (value) + { + this.mass = value; + + return this; + }, + + /** + * Sets the Body's `immovable` property. + * + * @method Phaser.Physics.Arcade.Body#setImmovable + * @since 3.0.0 + * + * @param {boolean} [value=true] - The value to assign to `immovable`. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setImmovable: function (value) + { + if (value === undefined) { value = true; } + + this.immovable = value; + + return this; + }, + + /** + * Sets the Body's `enable` property. + * + * @method Phaser.Physics.Arcade.Body#setEnable + * @since 3.15.0 + * + * @param {boolean} [value=true] - The value to assign to `enable`. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setEnable: function (value) + { + if (value === undefined) { value = true; } + + this.enable = value; + + return this; + }, + + /** + * This is an internal handler, called by the `ProcessX` function as part + * of the collision step. You should almost never call this directly. + * + * @method Phaser.Physics.Arcade.Body#processX + * @since 3.50.0 + * + * @param {number} x - The amount to add to the Body position. + * @param {number} [vx] - The amount to add to the Body velocity. + * @param {boolean} [left] - Set the blocked.left value? + * @param {boolean} [right] - Set the blocked.right value? + */ + processX: function (x, vx, left, right) + { + this.x += x; + + this.updateCenter(); + + if (vx !== null) + { + this.velocity.x = vx; + } + + var blocked = this.blocked; + + if (left) + { + blocked.left = true; + } + + if (right) + { + blocked.right = true; + } + }, + + /** + * This is an internal handler, called by the `ProcessY` function as part + * of the collision step. You should almost never call this directly. + * + * @method Phaser.Physics.Arcade.Body#processY + * @since 3.50.0 + * + * @param {number} y - The amount to add to the Body position. + * @param {number} [vy] - The amount to add to the Body velocity. + * @param {boolean} [up] - Set the blocked.up value? + * @param {boolean} [down] - Set the blocked.down value? + */ + processY: function (y, vy, up, down) + { + this.y += y; + + this.updateCenter(); + + if (vy !== null) + { + this.velocity.y = vy; + } + + var blocked = this.blocked; + + if (up) + { + blocked.up = true; + } + + if (down) + { + blocked.down = true; + } + }, + + /** + * The Bodys horizontal position (left edge). + * + * @name Phaser.Physics.Arcade.Body#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.position.x = value; + } + + }, + + /** + * The Bodys vertical position (top edge). + * + * @name Phaser.Physics.Arcade.Body#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.position.y = value; + } + + }, + + /** + * The left edge of the Body. Identical to x. + * + * @name Phaser.Physics.Arcade.Body#left + * @type {number} + * @readonly + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.position.x; + } + + }, + + /** + * The right edge of the Body. + * + * @name Phaser.Physics.Arcade.Body#right + * @type {number} + * @readonly + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.position.x + this.width; + } + + }, + + /** + * The top edge of the Body. Identical to y. + * + * @name Phaser.Physics.Arcade.Body#top + * @type {number} + * @readonly + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.position.y; + } + + }, + + /** + * The bottom edge of this Body. + * + * @name Phaser.Physics.Arcade.Body#bottom + * @type {number} + * @readonly + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.position.y + this.height; + } + + } + +}); + +module.exports = Body; + + +/***/ }), +/* 522 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects + * every step. If a collision, or overlap, occurs it will invoke the given callbacks. + * + * @class Collider + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade physics World that will manage the collisions. + * @param {boolean} overlapOnly - Whether to check for collisions or overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision. + * @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision. + * @param {ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean. + * @param {any} callbackContext - The scope in which to call the callbacks. + */ +var Collider = new Class({ + + initialize: + + function Collider (world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) + { + /** + * The world in which the bodies will collide. + * + * @name Phaser.Physics.Arcade.Collider#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The name of the collider (unused by Phaser). + * + * @name Phaser.Physics.Arcade.Collider#name + * @type {string} + * @since 3.1.0 + */ + this.name = ''; + + /** + * Whether the collider is active. + * + * @name Phaser.Physics.Arcade.Collider#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * Whether to check for collisions or overlaps. + * + * @name Phaser.Physics.Arcade.Collider#overlapOnly + * @type {boolean} + * @since 3.0.0 + */ + this.overlapOnly = overlapOnly; + + /** + * The first object to check for collision. + * + * @name Phaser.Physics.Arcade.Collider#object1 + * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} + * @since 3.0.0 + */ + this.object1 = object1; + + /** + * The second object to check for collision. + * + * @name Phaser.Physics.Arcade.Collider#object2 + * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} + * @since 3.0.0 + */ + this.object2 = object2; + + /** + * The callback to invoke when the two objects collide. + * + * @name Phaser.Physics.Arcade.Collider#collideCallback + * @type {ArcadePhysicsCallback} + * @since 3.0.0 + */ + this.collideCallback = collideCallback; + + /** + * If a processCallback exists it must return true or collision checking will be skipped. + * + * @name Phaser.Physics.Arcade.Collider#processCallback + * @type {ArcadePhysicsCallback} + * @since 3.0.0 + */ + this.processCallback = processCallback; + + /** + * The context the collideCallback and processCallback will run in. + * + * @name Phaser.Physics.Arcade.Collider#callbackContext + * @type {object} + * @since 3.0.0 + */ + this.callbackContext = callbackContext; + }, + + /** + * A name for the Collider. + * + * Phaser does not use this value, it's for your own reference. + * + * @method Phaser.Physics.Arcade.Collider#setName + * @since 3.1.0 + * + * @param {string} name - The name to assign to the Collider. + * + * @return {Phaser.Physics.Arcade.Collider} This Collider instance. + */ + setName: function (name) + { + this.name = name; + + return this; + }, + + /** + * Called by World as part of its step processing, initial operation of collision checking. + * + * @method Phaser.Physics.Arcade.Collider#update + * @since 3.0.0 + */ + update: function () + { + this.world.collideObjects( + this.object1, + this.object2, + this.collideCallback, + this.processCallback, + this.callbackContext, + this.overlapOnly + ); + }, + + /** + * Removes Collider from World and disposes of its resources. + * + * @method Phaser.Physics.Arcade.Collider#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.world.removeCollider(this); + + this.active = false; + + this.world = null; + + this.object1 = null; + this.object2 = null; + + this.collideCallback = null; + this.processCallback = null; + this.callbackContext = null; + } + +}); + +module.exports = Collider; + + +/***/ }), +/* 523 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(26); +var Vector2 = __webpack_require__(3); + +var pointStart = new Vector2(); +var pointEnd = new Vector2(); + +/** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * @function Phaser.Tilemaps.Components.GetTilesWithinWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} filteringOptions - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when factoring in which tiles to return. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. + */ +var GetTilesWithinWorldXY = function (worldX, worldY, width, height, filteringOptions, camera, layer) +{ + var worldToTileXY = layer.tilemapLayer.tilemap._convert.WorldToTileXY; + + // Top left corner of the rect, rounded down to include partial tiles + worldToTileXY(worldX, worldY, true, pointStart, camera, layer); + + var xStart = pointStart.x; + var yStart = pointStart.y; + + // Bottom right corner of the rect, rounded up to include partial tiles + worldToTileXY(worldX + width, worldY + height, false, pointEnd, camera, layer); + + var xEnd = Math.ceil(pointEnd.x); + var yEnd = Math.ceil(pointEnd.y); + + return GetTilesWithin(xStart, yStart, xEnd - xStart, yEnd - yStart, filteringOptions, layer); +}; + +module.exports = GetTilesWithinWorldXY; + + +/***/ }), +/* 524 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A function to process the collision callbacks between a single tile and an Arcade Physics enabled Game Object. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileCallbacks + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.Tile} tile - The Tile to process. + * @param {Phaser.GameObjects.Sprite} sprite - The Game Object to process with the Tile. + * + * @return {boolean} The result of the callback, `true` for further processing, or `false` to skip this pair. + */ +var ProcessTileCallbacks = function (tile, sprite) +{ + // Tile callbacks take priority over layer level callbacks + if (tile.collisionCallback) + { + return !tile.collisionCallback.call(tile.collisionCallbackContext, sprite, tile); + } + else if (tile.layer.callbacks[tile.index]) + { + return !tile.layer.callbacks[tile.index].callback.call( + tile.layer.callbacks[tile.index].callbackContext, sprite, tile + ); + } + + return true; +}; + +module.exports = ProcessTileCallbacks; + + +/***/ }), +/* 525 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Vladimir Agafonkin + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var quickselect = __webpack_require__(430); + +/** + * @classdesc + * RBush is a high-performance JavaScript library for 2D spatial indexing of points and rectangles. + * It's based on an optimized R-tree data structure with bulk insertion support. + * + * Spatial index is a special data structure for points and rectangles that allows you to perform queries like + * "all items within this bounding box" very efficiently (e.g. hundreds of times faster than looping over all items). + * + * This version of RBush uses a fixed min/max accessor structure of `[ '.left', '.top', '.right', '.bottom' ]`. + * This is to avoid the eval like function creation that the original library used, which caused CSP policy violations. + * + * rbush is forked from https://github.com/mourner/rbush by Vladimir Agafonkin + * + * @class RTree + * @memberof Phaser.Structs + * @constructor + * @since 3.0.0 + */ + +function rbush (maxEntries) +{ + var format = [ '.left', '.top', '.right', '.bottom' ]; + + if (!(this instanceof rbush)) return new rbush(maxEntries, format); + + // max entries in a node is 9 by default; min node fill is 40% for best performance + this._maxEntries = Math.max(4, maxEntries || 9); + this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); + + this.clear(); +} + +rbush.prototype = { + + all: function () + { + return this._all(this.data, []); + }, + + search: function (bbox) + { + var node = this.data, + result = [], + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return result; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf) result.push(child); + else if (contains(bbox, childBBox)) this._all(child, result); + else nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return result; + }, + + collides: function (bbox) + { + var node = this.data, + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return false; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf || contains(bbox, childBBox)) return true; + nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return false; + }, + + load: function (data) + { + if (!(data && data.length)) return this; + + if (data.length < this._minEntries) { + for (var i = 0, len = data.length; i < len; i++) { + this.insert(data[i]); + } + return this; + } + + // recursively build the tree with the given data from scratch using OMT algorithm + var node = this._build(data.slice(), 0, data.length - 1, 0); + + if (!this.data.children.length) { + // save as is if tree is empty + this.data = node; + + } else if (this.data.height === node.height) { + // split root if trees have the same height + this._splitRoot(this.data, node); + + } else { + if (this.data.height < node.height) { + // swap trees if inserted one is bigger + var tmpNode = this.data; + this.data = node; + node = tmpNode; + } + + // insert the small tree into the large tree at appropriate level + this._insert(node, this.data.height - node.height - 1, true); + } + + return this; + }, + + insert: function (item) + { + if (item) this._insert(item, this.data.height - 1); + return this; + }, + + clear: function () + { + this.data = createNode([]); + return this; + }, + + remove: function (item, equalsFn) + { + if (!item) return this; + + var node = this.data, + bbox = this.toBBox(item), + path = [], + indexes = [], + i, parent, index, goingUp; + + // depth-first iterative tree traversal + while (node || path.length) { + + if (!node) { // go up + node = path.pop(); + parent = path[path.length - 1]; + i = indexes.pop(); + goingUp = true; + } + + if (node.leaf) { // check current node + index = findItem(item, node.children, equalsFn); + + if (index !== -1) { + // item found, remove the item and condense tree upwards + node.children.splice(index, 1); + path.push(node); + this._condense(path); + return this; + } + } + + if (!goingUp && !node.leaf && contains(node, bbox)) { // go down + path.push(node); + indexes.push(i); + i = 0; + parent = node; + node = node.children[0]; + + } else if (parent) { // go right + i++; + node = parent.children[i]; + goingUp = false; + + } else node = null; // nothing found + } + + return this; + }, + + toBBox: function (item) { return item; }, + + compareMinX: compareNodeMinX, + compareMinY: compareNodeMinY, + + toJSON: function () { return this.data; }, + + fromJSON: function (data) + { + this.data = data; + return this; + }, + + _all: function (node, result) + { + var nodesToSearch = []; + while (node) { + if (node.leaf) result.push.apply(result, node.children); + else nodesToSearch.push.apply(nodesToSearch, node.children); + + node = nodesToSearch.pop(); + } + return result; + }, + + _build: function (items, left, right, height) + { + var N = right - left + 1, + M = this._maxEntries, + node; + + if (N <= M) { + // reached leaf level; return leaf + node = createNode(items.slice(left, right + 1)); + calcBBox(node, this.toBBox); + return node; + } + + if (!height) { + // target height of the bulk-loaded tree + height = Math.ceil(Math.log(N) / Math.log(M)); + + // target number of root entries to maximize storage utilization + M = Math.ceil(N / Math.pow(M, height - 1)); + } + + node = createNode([]); + node.leaf = false; + node.height = height; + + // split the items into M mostly square tiles + + var N2 = Math.ceil(N / M), + N1 = N2 * Math.ceil(Math.sqrt(M)), + i, j, right2, right3; + + multiSelect(items, left, right, N1, this.compareMinX); + + for (i = left; i <= right; i += N1) { + + right2 = Math.min(i + N1 - 1, right); + + multiSelect(items, i, right2, N2, this.compareMinY); + + for (j = i; j <= right2; j += N2) { + + right3 = Math.min(j + N2 - 1, right2); + + // pack each entry recursively + node.children.push(this._build(items, j, right3, height - 1)); + } + } + + calcBBox(node, this.toBBox); + + return node; + }, + + _chooseSubtree: function (bbox, node, level, path) + { + var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; + + while (true) { + path.push(node); + + if (node.leaf || path.length - 1 === level) break; + + minArea = minEnlargement = Infinity; + + for (i = 0, len = node.children.length; i < len; i++) { + child = node.children[i]; + area = bboxArea(child); + enlargement = enlargedArea(bbox, child) - area; + + // choose entry with the least area enlargement + if (enlargement < minEnlargement) { + minEnlargement = enlargement; + minArea = area < minArea ? area : minArea; + targetNode = child; + + } else if (enlargement === minEnlargement) { + // otherwise choose one with the smallest area + if (area < minArea) { + minArea = area; + targetNode = child; + } + } + } + + node = targetNode || node.children[0]; + } + + return node; + }, + + _insert: function (item, level, isNode) + { + var toBBox = this.toBBox, + bbox = isNode ? item : toBBox(item), + insertPath = []; + + // find the best node for accommodating the item, saving all nodes along the path too + var node = this._chooseSubtree(bbox, this.data, level, insertPath); + + // put the item into the node + node.children.push(item); + extend(node, bbox); + + // split on node overflow; propagate upwards if necessary + while (level >= 0) { + if (insertPath[level].children.length > this._maxEntries) { + this._split(insertPath, level); + level--; + } else break; + } + + // adjust bboxes along the insertion path + this._adjustParentBBoxes(bbox, insertPath, level); + }, + + // split overflowed node into two + _split: function (insertPath, level) + { + var node = insertPath[level], + M = node.children.length, + m = this._minEntries; + + this._chooseSplitAxis(node, m, M); + + var splitIndex = this._chooseSplitIndex(node, m, M); + + var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); + newNode.height = node.height; + newNode.leaf = node.leaf; + + calcBBox(node, this.toBBox); + calcBBox(newNode, this.toBBox); + + if (level) insertPath[level - 1].children.push(newNode); + else this._splitRoot(node, newNode); + }, + + _splitRoot: function (node, newNode) + { + // split root node + this.data = createNode([node, newNode]); + this.data.height = node.height + 1; + this.data.leaf = false; + calcBBox(this.data, this.toBBox); + }, + + _chooseSplitIndex: function (node, m, M) + { + var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; + + minOverlap = minArea = Infinity; + + for (i = m; i <= M - m; i++) { + bbox1 = distBBox(node, 0, i, this.toBBox); + bbox2 = distBBox(node, i, M, this.toBBox); + + overlap = intersectionArea(bbox1, bbox2); + area = bboxArea(bbox1) + bboxArea(bbox2); + + // choose distribution with minimum overlap + if (overlap < minOverlap) { + minOverlap = overlap; + index = i; + + minArea = area < minArea ? area : minArea; + + } else if (overlap === minOverlap) { + // otherwise choose distribution with minimum area + if (area < minArea) { + minArea = area; + index = i; + } + } + } + + return index; + }, + + // sorts node children by the best axis for split + _chooseSplitAxis: function (node, m, M) + { + var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, + compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, + xMargin = this._allDistMargin(node, m, M, compareMinX), + yMargin = this._allDistMargin(node, m, M, compareMinY); + + // if total distributions margin value is minimal for x, sort by minX, + // otherwise it's already sorted by minY + if (xMargin < yMargin) node.children.sort(compareMinX); + }, + + // total margin of all possible split distributions where each node is at least m full + _allDistMargin: function (node, m, M, compare) + { + node.children.sort(compare); + + var toBBox = this.toBBox, + leftBBox = distBBox(node, 0, m, toBBox), + rightBBox = distBBox(node, M - m, M, toBBox), + margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), + i, child; + + for (i = m; i < M - m; i++) { + child = node.children[i]; + extend(leftBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(leftBBox); + } + + for (i = M - m - 1; i >= m; i--) { + child = node.children[i]; + extend(rightBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(rightBBox); + } + + return margin; + }, + + _adjustParentBBoxes: function (bbox, path, level) + { + // adjust bboxes along the given tree path + for (var i = level; i >= 0; i--) { + extend(path[i], bbox); + } + }, + + _condense: function (path) + { + // go through the path, removing empty nodes and updating bboxes + for (var i = path.length - 1, siblings; i >= 0; i--) { + if (path[i].children.length === 0) { + if (i > 0) { + siblings = path[i - 1].children; + siblings.splice(siblings.indexOf(path[i]), 1); + + } else this.clear(); + + } else calcBBox(path[i], this.toBBox); + } + }, + + compareMinX: function (a, b) + { + return a.left - b.left; + }, + + compareMinY: function (a, b) + { + return a.top - b.top; + }, + + toBBox: function (a) + { + return { + minX: a.left, + minY: a.top, + maxX: a.right, + maxY: a.bottom + }; + } +}; + +function findItem (item, items, equalsFn) +{ + if (!equalsFn) return items.indexOf(item); + + for (var i = 0; i < items.length; i++) { + if (equalsFn(item, items[i])) return i; + } + return -1; +} + +// calculate node's bbox from bboxes of its children +function calcBBox (node, toBBox) +{ + distBBox(node, 0, node.children.length, toBBox, node); +} + +// min bounding rectangle of node children from k to p-1 +function distBBox (node, k, p, toBBox, destNode) +{ + if (!destNode) destNode = createNode(null); + destNode.minX = Infinity; + destNode.minY = Infinity; + destNode.maxX = -Infinity; + destNode.maxY = -Infinity; + + for (var i = k, child; i < p; i++) { + child = node.children[i]; + extend(destNode, node.leaf ? toBBox(child) : child); + } + + return destNode; +} + +function extend (a, b) +{ + a.minX = Math.min(a.minX, b.minX); + a.minY = Math.min(a.minY, b.minY); + a.maxX = Math.max(a.maxX, b.maxX); + a.maxY = Math.max(a.maxY, b.maxY); + return a; +} + +function compareNodeMinX (a, b) { return a.minX - b.minX; } +function compareNodeMinY (a, b) { return a.minY - b.minY; } + +function bboxArea (a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } +function bboxMargin (a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } + +function enlargedArea (a, b) +{ + return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * + (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); +} + +function intersectionArea (a, b) +{ + var minX = Math.max(a.minX, b.minX), + minY = Math.max(a.minY, b.minY), + maxX = Math.min(a.maxX, b.maxX), + maxY = Math.min(a.maxY, b.maxY); + + return Math.max(0, maxX - minX) * + Math.max(0, maxY - minY); +} + +function contains (a, b) +{ + return a.minX <= b.minX && + a.minY <= b.minY && + b.maxX <= a.maxX && + b.maxY <= a.maxY; +} + +function intersects (a, b) +{ + return b.minX <= a.maxX && + b.minY <= a.maxY && + b.maxX >= a.minX && + b.maxY >= a.minY; +} + +function createNode (children) +{ + return { + children: children, + height: 1, + leaf: true, + minX: Infinity, + minY: Infinity, + maxX: -Infinity, + maxY: -Infinity + }; +} + +// sort an array so that items come in groups of n unsorted items, with groups sorted between each other; +// combines selection algorithm with binary divide & conquer approach + +function multiSelect (arr, left, right, n, compare) +{ + var stack = [left, right], + mid; + + while (stack.length) + { + right = stack.pop(); + left = stack.pop(); + + if (right - left <= n) continue; + + mid = left + Math.ceil((right - left) / n / 2) * n; + quickselect(arr, mid, left, right, compare); + + stack.push(left, mid, mid, right); + } +} + +module.exports = rbush; + +/***/ }), +/* 526 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TileCheckX = __webpack_require__(527); +var TileCheckY = __webpack_require__(529); +var TileIntersectsBody = __webpack_require__(245); + +/** + * The core separation function to separate a physics body and a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.SeparateTile + * @since 3.0.0 + * + * @param {number} i - The index of the tile within the map data. + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to collide against. + * @param {Phaser.Geom.Rectangle} tileWorldRect - A rectangle-like object defining the dimensions of the tile. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The tilemapLayer to collide against. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {boolean} `true` if the body was separated, otherwise `false`. + */ +var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) +{ + var tileLeft = tileWorldRect.left; + var tileTop = tileWorldRect.top; + var tileRight = tileWorldRect.right; + var tileBottom = tileWorldRect.bottom; + var faceHorizontal = tile.faceLeft || tile.faceRight; + var faceVertical = tile.faceTop || tile.faceBottom; + + if (!isLayer) + { + faceHorizontal = true; + faceVertical = true; + } + + // We don't need to go any further if this tile doesn't actually have any colliding faces. This + // could happen if the tile was meant to be collided with re: a callback, but otherwise isn't + // needed for separation. + if (!faceHorizontal && !faceVertical) + { + return false; + } + + var ox = 0; + var oy = 0; + var minX = 0; + var minY = 1; + + if (body.deltaAbsX() > body.deltaAbsY()) + { + // Moving faster horizontally, check X axis first + minX = -1; + } + else if (body.deltaAbsX() < body.deltaAbsY()) + { + // Moving faster vertically, check Y axis first + minY = -1; + } + + if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical) + { + // We only need do this if both axes have colliding faces AND we're moving in both + // directions + minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft)); + minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop)); + } + + if (minX < minY) + { + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); + + // That's horizontal done, check if we still intersects? If not then we can return now + if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } + + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + } + } + else + { + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + + // That's vertical done, check if we still intersects? If not then we can return now + if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } + + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); + } + } + + return (ox !== 0 || oy !== 0); +}; + +module.exports = SeparateTile; + + +/***/ }), +/* 527 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ProcessTileSeparationX = __webpack_require__(528); + +/** + * Check the body against the given tile on the X axis. + * Used internally by the SeparateTile function. + * + * @function Phaser.Physics.Arcade.Tilemap.TileCheckX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to check. + * @param {number} tileLeft - The left position of the tile within the tile world. + * @param {number} tileRight - The right position of the tile within the tile world. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {number} The amount of separation that occurred. + */ +var TileCheckX = function (body, tile, tileLeft, tileRight, tileBias, isLayer) +{ + var ox = 0; + + var faceLeft = tile.faceLeft; + var faceRight = tile.faceRight; + var collideLeft = tile.collideLeft; + var collideRight = tile.collideRight; + + if (!isLayer) + { + faceLeft = true; + faceRight = true; + collideLeft = true; + collideRight = true; + } + + if (body.deltaX() < 0 && collideRight && body.checkCollision.left) + { + // Body is moving LEFT + if (faceRight && body.x < tileRight) + { + ox = body.x - tileRight; + + if (ox < -tileBias) + { + ox = 0; + } + } + } + else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) + { + // Body is moving RIGHT + if (faceLeft && body.right > tileLeft) + { + ox = body.right - tileLeft; + + if (ox > tileBias) + { + ox = 0; + } + } + } + + if (ox !== 0) + { + if (body.customSeparateX) + { + body.overlapX = ox; + } + else + { + ProcessTileSeparationX(body, ox); + } + } + + return ox; +}; + +module.exports = TileCheckX; + + +/***/ }), +/* 528 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Internal function to process the separation of a physics body from a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} x - The x separation amount. + */ +var ProcessTileSeparationX = function (body, x) +{ + if (x < 0) + { + body.blocked.none = false; + body.blocked.left = true; + } + else if (x > 0) + { + body.blocked.none = false; + body.blocked.right = true; + } + + body.position.x -= x; + + if (body.bounce.x === 0) + { + body.velocity.x = 0; + } + else + { + body.velocity.x = -body.velocity.x * body.bounce.x; + } +}; + +module.exports = ProcessTileSeparationX; + + +/***/ }), +/* 529 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ProcessTileSeparationY = __webpack_require__(530); + +/** + * Check the body against the given tile on the Y axis. + * Used internally by the SeparateTile function. + * + * @function Phaser.Physics.Arcade.Tilemap.TileCheckY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {Phaser.Tilemaps.Tile} tile - The tile to check. + * @param {number} tileTop - The top position of the tile within the tile world. + * @param {number} tileBottom - The bottom position of the tile within the tile world. + * @param {number} tileBias - The tile bias value. Populated by the `World.TILE_BIAS` constant. + * @param {boolean} isLayer - Is this check coming from a TilemapLayer or an array of tiles? + * + * @return {number} The amount of separation that occurred. + */ +var TileCheckY = function (body, tile, tileTop, tileBottom, tileBias, isLayer) +{ + var oy = 0; + + var faceTop = tile.faceTop; + var faceBottom = tile.faceBottom; + var collideUp = tile.collideUp; + var collideDown = tile.collideDown; + + if (!isLayer) + { + faceTop = true; + faceBottom = true; + collideUp = true; + collideDown = true; + } + + if (body.deltaY() < 0 && collideDown && body.checkCollision.up) + { + // Body is moving UP + if (faceBottom && body.y < tileBottom) + { + oy = body.y - tileBottom; + + if (oy < -tileBias) + { + oy = 0; + } + } + } + else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) + { + // Body is moving DOWN + if (faceTop && body.bottom > tileTop) + { + oy = body.bottom - tileTop; + + if (oy > tileBias) + { + oy = 0; + } + } + } + + if (oy !== 0) + { + if (body.customSeparateY) + { + body.overlapY = oy; + } + else + { + ProcessTileSeparationY(body, oy); + } + } + + return oy; +}; + +module.exports = TileCheckY; + + +/***/ }), +/* 530 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Internal function to process the separation of a physics body from a tile. + * + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} y - The y separation amount. + */ +var ProcessTileSeparationY = function (body, y) +{ + if (y < 0) + { + body.blocked.none = false; + body.blocked.up = true; + } + else if (y > 0) + { + body.blocked.none = false; + body.blocked.down = true; + } + + body.position.y -= y; + + if (body.bounce.y === 0) + { + body.velocity.y = 0; + } + else + { + body.velocity.y = -body.velocity.y * body.bounce.y; + } +}; + +module.exports = ProcessTileSeparationY; + + +/***/ }), +/* 531 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetOverlapX = __webpack_require__(243); +var ProcessX = __webpack_require__(1383); + +/** + * Separates two overlapping bodies on the X-axis (horizontally). + * + * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. + * + * The bodies won't be separated if there is no horizontal overlap between them, if they are static, or if either one uses custom logic for its separation. + * + * @function Phaser.Physics.Arcade.SeparateX + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. + * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. + * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateX = function (body1, body2, overlapOnly, bias) +{ + var overlap = GetOverlapX(body1, body2, overlapOnly, bias); + + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateX || body2.customSeparateX) + { + // return true if there was some overlap, otherwise false + return (overlap !== 0) || (body1.embedded && body2.embedded); + } + + var blockedState = ProcessX.Set(body1, body2, overlap); + + if (!body1Immovable && !body2Immovable) + { + if (blockedState > 0) + { + return true; + } + + return ProcessX.Check(); + } + else if (body1Immovable) + { + ProcessX.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessX.RunImmovableBody2(blockedState); + } + + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; + +module.exports = SeparateX; + + +/***/ }), +/* 532 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetOverlapY = __webpack_require__(244); +var ProcessY = __webpack_require__(1384); + +/** + * Separates two overlapping bodies on the Y-axis (vertically). + * + * Separation involves moving two overlapping bodies so they don't overlap anymore and adjusting their velocities based on their mass. This is a core part of collision detection. + * + * The bodies won't be separated if there is no vertical overlap between them, if they are static, or if either one uses custom logic for its separation. + * + * @function Phaser.Physics.Arcade.SeparateY + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} body2 - The second Body to separate. + * @param {boolean} overlapOnly - If `true`, the bodies will only have their overlap data set and no separation will take place. + * @param {number} bias - A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateY = function (body1, body2, overlapOnly, bias) +{ + var overlap = GetOverlapY(body1, body2, overlapOnly, bias); + + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; + + // Can't separate two immovable bodies, or a body with its own custom separation logic + if (overlapOnly || overlap === 0 || (body1Immovable && body2Immovable) || body1.customSeparateY || body2.customSeparateY) + { + // return true if there was some overlap, otherwise false + return (overlap !== 0) || (body1.embedded && body2.embedded); + } + + var blockedState = ProcessY.Set(body1, body2, overlap); + + if (!body1Immovable && !body2Immovable) + { + if (blockedState > 0) + { + return true; + } + + return ProcessY.Check(); + } + else if (body1Immovable) + { + ProcessY.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessY.RunImmovableBody2(blockedState); + } + + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; + +module.exports = SeparateY; + + +/***/ }), +/* 533 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircleContains = __webpack_require__(63); +var Class = __webpack_require__(0); +var CONST = __webpack_require__(60); +var RectangleContains = __webpack_require__(56); +var Vector2 = __webpack_require__(3); + +/** + * @classdesc + * A Static Arcade Physics Body. + * + * A Static Body never moves, and isn't automatically synchronized with its parent Game Object. + * That means if you make any change to the parent's origin, position, or scale after creating or adding the body, you'll need to update the Static Body manually. + * + * A Static Body can collide with other Bodies, but is never moved by collisions. + * + * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Body}. + * + * @class StaticBody + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics simulation this Static Body belongs to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Static Body belongs to. + */ +var StaticBody = new Class({ + + initialize: + + function StaticBody (world, gameObject) + { + var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; + var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; + + /** + * The Arcade Physics simulation this Static Body belongs to. + * + * @name Phaser.Physics.Arcade.StaticBody#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * The Game Object this Static Body belongs to. + * + * @name Phaser.Physics.Arcade.StaticBody#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = gameObject; + + /** + * Whether the Static Body's boundary is drawn to the debug display. + * + * @name Phaser.Physics.Arcade.StaticBody#debugShowBody + * @type {boolean} + * @since 3.0.0 + */ + this.debugShowBody = world.defaults.debugShowStaticBody; + + /** + * The color of this Static Body on the debug display. + * + * @name Phaser.Physics.Arcade.StaticBody#debugBodyColor + * @type {number} + * @since 3.0.0 + */ + this.debugBodyColor = world.defaults.staticBodyDebugColor; + + /** + * Whether this Static Body is updated by the physics simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#enable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.enable = true; + + /** + * Whether this Static Body's boundary is circular (`true`) or rectangular (`false`). + * + * @name Phaser.Physics.Arcade.StaticBody#isCircle + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.isCircle = false; + + /** + * If this Static Body is circular, this is the radius of the boundary, as set by {@link Phaser.Physics.Arcade.StaticBody#setCircle}, in pixels. + * Equal to `halfWidth`. + * + * @name Phaser.Physics.Arcade.StaticBody#radius + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.radius = 0; + + /** + * The offset set by {@link Phaser.Physics.Arcade.StaticBody#setCircle} or {@link Phaser.Physics.Arcade.StaticBody#setSize}. + * + * This doesn't affect the Static Body's position, because a Static Body does not follow its Game Object. + * + * @name Phaser.Physics.Arcade.StaticBody#offset + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.offset = new Vector2(); + + /** + * The position of this Static Body within the simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#position + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.position = new Vector2(gameObject.x - (width * gameObject.originX), gameObject.y - (height * gameObject.originY)); + + /** + * The width of the Static Body's boundary, in pixels. + * If the Static Body is circular, this is also the Static Body's diameter. + * + * @name Phaser.Physics.Arcade.StaticBody#width + * @type {number} + * @since 3.0.0 + */ + this.width = width; + + /** + * The height of the Static Body's boundary, in pixels. + * If the Static Body is circular, this is also the Static Body's diameter. + * + * @name Phaser.Physics.Arcade.StaticBody#height + * @type {number} + * @since 3.0.0 + */ + this.height = height; + + /** + * Half the Static Body's width, in pixels. + * If the Static Body is circular, this is also the Static Body's radius. + * + * @name Phaser.Physics.Arcade.StaticBody#halfWidth + * @type {number} + * @since 3.0.0 + */ + this.halfWidth = Math.abs(this.width / 2); + + /** + * Half the Static Body's height, in pixels. + * If the Static Body is circular, this is also the Static Body's radius. + * + * @name Phaser.Physics.Arcade.StaticBody#halfHeight + * @type {number} + * @since 3.0.0 + */ + this.halfHeight = Math.abs(this.height / 2); + + /** + * The center of the Static Body's boundary. + * This is the midpoint of its `position` (top-left corner) and its bottom-right corner. + * + * @name Phaser.Physics.Arcade.StaticBody#center + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + /** + * A constant zero velocity used by the Arcade Physics simulation for calculations. + * + * @name Phaser.Physics.Arcade.StaticBody#velocity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.velocity = Vector2.ZERO; + + /** + * A constant `false` value expected by the Arcade Physics simulation. + * + * @name Phaser.Physics.Arcade.StaticBody#allowGravity + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.allowGravity = false; + + /** + * Gravitational force applied specifically to this Body. Values are in pixels per second squared. Always zero for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#gravity + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.gravity = Vector2.ZERO; + + /** + * Rebound, or restitution, following a collision, relative to 1. Always zero for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#bounce + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.0.0 + */ + this.bounce = Vector2.ZERO; + + // If true this Body will dispatch events + + /** + * Whether the simulation emits a `worldbounds` event when this StaticBody collides with the world boundary. + * Always false for a Static Body. (Static Bodies never collide with the world boundary and never trigger a `worldbounds` event.) + * + * @name Phaser.Physics.Arcade.StaticBody#onWorldBounds + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.onWorldBounds = false; + + /** + * Whether the simulation emits a `collide` event when this StaticBody collides with another. + * + * @name Phaser.Physics.Arcade.StaticBody#onCollide + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.onCollide = false; + + /** + * Whether the simulation emits an `overlap` event when this StaticBody overlaps with another. + * + * @name Phaser.Physics.Arcade.StaticBody#onOverlap + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.onOverlap = false; + + /** + * The StaticBody's inertia, relative to a default unit (1). With `bounce`, this affects the exchange of momentum (velocities) during collisions. + * + * @name Phaser.Physics.Arcade.StaticBody#mass + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.mass = 1; + + /** + * Whether this object can be moved by collisions with another body. + * + * @name Phaser.Physics.Arcade.StaticBody#immovable + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.immovable = true; + + /** + * Sets if this Body can be pushed by another Body. + * + * A body that cannot be pushed will reflect back all of the velocity it is given to the + * colliding body. If that body is also not pushable, then the separation will be split + * between them evenly. + * + * If you want your body to never move or seperate at all, see the `setImmovable` method. + * + * By default, Static Bodies are not pushable. + * + * @name Phaser.Physics.Arcade.StaticBody#pushable + * @type {boolean} + * @default false + * @since 3.50.0 + * @see Phaser.GameObjects.Components.Pushable#setPushable + */ + this.pushable = false; + + /** + * A flag disabling the default horizontal separation of colliding bodies. Pass your own `collideHandler` to the collider. + * + * @name Phaser.Physics.Arcade.StaticBody#customSeparateX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateX = false; + + /** + * A flag disabling the default vertical separation of colliding bodies. Pass your own `collideHandler` to the collider. + * + * @name Phaser.Physics.Arcade.StaticBody#customSeparateY + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customSeparateY = false; + + /** + * The amount of horizontal overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapX = 0; + + /** + * The amount of vertical overlap (before separation), if this Body is colliding with another. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapY = 0; + + /** + * The amount of overlap (before separation), if this StaticBody is circular and colliding with another circular body. + * + * @name Phaser.Physics.Arcade.StaticBody#overlapR + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.overlapR = 0; + + /** + * Whether this StaticBody has ever overlapped with another while both were not moving. + * + * @name Phaser.Physics.Arcade.StaticBody#embedded + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.embedded = false; + + /** + * Whether this StaticBody interacts with the world boundary. + * Always false for a Static Body. (Static Bodies never collide with the world boundary.) + * + * @name Phaser.Physics.Arcade.StaticBody#collideWorldBounds + * @type {boolean} + * @readonly + * @default false + * @since 3.0.0 + */ + this.collideWorldBounds = false; + + /** + * Whether this StaticBody is checked for collisions and for which directions. You can set `checkCollision.none = false` to disable collision checks. + * + * @name Phaser.Physics.Arcade.StaticBody#checkCollision + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * + * @name Phaser.Physics.Arcade.StaticBody#touching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.touching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * The values are always false for a Static Body. + * + * @name Phaser.Physics.Arcade.StaticBody#wasTouching + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This property is kept for compatibility with Dynamic Bodies. + * Avoid using it. + * + * @name Phaser.Physics.Arcade.StaticBody#blocked + * @type {Phaser.Types.Physics.Arcade.ArcadeBodyCollision} + * @since 3.0.0 + */ + this.blocked = { none: true, up: false, down: false, left: false, right: false }; + + /** + * The StaticBody's physics type (static by default). + * + * @name Phaser.Physics.Arcade.StaticBody#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.STATIC_BODY + * @since 3.0.0 + */ + this.physicsType = CONST.STATIC_BODY; + + /** + * The calculated change in the Static Body's horizontal position during the current step. + * For a static body this is always zero. + * + * @name Phaser.Physics.Arcade.StaticBody#_dx + * @type {number} + * @private + * @default 0 + * @since 3.10.0 + */ + this._dx = 0; + + /** + * The calculated change in the Static Body's vertical position during the current step. + * For a static body this is always zero. + * + * @name Phaser.Physics.Arcade.StaticBody#_dy + * @type {number} + * @private + * @default 0 + * @since 3.10.0 + */ + this._dy = 0; + }, + + /** + * Changes the Game Object this Body is bound to. + * First it removes its reference from the old Game Object, then sets the new one. + * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#setGameObject + * @since 3.1.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. + * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * + * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject + */ + setGameObject: function (gameObject, update) + { + if (gameObject && gameObject !== this.gameObject) + { + // Remove this body from the old game object + this.gameObject.body = null; + + gameObject.body = this; + + // Update our reference + this.gameObject = gameObject; + } + + if (update) + { + this.updateFromGameObject(); + } + + return this; + }, + + /** + * Syncs the Static Body's position and size with its parent Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject + * @since 3.1.0 + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + updateFromGameObject: function () + { + this.world.staticTree.remove(this); + + var gameObject = this.gameObject; + + gameObject.getTopLeft(this.position); + + this.width = gameObject.displayWidth; + this.height = gameObject.displayHeight; + + this.halfWidth = Math.abs(this.width / 2); + this.halfHeight = Math.abs(this.height / 2); + + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Positions the Static Body at an offset from its Game Object. + * + * @method Phaser.Physics.Arcade.StaticBody#setOffset + * @since 3.4.0 + * + * @param {number} x - The horizontal offset of the Static Body from the Game Object's `x`. + * @param {number} y - The vertical offset of the Static Body from the Game Object's `y`. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setOffset: function (x, y) + { + if (y === undefined) { y = x; } + + this.world.staticTree.remove(this); + + this.position.x -= this.offset.x; + this.position.y -= this.offset.y; + + this.offset.set(x, y); + + this.position.x += this.offset.x; + this.position.y += this.offset.y; + + this.updateCenter(); + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Sets the size of the Static Body. + * When `center` is true, also repositions it. + * Resets the width and height to match current frame, if no width and height provided and a frame is found. + * + * @method Phaser.Physics.Arcade.StaticBody#setSize + * @since 3.0.0 + * + * @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. + * @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. + * @param {boolean} [center=true] - Place the Static Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setSize: function (width, height, center) + { + if (center === undefined) { center = true; } + + var gameObject = this.gameObject; + + if (!width && gameObject.frame) + { + width = gameObject.frame.realWidth; + } + + if (!height && gameObject.frame) + { + height = gameObject.frame.realHeight; + } + + this.world.staticTree.remove(this); + + this.width = width; + this.height = height; + + this.halfWidth = Math.floor(width / 2); + this.halfHeight = Math.floor(height / 2); + + if (center && gameObject.getCenter) + { + var ox = gameObject.displayWidth / 2; + var oy = gameObject.displayHeight / 2; + + this.position.x -= this.offset.x; + this.position.y -= this.offset.y; + + this.offset.set(ox - this.halfWidth, oy - this.halfHeight); + + this.position.x += this.offset.x; + this.position.y += this.offset.y; + } + + this.updateCenter(); + + this.isCircle = false; + this.radius = 0; + + this.world.staticTree.insert(this); + + return this; + }, + + /** + * Sets this Static Body to have a circular body and sets its size and position. + * + * @method Phaser.Physics.Arcade.StaticBody#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the StaticBody, in pixels. + * @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels. + * @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setCircle: function (radius, offsetX, offsetY) + { + if (offsetX === undefined) { offsetX = this.offset.x; } + if (offsetY === undefined) { offsetY = this.offset.y; } + + if (radius > 0) + { + this.world.staticTree.remove(this); + + this.isCircle = true; + + this.radius = radius; + + this.width = radius * 2; + this.height = radius * 2; + + this.halfWidth = Math.floor(this.width / 2); + this.halfHeight = Math.floor(this.height / 2); + + this.offset.set(offsetX, offsetY); + + this.updateCenter(); + + this.world.staticTree.insert(this); + } + else + { + this.isCircle = false; + } + + return this; + }, + + /** + * Updates the StaticBody's `center` from its `position` and dimensions. + * + * @method Phaser.Physics.Arcade.StaticBody#updateCenter + * @since 3.0.0 + */ + updateCenter: function () + { + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + }, + + /** + * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. + * + * @method Phaser.Physics.Arcade.StaticBody#reset + * @since 3.0.0 + * + * @param {number} [x] - The x coordinate to reset the body to. If not given will use the parent Game Object's coordinate. + * @param {number} [y] - The y coordinate to reset the body to. If not given will use the parent Game Object's coordinate. + */ + reset: function (x, y) + { + var gameObject = this.gameObject; + + if (x === undefined) { x = gameObject.x; } + if (y === undefined) { y = gameObject.y; } + + this.world.staticTree.remove(this); + + gameObject.setPosition(x, y); + + gameObject.getTopLeft(this.position); + + this.updateCenter(); + + this.world.staticTree.insert(this); + }, + + /** + * NOOP function. A Static Body cannot be stopped. + * + * @method Phaser.Physics.Arcade.StaticBody#stop + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + stop: function () + { + return this; + }, + + /** + * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. + * + * @method Phaser.Physics.Arcade.StaticBody#getBounds + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. + * + * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody. + */ + getBounds: function (obj) + { + obj.x = this.x; + obj.y = this.y; + obj.right = this.right; + obj.bottom = this.bottom; + + return obj; + }, + + /** + * Checks to see if a given x,y coordinate is colliding with this Static Body. + * + * @method Phaser.Physics.Arcade.StaticBody#hitTest + * @since 3.0.0 + * + * @param {number} x - The x coordinate to check against this body. + * @param {number} y - The y coordinate to check against this body. + * + * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. + */ + hitTest: function (x, y) + { + return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); + }, + + /** + * NOOP + * + * @method Phaser.Physics.Arcade.StaticBody#postUpdate + * @since 3.12.0 + */ + postUpdate: function () + { + }, + + /** + * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX + * @since 3.0.0 + * + * @return {number} Always zero for a Static Body. + */ + deltaAbsX: function () + { + return 0; + }, + + /** + * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY + * @since 3.0.0 + * + * @return {number} Always zero for a Static Body. + */ + deltaAbsY: function () + { + return 0; + }, + + /** + * The change in this StaticBody's horizontal position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaX + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + */ + deltaX: function () + { + return 0; + }, + + /** + * The change in this StaticBody's vertical position from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaY + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + */ + deltaY: function () + { + return 0; + }, + + /** + * The change in this StaticBody's rotation from the previous step. Always zero. + * + * @method Phaser.Physics.Arcade.StaticBody#deltaZ + * @since 3.0.0 + * + * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. + */ + deltaZ: function () + { + return 0; + }, + + /** + * Disables this Body and marks it for destruction during the next step. + * + * @method Phaser.Physics.Arcade.StaticBody#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.enable = false; + + this.world.pendingDestroy.set(this); + }, + + /** + * Draws a graphical representation of the StaticBody for visual debugging purposes. + * + * @method Phaser.Physics.Arcade.StaticBody#drawDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. + */ + drawDebug: function (graphic) + { + var pos = this.position; + + var x = pos.x + this.halfWidth; + var y = pos.y + this.halfHeight; + + if (this.debugShowBody) + { + graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor, 1); + + if (this.isCircle) + { + graphic.strokeCircle(x, y, this.width / 2); + } + else + { + graphic.strokeRect(pos.x, pos.y, this.width, this.height); + } + + } + }, + + /** + * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. + * + * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug + * @since 3.0.0 + * + * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. + */ + willDrawDebug: function () + { + return this.debugShowBody; + }, + + /** + * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. + * + * @method Phaser.Physics.Arcade.StaticBody#setMass + * @since 3.0.0 + * + * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. + * + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + */ + setMass: function (value) + { + if (value <= 0) + { + // Causes havoc otherwise + value = 0.1; + } + + this.mass = value; + + return this; + }, + + /** + * The x coordinate of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#x + * @type {number} + * @since 3.0.0 + */ + x: { + + get: function () + { + return this.position.x; + }, + + set: function (value) + { + this.world.staticTree.remove(this); + + this.position.x = value; + + this.world.staticTree.insert(this); + } + + }, + + /** + * The y coordinate of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#y + * @type {number} + * @since 3.0.0 + */ + y: { + + get: function () + { + return this.position.y; + }, + + set: function (value) + { + this.world.staticTree.remove(this); + + this.position.y = value; + + this.world.staticTree.insert(this); + } + + }, + + /** + * Returns the left-most x coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#left + * @type {number} + * @readonly + * @since 3.0.0 + */ + left: { + + get: function () + { + return this.position.x; + } + + }, + + /** + * The right-most x coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#right + * @type {number} + * @readonly + * @since 3.0.0 + */ + right: { + + get: function () + { + return this.position.x + this.width; + } + + }, + + /** + * The highest y coordinate of the area of the StaticBody. + * + * @name Phaser.Physics.Arcade.StaticBody#top + * @type {number} + * @readonly + * @since 3.0.0 + */ + top: { + + get: function () + { + return this.position.y; + } + + }, + + /** + * The lowest y coordinate of the area of the StaticBody. (y + height) + * + * @name Phaser.Physics.Arcade.StaticBody#bottom + * @type {number} + * @readonly + * @since 3.0.0 + */ + bottom: { + + get: function () + { + return this.position.y + this.height; + } + + } + +}); + +module.exports = StaticBody; + + +/***/ }), +/* 534 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Physics.Matter.Components + */ + +module.exports = { + + Bounce: __webpack_require__(1500), + Collision: __webpack_require__(1501), + Force: __webpack_require__(1502), + Friction: __webpack_require__(1503), + Gravity: __webpack_require__(1504), + Mass: __webpack_require__(1505), + Sensor: __webpack_require__(1506), + SetBody: __webpack_require__(1507), + Sleep: __webpack_require__(1508), + Static: __webpack_require__(1525), + Transform: __webpack_require__(1526), + Velocity: __webpack_require__(1527) + +}; + + +/***/ }), +/* 535 */ +/***/ (function(module, exports) { + +/** +* The `Matter.Pair` module contains methods for creating and manipulating collision pairs. +* +* @class Pair +*/ + +var Pair = {}; + +module.exports = Pair; + +(function() { + + /** + * Creates a pair. + * @method create + * @param {collision} collision + * @param {number} timestamp + * @return {pair} A new pair + */ + Pair.create = function(collision, timestamp) { + var bodyA = collision.bodyA, + bodyB = collision.bodyB; + + var pair = { + id: Pair.id(bodyA, bodyB), + bodyA: bodyA, + bodyB: bodyB, + activeContacts: [], + separation: 0, + isActive: true, + confirmedActive: true, + isSensor: bodyA.isSensor || bodyB.isSensor, + timeCreated: timestamp, + timeUpdated: timestamp, + collision: null, + inverseMass: 0, + friction: 0, + frictionStatic: 0, + restitution: 0, + slop: 0 + }; + + Pair.update(pair, collision, timestamp); + + return pair; + }; + + /** + * Updates a pair given a collision. + * @method update + * @param {pair} pair + * @param {collision} collision + * @param {number} timestamp + */ + Pair.update = function(pair, collision, timestamp) { + pair.collision = collision; + + if (collision.collided) { + var supports = collision.supports, + activeContacts = pair.activeContacts, + parentA = collision.parentA, + parentB = collision.parentB; + + pair.inverseMass = parentA.inverseMass + parentB.inverseMass; + pair.friction = Math.min(parentA.friction, parentB.friction); + pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic); + pair.restitution = Math.max(parentA.restitution, parentB.restitution); + pair.slop = Math.max(parentA.slop, parentB.slop); + + for (var i = 0; i < supports.length; i++) { + activeContacts[i] = supports[i].contact; + } + + // optimise array size + var supportCount = supports.length; + if (supportCount < activeContacts.length) { + activeContacts.length = supportCount; + } + + pair.separation = collision.depth; + Pair.setActive(pair, true, timestamp); + } else { + if (pair.isActive === true) + Pair.setActive(pair, false, timestamp); + } + }; + + /** + * Set a pair as active or inactive. + * @method setActive + * @param {pair} pair + * @param {bool} isActive + * @param {number} timestamp + */ + Pair.setActive = function(pair, isActive, timestamp) { + if (isActive) { + pair.isActive = true; + pair.timeUpdated = timestamp; + } else { + pair.isActive = false; + pair.activeContacts.length = 0; + } + }; + + /** + * Get the id for the given pair. + * @method id + * @param {body} bodyA + * @param {body} bodyB + * @return {string} Unique pairId + */ + Pair.id = function(bodyA, bodyB) { + if (bodyA.id < bodyB.id) { + return 'A' + bodyA.id + 'B' + bodyB.id; + } else { + return 'A' + bodyB.id + 'B' + bodyA.id; + } + }; + +})(); + + +/***/ }), +/* 536 */ +/***/ (function(module, exports, __webpack_require__) { + +/** +* @author Richard Davey +* @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; + + +/***/ }), +/* 537 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +var point = new Vector2(); + +/** + * Checks if the given tile coordinate is within the isometric layer bounds, or not. + * + * @function Phaser.Tilemaps.Components.CheckIsoBounds + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to check against. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. + * + * @return {boolean} Returns `true` if the coordinates are within the iso bounds. + */ +var CheckIsoBounds = function (tileX, tileY, layer, camera) +{ + var tilemapLayer = layer.tilemapLayer; + + var cullPaddingX = tilemapLayer.cullPaddingX; + var cullPaddingY = tilemapLayer.cullPaddingY; + + var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer); + + // we always subtract 1/2 of the tile's height/width to make the culling distance start from the center of the tiles. + return pos.x > camera.worldView.x + tilemapLayer.scaleX * layer.tileWidth * (-cullPaddingX - 0.5) + && pos.x < camera.worldView.right + tilemapLayer.scaleX * layer.tileWidth * (cullPaddingX - 0.5) + && pos.y > camera.worldView.y + tilemapLayer.scaleY * layer.tileHeight * (-cullPaddingY - 1.0) + && pos.y < camera.worldView.bottom + tilemapLayer.scaleY * layer.tileHeight * (cullPaddingY - 0.5); +}; + +module.exports = CheckIsoBounds; + + +/***/ }), +/* 538 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(26); + +/** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * @function Phaser.Tilemaps.Components.ReplaceByIndex + * @since 3.0.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var ReplaceByIndex = function (findIndex, newIndex, tileX, tileY, width, height, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) + { + if (tiles[i] && tiles[i].index === findIndex) + { + tiles[i].index = newIndex; + } + } +}; + +module.exports = ReplaceByIndex; + + +/***/ }), +/* 539 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(10); +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +var bounds = new Rectangle(); + +/** + * Returns the bounds in the given orthogonal layer that are within the cameras viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.CullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {Phaser.Geom.Rectangle} A rectangle containing the culled bounds. If you wish to retain this object, clone it, as it's recycled internally. + */ +var CullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY; + + return bounds.setTo( + boundsLeft, + boundsTop, + (boundsRight - boundsLeft), + (boundsBottom - boundsTop) + ); +}; + +module.exports = CullBounds; + + +/***/ }), +/* 540 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(539); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.CullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var CullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + var bounds = CullBounds(layer, camera); + + if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) + { + bounds.left = 0; + bounds.right = layer.width; + bounds.top = 0; + bounds.bottom = layer.height; + } + + RunCull(layer, bounds, renderOrder, outputArray); + + return outputArray; +}; + +module.exports = CullTiles; + + +/***/ }), +/* 541 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(542); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.HexagonalCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var HexagonalCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + { + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + + var bounds = CullBounds(layer, camera); + + RunCull(layer, bounds, renderOrder, outputArray); + } + + return outputArray; +}; + +module.exports = HexagonalCullTiles; + + +/***/ }), +/* 542 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +/** + * Returns the bounds in the given layer that are within the camera's viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.HexagonalCullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + */ +var HexagonalCullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var len = layer.hexSideLength; + var rowH = ((tileH - len) / 2 + len); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY; + + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; + +module.exports = HexagonalCullBounds; + + +/***/ }), +/* 543 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CheckIsoBounds = __webpack_require__(537); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.IsometricCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + + var drawLeft = 0; + var drawRight = mapWidth; + var drawTop = 0; + var drawBottom = mapHeight; + + if (!tilemapLayer.skipCull) + { + var x; + var y; + var tile; + + if (renderOrder === 0) + { + // right-down + + for (y = drawTop; y < drawBottom; y++) + { + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 1) + { + // left-down + + for (y = drawTop; y < drawBottom; y++) + { + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 2) + { + // right-up + + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + else if (renderOrder === 3) + { + // left-up + + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + if (CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + } + } + + tilemapLayer.tilesDrawn = outputArray.length; + tilemapLayer.tilesTotal = mapWidth * mapHeight; + + return outputArray; +}; + +module.exports = IsometricCullTiles; + + +/***/ }), +/* 544 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(545); +var RunCull = __webpack_require__(157); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.StaggeredCullTiles + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * @param {array} [outputArray] - An optional array to store the Tile objects within. + * @param {number} [renderOrder=0] - The rendering order constant. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var StaggeredCullTiles = function (layer, camera, outputArray, renderOrder) +{ + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } + + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + { + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels + + var bounds = CullBounds(layer, camera); + + RunCull(layer, bounds, renderOrder, outputArray); + } + + return outputArray; +}; + +module.exports = StaggeredCullTiles; + + +/***/ }), +/* 545 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SnapCeil = __webpack_require__(137); +var SnapFloor = __webpack_require__(76); + +/** + * Returns the bounds in the given layer that are within the camera's viewport. + * This is used internally by the cull tiles function. + * + * @function Phaser.Tilemaps.Components.StaggeredCullBounds + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to run the cull check against. + * + * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + */ +var StaggeredCullBounds = function (layer, camera) +{ + var tilemap = layer.tilemapLayer.tilemap; + var tilemapLayer = layer.tilemapLayer; + + // We need to use the tile sizes defined for the map as a whole, not the layer, + // in order to calculate the bounds correctly. As different sized tiles may be + // placed on the grid and we cannot trust layer.baseTileWidth to give us the true size. + var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX); + var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY); + + var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH / 2, 0, true) - tilemapLayer.cullPaddingY; + var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH / 2, 0, true) + tilemapLayer.cullPaddingY; + + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; + +module.exports = StaggeredCullBounds; + + +/***/ }), +/* 546 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from hexagonal tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.HexagonalTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = layer.hexSideLength; + var rowHeight = ((tileHeight - len) / 2 + len); + + // similar to staggered, because Tiled uses the oddr representation. + var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); + var y = layerWorldY + tileY * rowHeight; + + return point.set(x, y); +}; + +module.exports = HexagonalTileToWorldXY; + + +/***/ }), +/* 547 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from isometric tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.IsometricTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var IsometricTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); + var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); + + return point.set(x, y); +}; + +module.exports = IsometricTileToWorldXY; + + +/***/ }), +/* 548 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from staggered tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.StaggeredTileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var StaggeredTileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + var layerWorldX = 0; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); + var y = layerWorldY + tileY * (tileHeight / 2); + + return point.set(x, y); +}; + +module.exports = StaggeredTileToWorldXY; + + +/***/ }), +/* 549 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TileToWorldX = __webpack_require__(249); +var TileToWorldY = __webpack_require__(250); +var Vector2 = __webpack_require__(3); + +/** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.TileToWorldXY + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in world coordinates. + */ +var TileToWorldXY = function (tileX, tileY, point, camera, layer) +{ + if (!point) { point = new Vector2(0, 0); } + + point.x = TileToWorldX(tileX, camera, layer); + point.y = TileToWorldY(tileY, camera, layer); + + return point; +}; + +module.exports = TileToWorldXY; + + +/***/ }), +/* 550 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from hexagonal tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layer's position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.HexagonalTileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in world coordinates. + */ +var HexagonalTileToWorldY = function (tileY, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = tilemapLayer.tilemap.hexSideLength; + + var rowHeight = ((tileHeight - len) / 2 + len); + + return layerWorldY + tileY * rowHeight; +}; + +module.exports = HexagonalTileToWorldY; + + +/***/ }), +/* 551 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from staggered tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.StaggeredTileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in world coordinates. + */ +var StaggeredTileToWorldY = function (tileY, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + var layerWorldY = 0; + + if (tilemapLayer) + { + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + return layerWorldY + tileY * (tileHeight / 2); +}; + +module.exports = StaggeredTileToWorldY; + + +/***/ }), +/* 552 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinates down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + var len = layer.hexSideLength; + var rowHeight = ((tileHeight - len) / 2 + len); + + // similar to staggered, because Tiled uses the oddr representation. + var y = (snapToFloor) ? Math.floor((worldY / rowHeight)) : (worldY / rowHeight); + var x = (snapToFloor) ? Math.floor((worldX - (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX - (y % 2) * 0.5 * tileWidth) / tileWidth; + + return point.set(x, y); +}; + +module.exports = HexagonalWorldToTileXY; + + +/***/ }), +/* 553 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to isometric tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.IsometricWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var IsometricWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + worldX -= tileWidth / 2; + + var x = (snapToFloor) ? Math.floor((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2) : ((worldX / (tileWidth / 2) + worldY / (tileHeight / 2)) / 2); + var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2) : ((worldY / (tileHeight / 2) - worldX / (tileWidth / 2)) / 2); + + return point.set(x, y); +}; + +module.exports = IsometricWorldToTileXY; + + +/***/ }), +/* 554 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to staggered tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.StaggeredWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var StaggeredWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + var y = (snapToFloor) ? Math.floor((worldY / (tileHeight / 2))) : (worldY / (tileHeight / 2)); + var x = (snapToFloor) ? Math.floor((worldX + (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX + (y % 2) * 0.5 * tileWidth) / tileWidth; + + return point.set(x, y); +}; + +module.exports = StaggeredWorldToTileXY; + + +/***/ }), +/* 555 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WorldToTileX = __webpack_require__(251); +var WorldToTileY = __webpack_require__(252); +var Vector2 = __webpack_require__(3); + +/** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.WorldToTileXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} point - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var WorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (snapToFloor === undefined) { snapToFloor = true; } + if (!point) { point = new Vector2(0, 0); } + + point.x = WorldToTileX(worldX, snapToFloor, camera, layer); + point.y = WorldToTileY(worldY, snapToFloor, camera, layer); + + return point; +}; + +module.exports = WorldToTileXY; + + +/***/ }), +/* 556 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from world Y coordinates (pixels) to hexagonal tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in tile units. + */ +var HexagonalWorldToTileY = function (worldY, snapToFloor, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + var len = layer.hexSideLength; + + var rowHeight = ((tileHeight - len) / 2 + len); + + return (snapToFloor) ? Math.floor(worldY / rowHeight) : worldY / rowHeight; +}; + +module.exports = HexagonalWorldToTileY; + + +/***/ }), +/* 557 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from world Y coordinates (pixels) to staggered tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.StaggeredWorldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} snapToFloor - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} The Y location in tile units. + */ +var StaggeredWorldToTileY = function (worldY, snapToFloor, camera, layer) +{ + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + } + + return (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); +}; + +module.exports = StaggeredWorldToTileY; + + +/***/ }), +/* 558 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var IsInLayerBounds = __webpack_require__(118); + +/** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @function Phaser.Tilemaps.Components.HasTileAt + * @since 3.0.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ +var HasTileAt = function (tileX, tileY, layer) +{ + if (IsInLayerBounds(tileX, tileY, layer)) + { + var tile = layer.data[tileY][tileX]; + + return (tile !== null && tile.index > -1); + } + else + { + return false; + } +}; + +module.exports = HasTileAt; + + +/***/ }), +/* 559 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tile = __webpack_require__(83); +var IsInLayerBounds = __webpack_require__(118); +var CalculateFacesAt = __webpack_require__(248); + +/** + * Removes the tile at the given tile coordinates in the specified layer and updates the layer's + * collision information. + * + * @function Phaser.Tilemaps.Components.RemoveTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate. + * @param {number} tileY - The y coordinate. + * @param {boolean} replaceWithNull - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} recalculateFaces - `true` if the faces data should be recalculated. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was removed. + */ +var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) +{ + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + if (!IsInLayerBounds(tileX, tileY, layer)) + { + return null; + } + + var tile = layer.data[tileY][tileX]; + + if (!tile) + { + return null; + } + else + { + layer.data[tileY][tileX] = (replaceWithNull) ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight); + } + + // Recalculate faces only if the removed tile was a colliding tile + if (recalculateFaces && tile && tile.collides) + { + CalculateFacesAt(tileX, tileY, layer); + } + + return tile; +}; + +module.exports = RemoveTileAt; + + +/***/ }), +/* 560 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var Parse2DArray = __webpack_require__(255); +var ParseCSV = __webpack_require__(561); +var ParseJSONTiled = __webpack_require__(562); +var ParseWeltmeister = __webpack_require__(573); + +/** + * Parses raw data of a given Tilemap format into a new MapData object. If no recognized data format + * is found, returns `null`. When loading from CSV or a 2D array, you should specify the tileWidth & + * tileHeight. When parsing from a map from Tiled, the tileWidth & tileHeight will be pulled from + * the map data. + * + * @function Phaser.Tilemaps.Parsers.Parse + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {number} mapFormat - See ../Formats.js. + * @param {(number[][]|string|object)} data - 2D array, CSV string or Tiled JSON object. + * @param {number} tileWidth - The width of a tile in pixels. Required for 2D array and CSV, but + * ignored for Tiled JSON. + * @param {number} tileHeight - The height of a tile in pixels. Required for 2D array and CSV, but + * ignored for Tiled JSON. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {Phaser.Tilemaps.MapData} The created `MapData` object. + */ +var Parse = function (name, mapFormat, data, tileWidth, tileHeight, insertNull) +{ + var newMap; + + switch (mapFormat) + { + case (Formats.ARRAY_2D): + newMap = Parse2DArray(name, data, tileWidth, tileHeight, insertNull); + break; + case (Formats.CSV): + newMap = ParseCSV(name, data, tileWidth, tileHeight, insertNull); + break; + case (Formats.TILED_JSON): + newMap = ParseJSONTiled(name, data, insertNull); + break; + case (Formats.WELTMEISTER): + newMap = ParseWeltmeister(name, data, insertNull); + break; + default: + console.warn('Unrecognized tilemap data format: ' + mapFormat); + newMap = null; + } + + return newMap; +}; + +module.exports = Parse; + + +/***/ }), +/* 561 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var Parse2DArray = __webpack_require__(255); + +/** + * Parses a CSV string of tile indexes into a new MapData object with a single layer. + * + * @function Phaser.Tilemaps.Parsers.ParseCSV + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {string} data - CSV string of tile indexes. + * @param {number} tileWidth - The width of a tile in pixels. + * @param {number} tileHeight - The height of a tile in pixels. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {Phaser.Tilemaps.MapData} The resulting MapData object. + */ +var ParseCSV = function (name, data, tileWidth, tileHeight, insertNull) +{ + var array2D = data + .trim() + .split('\n') + .map(function (row) { return row.split(','); }); + + var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); + map.format = Formats.CSV; + + return map; +}; + +module.exports = ParseCSV; + + +/***/ }), +/* 562 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AssignTileProperties = __webpack_require__(563); +var BuildTilesetIndex = __webpack_require__(564); +var CONST = __webpack_require__(29); +var Formats = __webpack_require__(38); +var FromOrientationString = __webpack_require__(254); +var MapData = __webpack_require__(120); +var ParseImageLayers = __webpack_require__(565); +var ParseObjectLayers = __webpack_require__(566); +var ParseTileLayers = __webpack_require__(569); +var ParseTilesets = __webpack_require__(571); + +/** + * Parses a Tiled JSON object into a new MapData object. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {object} json - The Tiled JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + */ +var ParseJSONTiled = function (name, json, insertNull) +{ + // Map data will consist of: layers, objects, images, tilesets, sizes + var mapData = new MapData({ + width: json.width, + height: json.height, + name: name, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + orientation: FromOrientationString(json.orientation), + format: Formats.TILED_JSON, + version: json.version, + properties: json.properties, + renderOrder: json.renderorder, + infinite: json.infinite + }); + + if (mapData.orientation === CONST.HEXAGONAL) + { + mapData.hexSideLength = json.hexsidelength; + } + + mapData.layers = ParseTileLayers(json, insertNull); + mapData.images = ParseImageLayers(json); + + var sets = ParseTilesets(json); + + mapData.tilesets = sets.tilesets; + mapData.imageCollections = sets.imageCollections; + + mapData.objects = ParseObjectLayers(json); + + mapData.tiles = BuildTilesetIndex(mapData); + + AssignTileProperties(mapData); + + return mapData; +}; + +module.exports = ParseJSONTiled; + + +/***/ }), +/* 563 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Extend = __webpack_require__(17); + +/** + * Copy properties from tileset to tiles. + * + * @function Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + */ +var AssignTileProperties = function (mapData) +{ + var layerData; + var tile; + var sid; + var set; + var row; + + // go through each of the map data layers + for (var i = 0; i < mapData.layers.length; i++) + { + layerData = mapData.layers[i]; + + set = null; + + // rows of tiles + for (var j = 0; j < layerData.data.length; j++) + { + row = layerData.data[j]; + + // individual tiles + for (var k = 0; k < row.length; k++) + { + tile = row[k]; + + if (tile === null || tile.index < 0) + { + continue; + } + + // find the relevant tileset + sid = mapData.tiles[tile.index][2]; + set = mapData.tilesets[sid]; + + // Ensure that a tile's size matches its tileset + tile.width = set.tileWidth; + tile.height = set.tileHeight; + + // if that tile type has any properties, add them to the tile object + if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) + { + tile.properties = Extend( + tile.properties, set.tileProperties[tile.index - set.firstgid] + ); + } + } + } + } +}; + +module.exports = AssignTileProperties; + + +/***/ }), +/* 564 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); + +/** + * Master list of tiles -> x, y, index in tileset. + * + * @function Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + * + * @return {array} An array of Tileset objects. + */ +var BuildTilesetIndex = function (mapData) +{ + var i; + var set; + var tiles = []; + + for (i = 0; i < mapData.imageCollections.length; i++) + { + var collection = mapData.imageCollections[i]; + var images = collection.images; + + for (var j = 0; j < images.length; j++) + { + var image = images[j]; + + set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); + + set.updateTileData(collection.imageWidth, collection.imageHeight); + + mapData.tilesets.push(set); + } + } + + for (i = 0; i < mapData.tilesets.length; i++) + { + set = mapData.tilesets[i]; + + var x = set.tileMargin; + var y = set.tileMargin; + + var count = 0; + var countX = 0; + var countY = 0; + + for (var t = set.firstgid; t < set.firstgid + set.total; t++) + { + // Can add extra properties here as needed + tiles[t] = [ x, y, i ]; + + x += set.tileWidth + set.tileSpacing; + + count++; + + if (count === set.total) + { + break; + } + + countX++; + + if (countX === set.columns) + { + x = set.tileMargin; + y += set.tileHeight + set.tileSpacing; + + countX = 0; + countY++; + + if (countY === set.rows) + { + break; + } + } + } + } + + return tiles; +}; + +module.exports = BuildTilesetIndex; + + +/***/ }), +/* 565 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var CreateGroupLayer = __webpack_require__(159); + +/** + * Parses a Tiled JSON object into an array of objects with details about the image layers. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * + * @return {array} Array of objects that include critical info about the map's image layers + */ +var ParseImageLayers = function (json) +{ + var images = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + // Get current layer and advance iterator + var curi = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + if (curi.type !== 'imagelayer') + { + if (curi.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curi, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + var layerOffsetX = GetFastValue(curi, 'offsetx', 0) + GetFastValue(curi, 'startx', 0); + var layerOffsetY = GetFastValue(curi, 'offsety', 0) + GetFastValue(curi, 'starty', 0); + images.push({ + name: (curGroupState.name + curi.name), + image: curi.image, + x: (curGroupState.x + layerOffsetX + curi.x), + y: (curGroupState.y + layerOffsetY + curi.y), + alpha: (curGroupState.opacity * curi.opacity), + visible: (curGroupState.visible && curi.visible), + properties: GetFastValue(curi, 'properties', {}) + }); + } + + return images; +}; + +module.exports = ParseImageLayers; + + +/***/ }), +/* 566 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(2); +var ParseObject = __webpack_require__(256); +var ObjectLayer = __webpack_require__(568); +var CreateGroupLayer = __webpack_require__(159); + +/** + * Parses a Tiled JSON object into an array of ObjectLayer objects. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * + * @return {array} An array of all object layers in the tilemap as `ObjectLayer`s. + */ +var ParseObjectLayers = function (json) +{ + var objectLayers = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + // Get current layer and advance iterator + var curo = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + // Modify inherited properties + curo.opacity *= curGroupState.opacity; + curo.visible = curGroupState.visible && curo.visible; + + if (curo.type !== 'objectgroup') + { + if (curo.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curo, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + curo.name = curGroupState.name + curo.name; + var offsetX = curGroupState.x + GetFastValue(curo, 'startx', 0) + GetFastValue(curo, 'offsetx', 0); + var offsetY = curGroupState.y + GetFastValue(curo, 'starty', 0) + GetFastValue(curo, 'offsety', 0); + + var objects = []; + for (var j = 0; j < curo.objects.length; j++) + { + var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); + + objects.push(parsedObject); + } + + var objectLayer = new ObjectLayer(curo); + objectLayer.objects = objects; + + objectLayers.push(objectLayer); + } + + return objectLayers; +}; + +module.exports = ParseObjectLayers; + + +/***/ }), +/* 567 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var HasValue = __webpack_require__(125); + +/** + * Returns a new object that only contains the `keys` that were found on the object provided. + * If no `keys` are found, an empty object is returned. + * + * @function Phaser.Utils.Objects.Pick + * @since 3.18.0 + * + * @param {object} object - The object to pick the provided keys from. + * @param {array} keys - An array of properties to retrieve from the provided object. + * + * @return {object} A new object that only contains the `keys` that were found on the provided object. If no `keys` were found, an empty object will be returned. + */ +var Pick = function (object, keys) +{ + var obj = {}; + + for (var i = 0; i < keys.length; i++) + { + var key = keys[i]; + + if (HasValue(object, key)) + { + obj[key] = object[key]; + } + } + + return obj; +}; + +module.exports = Pick; + + +/***/ }), +/* 568 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * A class for representing a Tiled object layer in a map. This mirrors the structure of a Tiled + * object layer, except: + * - "x" & "y" properties are ignored since these cannot be changed in Tiled. + * - "offsetx" & "offsety" are applied to the individual object coordinates directly, so they + * are ignored as well. + * - "draworder" is ignored. + * + * @class ObjectLayer + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Tilemaps.ObjectLayerConfig} [config] - The data for the layer from the Tiled JSON object. + */ +var ObjectLayer = new Class({ + + initialize: + + function ObjectLayer (config) + { + if (config === undefined) { config = {}; } + + /** + * The name of the Object Layer. + * + * @name Phaser.Tilemaps.ObjectLayer#name + * @type {string} + * @since 3.0.0 + */ + this.name = GetFastValue(config, 'name', 'object layer'); + + /** + * The opacity of the layer, between 0 and 1. + * + * @name Phaser.Tilemaps.ObjectLayer#opacity + * @type {number} + * @since 3.0.0 + */ + this.opacity = GetFastValue(config, 'opacity', 1); + + /** + * The custom properties defined on the Object Layer, keyed by their name. + * + * @name Phaser.Tilemaps.ObjectLayer#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = GetFastValue(config, 'properties', {}); + + /** + * The type of each custom property defined on the Object Layer, keyed by its name. + * + * @name Phaser.Tilemaps.ObjectLayer#propertyTypes + * @type {object} + * @since 3.0.0 + */ + this.propertyTypes = GetFastValue(config, 'propertytypes', {}); + + /** + * The type of the layer, which should be `objectgroup`. + * + * @name Phaser.Tilemaps.ObjectLayer#type + * @type {string} + * @since 3.0.0 + */ + this.type = GetFastValue(config, 'type', 'objectgroup'); + + /** + * Whether the layer is shown (`true`) or hidden (`false`). + * + * @name Phaser.Tilemaps.ObjectLayer#visible + * @type {boolean} + * @since 3.0.0 + */ + this.visible = GetFastValue(config, 'visible', true); + + /** + * An array of all objects on this Object Layer. + * + * Each Tiled object corresponds to a JavaScript object in this array. It has an `id` (unique), + * `name` (as assigned in Tiled), `type` (as assigned in Tiled), `rotation` (in clockwise degrees), + * `properties` (if any), `visible` state (`true` if visible, `false` otherwise), + * `x` and `y` coordinates (in pixels, relative to the tilemap), and a `width` and `height` (in pixels). + * + * An object tile has a `gid` property (GID of the represented tile), a `flippedHorizontal` property, + * a `flippedVertical` property, and `flippedAntiDiagonal` property. + * The {@link http://docs.mapeditor.org/en/latest/reference/tmx-map-format/|Tiled documentation} contains + * information on flipping and rotation. + * + * Polylines have a `polyline` property, which is an array of objects corresponding to points, + * where each point has an `x` property and a `y` property. Polygons have an identically structured + * array in their `polygon` property. Text objects have a `text` property with the text's properties. + * + * Rectangles and ellipses have a `rectangle` or `ellipse` property set to `true`. + * + * @name Phaser.Tilemaps.ObjectLayer#objects + * @type {Phaser.Types.Tilemaps.TiledObject[]} + * @since 3.0.0 + */ + this.objects = GetFastValue(config, 'objects', []); + } + +}); + +module.exports = ObjectLayer; + + +/***/ }), +/* 569 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Base64Decode = __webpack_require__(570); +var CONST = __webpack_require__(29); +var CreateGroupLayer = __webpack_require__(159); +var FromOrientationString = __webpack_require__(254); +var GetFastValue = __webpack_require__(2); +var LayerData = __webpack_require__(119); +var ParseGID = __webpack_require__(257); +var Tile = __webpack_require__(83); + +/** + * Parses all tilemap layers in a Tiled JSON object into new LayerData objects. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). + * + * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in + * json.layers with the type 'tilelayer'. + */ +var ParseTileLayers = function (json, insertNull) +{ + var infiniteMap = GetFastValue(json, 'infinite', false); + var tileLayers = []; + + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); + + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) + { + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } + + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; + } + + var curl = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + if (curl.type !== 'tilelayer') + { + if (curl.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curl, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } + + // Skip this layer OR 'recurse' (iterative style) into the group + continue; + } + + // Base64 decode data if necessary. NOTE: uncompressed base64 only. + if (curl.compression) + { + console.warn( + 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' + + curl.name + '\'' + ); + continue; + } + else if (curl.encoding && curl.encoding === 'base64') + { + // Chunks for an infinite map + if (curl.chunks) + { + for (var i = 0; i < curl.chunks.length; i++) + { + curl.chunks[i].data = Base64Decode(curl.chunks[i].data); + } + } + + // Non-infinite map data + if (curl.data) + { + curl.data = Base64Decode(curl.data); + } + + delete curl.encoding; // Allow the same map to be parsed multiple times + } + + // This is an array containing the tile indexes, one after the other. -1 = no tile, + // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map + // contains multiple tilesets then the indexes are relative to that which the set starts + // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this + // manually it means you can use the same map data but a new tileset. + + var layerData; + var gidInfo; + var tile; + var blankTile; + + var output = []; + var x = 0; + + if (infiniteMap) + { + var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x); + var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y); + + layerData = new LayerData({ + name: (curGroupState.name + curl.name), + x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + layerOffsetX * json.tilewidth), + y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + layerOffsetY * json.tileheight), + width: curl.width, + height: curl.height, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + alpha: (curGroupState.opacity * curl.opacity), + visible: (curGroupState.visible && curl.visible), + properties: GetFastValue(curl, 'properties', []), + orientation: FromOrientationString(json.orientation) + }); + + if (layerData.orientation === CONST.HEXAGONAL) + { + layerData.hexSideLength = json.hexsidelength; + } + + for (var c = 0; c < curl.height; c++) + { + output.push([ null ]); + + for (var j = 0; j < curl.width; j++) + { + output[c][j] = null; + } + } + + for (c = 0, len = curl.chunks.length; c < len; c++) + { + var chunk = curl.chunks[c]; + + var offsetX = (chunk.x - layerOffsetX); + var offsetY = (chunk.y - layerOffsetY); + + var y = 0; + + for (var t = 0, len2 = chunk.data.length; t < len2; t++) + { + var newOffsetX = x + offsetX; + var newOffsetY = y + offsetY; + + gidInfo = ParseGID(chunk.data[t]); + + // index, x, y, width, height + if (gidInfo.gid > 0) + { + tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); + + // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal + // propeties into flipX, flipY and rotation + tile.rotation = gidInfo.rotation; + tile.flipX = gidInfo.flipped; + + output[newOffsetY][newOffsetX] = tile; + } + else + { + blankTile = insertNull + ? null + : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); + + output[newOffsetY][newOffsetX] = blankTile; + } + + x++; + + if (x === chunk.width) + { + y++; + x = 0; + } + } + } + } + else + { + layerData = new LayerData({ + name: (curGroupState.name + curl.name), + x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + curl.x), + y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + curl.y), + width: curl.width, + height: curl.height, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + alpha: (curGroupState.opacity * curl.opacity), + visible: (curGroupState.visible && curl.visible), + properties: GetFastValue(curl, 'properties', []), + orientation: FromOrientationString(json.orientation) + }); + + if (layerData.orientation === CONST.HEXAGONAL) + { + layerData.hexSideLength = json.hexsidelength; + } + var row = []; + + // Loop through the data field in the JSON. + for (var k = 0, len = curl.data.length; k < len; k++) + { + gidInfo = ParseGID(curl.data[k]); + + // index, x, y, width, height + if (gidInfo.gid > 0) + { + tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); + + // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal + // propeties into flipX, flipY and rotation + tile.rotation = gidInfo.rotation; + tile.flipX = gidInfo.flipped; + + row.push(tile); + } + else + { + blankTile = insertNull + ? null + : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); + row.push(blankTile); + } + + x++; + + if (x === curl.width) + { + output.push(row); + x = 0; + row = []; + } + } + } + + layerData.data = output; + tileLayers.push(layerData); + } + + return tileLayers; +}; + +module.exports = ParseTileLayers; + + +/***/ }), +/* 570 */ +/***/ (function(module, exports) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Decode base-64 encoded data, for example as exported by Tiled. + * + * @function Phaser.Tilemaps.Parsers.Tiled.Base64Decode + * @since 3.0.0 + * + * @param {object} data - Base-64 encoded data to decode. + * + * @return {array} Array containing the decoded bytes. + */ +var Base64Decode = function (data) +{ + var binaryString = window.atob(data); + var len = binaryString.length; + var bytes = new Array(len / 4); + + // Interpret binaryString as an array of bytes representing little-endian encoded uint32 values. + for (var i = 0; i < len; i += 4) + { + bytes[i / 4] = ( + binaryString.charCodeAt(i) | + binaryString.charCodeAt(i + 1) << 8 | + binaryString.charCodeAt(i + 2) << 16 | + binaryString.charCodeAt(i + 3) << 24 + ) >>> 0; + } + + return bytes; +}; + +module.exports = Base64Decode; + + +/***/ }), +/* 571 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); +var ImageCollection = __webpack_require__(572); +var ParseObject = __webpack_require__(256); + +/** + * Tilesets and Image Collections + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseTilesets + * @since 3.0.0 + * + * @param {object} json - The Tiled JSON data. + * + * @return {object} An object containing the tileset and image collection data. + */ +var ParseTilesets = function (json) +{ + var tilesets = []; + var imageCollections = []; + var lastSet = null; + var stringID; + + for (var i = 0; i < json.tilesets.length; i++) + { + // name, firstgid, width, height, margin, spacing, properties + var set = json.tilesets[i]; + + if (set.source) + { + console.warn('External tilesets unsupported. Use Embed Tileset and re-export'); + } + else if (set.image) + { + var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); + + if (json.version > 1) + { + // Tiled 1.2+ + + if (Array.isArray(set.tiles)) + { + var tiles = {}; + var props = {}; + + for (var t = 0; t < set.tiles.length; t++) + { + var tile = set.tiles[t]; + + // Convert tileproperties + if (tile.properties) + { + var newPropData = {}; + + tile.properties.forEach(function (propData) + { + newPropData[propData['name']] = propData['value']; + }); + + props[tile.id] = newPropData; + } + + // Convert objectgroup + if (tile.objectgroup) + { + tiles[tile.id] = { objectgroup: tile.objectgroup }; + + if (tile.objectgroup.objects) + { + var parsedObjects2 = tile.objectgroup.objects.map(function (obj) + { + return ParseObject(obj); + }); + + tiles[tile.id].objectgroup.objects = parsedObjects2; + } + } + + // Copy animation data + if (tile.animation) + { + if (tiles.hasOwnProperty(tile.id)) + { + tiles[tile.id].animation = tile.animation; + } + else + { + tiles[tile.id] = { animation: tile.animation }; + } + } + } + + newSet.tileData = tiles; + newSet.tileProperties = props; + } + } + else + { + // Tiled 1 + + // Properties stored per-tile in object with string indexes starting at "0" + if (set.tileproperties) + { + newSet.tileProperties = set.tileproperties; + } + + // Object & terrain shapes stored per-tile in object with string indexes starting at "0" + if (set.tiles) + { + newSet.tileData = set.tiles; + + // Parse the objects into Phaser format to match handling of other Tiled objects + for (stringID in newSet.tileData) + { + var objectGroup = newSet.tileData[stringID].objectgroup; + + if (objectGroup && objectGroup.objects) + { + var parsedObjects1 = objectGroup.objects.map(function (obj) + { + return ParseObject(obj); + }); + + newSet.tileData[stringID].objectgroup.objects = parsedObjects1; + } + } + } + } + + // For a normal sliced tileset the row/count/size information is computed when updated. + // This is done (again) after the image is set. + newSet.updateTileData(set.imagewidth, set.imageheight); + + tilesets.push(newSet); + } + else + { + var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); + + var maxId = 0; + + for (t = 0; t < set.tiles.length; t++) + { + tile = set.tiles[t]; + + var image = tile.image; + var tileId = parseInt(tile.id, 10); + var gid = set.firstgid + tileId; + newCollection.addImage(gid, image); + + maxId = Math.max(tileId, maxId); + } + + newCollection.maxId = maxId; + + imageCollections.push(newCollection); + } + + // We've got a new Tileset, so set the lastgid into the previous one + if (lastSet) + { + lastSet.lastgid = set.firstgid - 1; + } + + lastSet = set; + } + + return { tilesets: tilesets, imageCollections: imageCollections }; +}; + +module.exports = ParseTilesets; + + +/***/ }), +/* 572 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); + +/** + * @classdesc + * An Image Collection is a special Tile Set containing multiple images, with no slicing into each image. + * + * Image Collections are normally created automatically when Tiled data is loaded. + * + * @class ImageCollection + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {string} name - The name of the image collection in the map data. + * @param {number} firstgid - The first image index this image collection contains. + * @param {number} [width=32] - Width of widest image (in pixels). + * @param {number} [height=32] - Height of tallest image (in pixels). + * @param {number} [margin=0] - The margin around all images in the collection (in pixels). + * @param {number} [spacing=0] - The spacing between each image in the collection (in pixels). + * @param {object} [properties={}] - Custom Image Collection properties. + */ +var ImageCollection = new Class({ + + initialize: + + function ImageCollection (name, firstgid, width, height, margin, spacing, properties) + { + if (width === undefined || width <= 0) { width = 32; } + if (height === undefined || height <= 0) { height = 32; } + if (margin === undefined) { margin = 0; } + if (spacing === undefined) { spacing = 0; } + + /** + * The name of the Image Collection. + * + * @name Phaser.Tilemaps.ImageCollection#name + * @type {string} + * @since 3.0.0 + */ + this.name = name; + + /** + * The Tiled firstgid value. + * This is the starting index of the first image index this Image Collection contains. + * + * @name Phaser.Tilemaps.ImageCollection#firstgid + * @type {number} + * @since 3.0.0 + */ + this.firstgid = firstgid | 0; + + /** + * The width of the widest image (in pixels). + * + * @name Phaser.Tilemaps.ImageCollection#imageWidth + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageWidth = width | 0; + + /** + * The height of the tallest image (in pixels). + * + * @name Phaser.Tilemaps.ImageCollection#imageHeight + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageHeight = height | 0; + + /** + * The margin around the images in the collection (in pixels). + * Use `setSpacing` to change. + * + * @name Phaser.Tilemaps.ImageCollection#imageMarge + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageMargin = margin | 0; + + /** + * The spacing between each image in the collection (in pixels). + * Use `setSpacing` to change. + * + * @name Phaser.Tilemaps.ImageCollection#imageSpacing + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageSpacing = spacing | 0; + + /** + * Image Collection-specific properties that are typically defined in the Tiled editor. + * + * @name Phaser.Tilemaps.ImageCollection#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = properties || {}; + + /** + * The cached images that are a part of this collection. + * + * @name Phaser.Tilemaps.ImageCollection#images + * @type {array} + * @readonly + * @since 3.0.0 + */ + this.images = []; + + /** + * The total number of images in the image collection. + * + * @name Phaser.Tilemaps.ImageCollection#total + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.total = 0; + }, + + /** + * Returns true if and only if this image collection contains the given image index. + * + * @method Phaser.Tilemaps.ImageCollection#containsImageIndex + * @since 3.0.0 + * + * @param {number} imageIndex - The image index to search for. + * + * @return {boolean} True if this Image Collection contains the given index. + */ + containsImageIndex: function (imageIndex) + { + return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); + }, + + /** + * Add an image to this Image Collection. + * + * @method Phaser.Tilemaps.ImageCollection#addImage + * @since 3.0.0 + * + * @param {number} gid - The gid of the image in the Image Collection. + * @param {string} image - The the key of the image in the Image Collection and in the cache. + * + * @return {Phaser.Tilemaps.ImageCollection} This ImageCollection object. + */ + addImage: function (gid, image) + { + this.images.push({ gid: gid, image: image }); + this.total++; + + return this; + } + +}); + +module.exports = ImageCollection; + + +/***/ }), +/* 573 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(38); +var MapData = __webpack_require__(120); +var ParseTileLayers = __webpack_require__(574); +var ParseTilesets = __webpack_require__(575); + +/** + * Parses a Weltmeister JSON object into a new MapData object. + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {object} json - The Weltmeister JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled. If `true`, empty locations will get a value of `null`. If `false`, empty + * location will get a Tile object with an index of -1. If you've a large sparsely populated map and + * the tile data doesn't need to change then setting this value to `true` will help with memory + * consumption. However if your map is small or you need to update the tiles dynamically, then leave + * the default value set. + * + * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + */ +var ParseWeltmeister = function (name, json, insertNull) +{ + if (json.layer.length === 0) + { + console.warn('No layers found in the Weltmeister map: ' + name); + return null; + } + + var width = 0; + var height = 0; + + for (var i = 0; i < json.layer.length; i++) + { + if (json.layer[i].width > width) { width = json.layer[i].width; } + if (json.layer[i].height > height) { height = json.layer[i].height; } + } + + var mapData = new MapData({ + width: width, + height: height, + name: name, + tileWidth: json.layer[0].tilesize, + tileHeight: json.layer[0].tilesize, + format: Formats.WELTMEISTER + }); + + mapData.layers = ParseTileLayers(json, insertNull); + mapData.tilesets = ParseTilesets(json); + + return mapData; +}; + +module.exports = ParseWeltmeister; + + +/***/ }), +/* 574 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LayerData = __webpack_require__(119); +var Tile = __webpack_require__(83); + +/** + * Parses all tilemap layers in an Impact JSON object into new LayerData objects. + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers + * @since 3.0.0 + * + * @param {object} json - The Impact JSON object. + * @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map + * data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}). + * + * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in + * json.layers with the type 'tilelayer'. + */ +var ParseTileLayers = function (json, insertNull) +{ + var tileLayers = []; + + for (var i = 0; i < json.layer.length; i++) + { + var layer = json.layer[i]; + + var layerData = new LayerData({ + name: layer.name, + width: layer.width, + height: layer.height, + tileWidth: layer.tilesize, + tileHeight: layer.tilesize, + visible: layer.visible === 1 + }); + + var row = []; + var tileGrid = []; + + // Loop through the data field in the JSON. This is a 2D array containing the tile indexes, + // one after the other. The indexes are relative to the tileset that contains the tile. + for (var y = 0; y < layer.data.length; y++) + { + for (var x = 0; x < layer.data[y].length; x++) + { + // In Weltmeister, 0 = no tile, but the Tilemap API expects -1 = no tile. + var index = layer.data[y][x] - 1; + + var tile; + + if (index > -1) + { + tile = new Tile(layerData, index, x, y, layer.tilesize, layer.tilesize); + } + else + { + tile = insertNull + ? null + : new Tile(layerData, -1, x, y, layer.tilesize, layer.tilesize); + } + + row.push(tile); + } + + tileGrid.push(row); + row = []; + } + + layerData.data = tileGrid; + + tileLayers.push(layerData); + } + + return tileLayers; +}; + +module.exports = ParseTileLayers; + + +/***/ }), +/* 575 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tileset = __webpack_require__(121); + +/** + * Tilesets and Image Collections + * + * @function Phaser.Tilemaps.Parsers.Impact.ParseTilesets + * @since 3.0.0 + * + * @param {object} json - The Impact JSON data. + * + * @return {array} An array of Tilesets. + */ +var ParseTilesets = function (json) +{ + var tilesets = []; + var tilesetsNames = []; + + for (var i = 0; i < json.layer.length; i++) + { + var layer = json.layer[i]; + + // A relative filepath to the source image (within Weltmeister) is used for the name + var tilesetName = layer.tilesetName; + + // Only add unique tilesets that have a valid name. Collision layers will have a blank name. + if (tilesetName !== '' && tilesetsNames.indexOf(tilesetName) === -1) + { + tilesetsNames.push(tilesetName); + + // Tiles are stored with an ID relative to the tileset, rather than a globally unique ID + // across all tilesets. Also, tilesets in Weltmeister have no margin or padding. + tilesets.push(new Tileset(tilesetName, 0, layer.tilesize, layer.tilesize, 0, 0)); + } + } + + return tilesets; +}; + +module.exports = ParseTilesets; + + +/***/ }), +/* 576 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var DegToRad = __webpack_require__(34); +var Formats = __webpack_require__(38); +var GetFastValue = __webpack_require__(2); +var LayerData = __webpack_require__(119); +var ORIENTATION = __webpack_require__(29); +var Rotate = __webpack_require__(356); +var SpliceOne = __webpack_require__(74); +var Sprite = __webpack_require__(73); +var Tile = __webpack_require__(83); +var TilemapComponents = __webpack_require__(247); +var TilemapLayer = __webpack_require__(577); +var Tileset = __webpack_require__(121); + +/** + * @callback TilemapFilterCallback + * + * @param {Phaser.GameObjects.GameObject} value - An object found in the filtered area. + * @param {number} index - The index of the object within the array. + * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. + * + * @return {Phaser.GameObjects.GameObject} The object. + */ + +/** + * @callback TilemapFindCallback + * + * @param {Phaser.GameObjects.GameObject} value - An object found. + * @param {number} index - The index of the object within the array. + * @param {Phaser.GameObjects.GameObject[]} array - An array of all the objects found. + * + * @return {boolean} `true` if the callback should be invoked, otherwise `false`. + */ + +/** + * @classdesc + * A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data + * about the map and allows you to add tilesets and tilemap layers to it. A map can have one or + * more tilemap layers, which are the display objects that actually render the tiles. + * + * The Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free + * software package specifically for creating tile maps, and is available from: + * http://www.mapeditor.org + * + * As of Phaser 3.50.0 the Tilemap API now supports the following types of map: + * + * 1) Orthogonal + * 2) Isometric + * 3) Hexagonal + * 4) Staggered + * + * Prior to this release, only orthogonal maps were supported. + * + * Another large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created + * either a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been + * merged and the API simplified, so now there is just the single `TilemapLayer` class. + * + * A Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing + * you to build or modify the tilemap data at runtime. + * + * Note that all Tilemaps use a base tile size to calculate dimensions from, but that a + * TilemapLayer may have its own unique tile size that overrides this. + * + * As of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these + * will be traversed and the following properties will impact children: + * + * - Opacity (blended with parent) and visibility (parent overrides child) + * - Vertical and horizontal offset + * + * The grouping hierarchy is not preserved and all layers will be flattened into a single array. + * + * Group layers are parsed during Tilemap construction but are discarded after parsing so dynamic + * layers will NOT continue to be affected by a parent. + * + * To avoid duplicate layer names, a layer that is a child of a group layer will have its parent + * group name prepended with a '/'. For example, consider a group called 'ParentGroup' with a + * child called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name + * 'ParentGroup/Layer 1'. + * + * @class Tilemap + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. + * @param {Phaser.Tilemaps.MapData} mapData - A MapData instance containing Tilemap data. + */ +var Tilemap = new Class({ + + initialize: + + function Tilemap (scene, mapData) + { + /** + * @name Phaser.Tilemaps.Tilemap#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; + + /** + * The base width of a tile in pixels. Note that individual layers may have a different tile + * width. + * + * @name Phaser.Tilemaps.Tilemap#tileWidth + * @type {number} + * @since 3.0.0 + */ + this.tileWidth = mapData.tileWidth; + + /** + * The base height of a tile in pixels. Note that individual layers may have a different + * tile height. + * + * @name Phaser.Tilemaps.Tilemap#tileHeight + * @type {number} + * @since 3.0.0 + */ + this.tileHeight = mapData.tileHeight; + + /** + * The width of the map (in tiles). + * + * @name Phaser.Tilemaps.Tilemap#width + * @type {number} + * @since 3.0.0 + */ + this.width = mapData.width; + + /** + * The height of the map (in tiles). + * + * @name Phaser.Tilemaps.Tilemap#height + * @type {number} + * @since 3.0.0 + */ + this.height = mapData.height; + + /** + * The orientation of the map data (as specified in Tiled), usually 'orthogonal'. + * + * @name Phaser.Tilemaps.Tilemap#orientation + * @type {string} + * @since 3.0.0 + */ + this.orientation = mapData.orientation; + + /** + * The render (draw) order of the map data (as specified in Tiled), usually 'right-down'. + * + * The draw orders are: + * + * right-down + * left-down + * right-up + * left-up + * + * This can be changed via the `setRenderOrder` method. + * + * @name Phaser.Tilemaps.Tilemap#renderOrder + * @type {string} + * @since 3.12.0 + */ + this.renderOrder = mapData.renderOrder; + + /** + * The format of the map data. + * + * @name Phaser.Tilemaps.Tilemap#format + * @type {number} + * @since 3.0.0 + */ + this.format = mapData.format; + + /** + * The version of the map data (as specified in Tiled, usually 1). + * + * @name Phaser.Tilemaps.Tilemap#version + * @type {number} + * @since 3.0.0 + */ + this.version = mapData.version; + + /** + * Map specific properties as specified in Tiled. + * + * @name Phaser.Tilemaps.Tilemap#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = mapData.properties; + + /** + * The width of the map in pixels based on width * tileWidth. + * + * @name Phaser.Tilemaps.Tilemap#widthInPixels + * @type {number} + * @since 3.0.0 + */ + this.widthInPixels = mapData.widthInPixels; + + /** + * The height of the map in pixels based on height * tileHeight. + * + * @name Phaser.Tilemaps.Tilemap#heightInPixels + * @type {number} + * @since 3.0.0 + */ + this.heightInPixels = mapData.heightInPixels; + + /** + * A collection of Images, as parsed from Tiled map data. + * + * @name Phaser.Tilemaps.Tilemap#imageCollections + * @type {Phaser.Tilemaps.ImageCollection[]} + * @since 3.0.0 + */ + this.imageCollections = mapData.imageCollections; + + /** + * An array of Tiled Image Layers. + * + * @name Phaser.Tilemaps.Tilemap#images + * @type {array} + * @since 3.0.0 + */ + this.images = mapData.images; + + /** + * An array of Tilemap layer data. + * + * @name Phaser.Tilemaps.Tilemap#layers + * @type {Phaser.Tilemaps.LayerData[]} + * @since 3.0.0 + */ + this.layers = mapData.layers; + + /** + * An array of Tilesets used in the map. + * + * @name Phaser.Tilemaps.Tilemap#tilesets + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.0.0 + */ + this.tilesets = mapData.tilesets; + + /** + * An array of ObjectLayer instances parsed from Tiled object layers. + * + * @name Phaser.Tilemaps.Tilemap#objects + * @type {Phaser.Tilemaps.ObjectLayer[]} + * @since 3.0.0 + */ + this.objects = mapData.objects; + + /** + * The index of the currently selected LayerData object. + * + * @name Phaser.Tilemaps.Tilemap#currentLayerIndex + * @type {number} + * @since 3.0.0 + */ + this.currentLayerIndex = 0; + + /** + * The length of the horizontal sides of the hexagon. + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.Tilemap#hexSideLength + * @type {number} + * @since 3.50.0 + */ + this.hexSideLength = mapData.hexSideLength; + + var orientation = this.orientation; + + /** + * Functions used to handle world to tile, and tile to world, conversion. + * Cached here for internal use by public methods such as `worldToTileXY`, etc. + * + * @name Phaser.Tilemaps.Tilemap#_convert + * @private + * @type {object} + * @since 3.50.0 + */ + this._convert = { + WorldToTileXY: TilemapComponents.GetWorldToTileXYFunction(orientation), + WorldToTileX: TilemapComponents.GetWorldToTileXFunction(orientation), + WorldToTileY: TilemapComponents.GetWorldToTileYFunction(orientation), + TileToWorldXY: TilemapComponents.GetTileToWorldXYFunction(orientation), + TileToWorldX: TilemapComponents.GetTileToWorldXFunction(orientation), + TileToWorldY: TilemapComponents.GetTileToWorldYFunction(orientation) + }; + }, + + /** + * @ignore + */ + createBlankDynamicLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) + { + console.warn('createBlankDynamicLayer is deprecated. Use createBlankLayer'); + + return this.createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight); + }, + + /** + * @ignore + */ + createDynamicLayer: function (layerID, tileset, x, y) + { + console.warn('createDynamicLayer is deprecated. Use createLayer'); + + return this.createLayer(layerID, tileset, x, y); + }, + + /** + * @ignore + */ + createStaticLayer: function (layerID, tileset, x, y) + { + console.warn('createStaticLayer is deprecated. Use createLayer'); + + return this.createLayer(layerID, tileset, x, y); + }, + + /** + * Sets the rendering (draw) order of the tiles in this map. + * + * The default is 'right-down', meaning it will order the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * Setting the render order does not change the tiles or how they are stored in the layer, + * it purely impacts the order in which they are rendered. + * + * You can provide either an integer (0 to 3), or the string version of the order. + * + * Calling this method _after_ creating Tilemap Layers will **not** automatically + * update them to use the new render order. If you call this method after creating layers, use their + * own `setRenderOrder` methods to change them as needed. + * + * @method Phaser.Tilemaps.Tilemap#setRenderOrder + * @since 3.12.0 + * + * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. + * + * @return {this} This Tilemap object. + */ + setRenderOrder: function (renderOrder) + { + var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; + + if (typeof renderOrder === 'number') + { + renderOrder = orders[renderOrder]; + } + + if (orders.indexOf(renderOrder) > -1) + { + this.renderOrder = renderOrder; + } + + return this; + }, + + /** + * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. + * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled + * editor. + * + * @method Phaser.Tilemaps.Tilemap#addTilesetImage + * @since 3.0.0 + * + * @param {string} tilesetName - The name of the tileset as specified in the map data. + * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If + * `undefined` or `null` it will look for an image with a key matching the tilesetName parameter. + * @param {number} [tileWidth] - The width of the tile (in pixels) in the Tileset Image. If not + * given it will default to the map's tileWidth value, or the tileWidth specified in the Tiled + * JSON file. + * @param {number} [tileHeight] - The height of the tiles (in pixels) in the Tileset Image. If + * not given it will default to the map's tileHeight value, or the tileHeight specified in the + * Tiled JSON file. + * @param {number} [tileMargin] - The margin around the tiles in the sheet (in pixels). If not + * specified, it will default to 0 or the value specified in the Tiled JSON file. + * @param {number} [tileSpacing] - The spacing between each the tile in the sheet (in pixels). + * If not specified, it will default to 0 or the value specified in the Tiled JSON file. + * @param {number} [gid=0] - If adding multiple tilesets to a blank map, specify the starting + * GID this set will use here. + * + * @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it + * failed. + */ + addTilesetImage: function (tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid) + { + if (tilesetName === undefined) { return null; } + if (key === undefined || key === null) { key = tilesetName; } + + if (!this.scene.sys.textures.exists(key)) + { + console.warn('Invalid Tileset Image: ' + key); + return null; + } + + var texture = this.scene.sys.textures.get(key); + + var index = this.getTilesetIndex(tilesetName); + + if (index === null && this.format === Formats.TILED_JSON) + { + console.warn('No data found for Tileset: ' + tilesetName); + return null; + } + + var tileset = this.tilesets[index]; + + if (tileset) + { + tileset.setTileSize(tileWidth, tileHeight); + tileset.setSpacing(tileMargin, tileSpacing); + tileset.setImage(texture); + + return tileset; + } + + if (tileWidth === undefined) { tileWidth = this.tileWidth; } + if (tileHeight === undefined) { tileHeight = this.tileHeight; } + if (tileMargin === undefined) { tileMargin = 0; } + if (tileSpacing === undefined) { tileSpacing = 0; } + if (gid === undefined) { gid = 0; } + + tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing); + + tileset.setImage(texture); + + this.tilesets.push(tileset); + + return tileset; + }, + + /** + * Copies the tiles in the source rectangular area to a new destination (all specified in tile + * coordinates) within the layer. This copies all tile properties & recalculates collision + * information in the destination region. + * + * If no layer specified, the map's current layer is used. This cannot be applied to StaticTilemapLayers. + * + * @method Phaser.Tilemaps.Tilemap#copy + * @since 3.0.0 + * + * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. + * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. + * @param {number} width - The width of the area to copy, in tiles, not pixels. + * @param {number} height - The height of the area to copy, in tiles, not pixels. + * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. + * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) + { + layer = this.getLayer(layer); + + if (layer !== null) + { + TilemapComponents.Copy( + srcTileX, srcTileY, + width, height, + destTileX, destTileY, + recalculateFaces, layer + ); + + return this; + } + else + { + return null; + } + }, + + /** + * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. + * + * Prior to v3.50.0 this method was called `createBlankDynamicLayer`. + * + * @method Phaser.Tilemaps.Tilemap#createBlankLayer + * @since 3.0.0 + * + * @param {string} name - The name of this layer. Must be unique within the map. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The world x position where the top left of this layer will be placed. + * @param {number} [y=0] - The world y position where the top left of this layer will be placed. + * @param {number} [width] - The width of the layer in tiles. If not specified, it will default to the map's width. + * @param {number} [height] - The height of the layer in tiles. If not specified, it will default to the map's height. + * @param {number} [tileWidth] - The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth. + * @param {number} [tileHeight] - The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight. + * + * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed. + */ + createBlankLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + if (tileWidth === undefined) { tileWidth = this.tileWidth; } + if (tileHeight === undefined) { tileHeight = this.tileHeight; } + + var index = this.getLayerIndex(name); + + if (index !== null) + { + console.warn('Invalid Tilemap Layer ID: ' + name); + return null; + } + + var layerData = new LayerData({ + name: name, + tileWidth: tileWidth, + tileHeight: tileHeight, + width: width, + height: height, + orientation: this.orientation + }); + + var row; + + for (var tileY = 0; tileY < height; tileY++) + { + row = []; + + for (var tileX = 0; tileX < width; tileX++) + { + row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight)); + } + + layerData.data.push(row); + } + + this.layers.push(layerData); + + this.currentLayerIndex = this.layers.length - 1; + + var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y); + + layer.setRenderOrder(this.renderOrder); + + this.scene.sys.displayList.add(layer); + + return layer; + }, + + /** + * Creates a new Tilemap Layer that renders the LayerData associated with the given + * `layerID`. The currently selected layer in the map is set to this new layer. + * + * The `layerID` is important. If you've created your map in Tiled then you can get this by + * looking in Tiled and looking at the layer name. Or you can open the JSON file it exports and + * look at the layers[].name value. Either way it must match. + * + * Prior to v3.50.0 this method was called `createDynamicLayer`. + * + * @method Phaser.Tilemaps.Tilemap#createLayer + * @since 3.0.0 + * + * @param {(number|string)} layerID - The layer array index value, or if a string is given, the layer name from Tiled. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. + * @param {number} [y=0] - The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. + * + * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed. + */ + createLayer: function (layerID, tileset, x, y) + { + var index = this.getLayerIndex(layerID); + + if (index === null) + { + console.warn('Invalid Tilemap Layer ID: ' + layerID); + + if (typeof layerID === 'string') + { + console.warn('Valid tilelayer names:\n\t' + this.getTileLayerNames().join(',\n\t')); + } + + return null; + } + + var layerData = this.layers[index]; + + // Check for an associated static or dynamic tilemap layer + if (layerData.tilemapLayer) + { + console.warn('Tilemap Layer ID already exists:' + layerID); + return null; + } + + this.currentLayerIndex = index; + + // Default the x/y position to match Tiled layer offset, if it exists. + + if (x === undefined) + { + x = layerData.x; + } + + if (y === undefined) + { + y = layerData.y; + } + + var layer = new TilemapLayer(this.scene, this, index, tileset, x, y); + + layer.setRenderOrder(this.renderOrder); + + this.scene.sys.displayList.add(layer); + + return layer; + }, + + /** + * This method will iterate through all of the objects defined in a Tiled Object Layer and then + * convert the matching results into Phaser Game Objects (by default, Sprites) + * + * Objects are matched on one of 3 criteria: The Object ID, the Object GID or the Object Name. + * + * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects + * using the same image. Finally, Object Names are strings and the same name can be used on multiple + * Objects in Tiled, they do not have to be unique. + * + * You set the configuration parameter accordingly, based on which type of criteria you wish + * to match against. For example, to convert all items on an Object Layer with a `gid` of 26: + * + * ```javascript + * createFromObjects(layerName, { + * gid: 26 + * }); + * ``` + * + * Or, to convert objects with the name 'bonus': + * + * ```javascript + * createFromObjects(layerName, { + * name: 'bonus' + * }); + * ``` + * + * Or, to convert an object with a specific id: + * + * ```javascript + * createFromObjects(layerName, { + * id: 9 + * }); + * ``` + * + * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than + * one criteria to your config. If you do not specify any criteria, then _all_ objects in the + * Object Layer will be converted. + * + * By default this method will convert objects into `Sprite` instances, but you can override + * this by providing your own class type: + * + * ```javascript + * createFromObjects(layerName, { + * gid: 26, + * classType: Coin + * }); + * ``` + * + * This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass + * any class type here, but it _must_ extend `Phaser.GameObjects.GameObject` as its base class. + * Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene + * specified in the config object or, if not given, the Scene to which this Tilemap belongs. + * + * All properties from object are copied into the Game Object, so you can use this as an easy + * way to configure properties from within the map editor. For example giving an object a + * property of `alpha: 0.5` in Tiled will be reflected in the Game Object that is created. + * + * Custom object properties that do not exist as a Game Object property are set in the + * Game Objects {@link Phaser.GameObjects.GameObject#data data store}. + * + * You can use set a `container` property in the config. If given, the class will be added to + * the Container instance instead of the Scene. + * + * Finally, you can provide an array of config objects, to convert multiple types of object in + * a single call: + * + * ```javascript + * createFromObjects(layerName, [ + * { + * gid: 26, + * classType: Coin + * }, + * { + * id: 9, + * classType: BossMonster + * }, + * { + * name: 'lava', + * classType: LavaTile + * } + * ]); + * ``` + * + * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. + * + * @method Phaser.Tilemaps.Tilemap#createFromObjects + * @since 3.0.0 + * + * @param {string} objectLayerName - The name of the Tiled object layer to create the Game Objects from. + * @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]} config - A CreateFromObjects configuration object, or an array of them. + * + * @return {Phaser.GameObjects.GameObject[]} An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found. + */ + createFromObjects: function (objectLayerName, config) + { + var results = []; + + var objectLayer = this.getObjectLayer(objectLayerName); + + if (!objectLayer) + { + console.warn('createFromObjects: Invalid objectLayerName given: ' + objectLayerName); + + return results; + } + + if (!Array.isArray(config)) + { + config = [ config ]; + } + + var objects = objectLayer.objects; + + for (var c = 0; c < config.length; c++) + { + var singleConfig = config[c]; + + var id = GetFastValue(singleConfig, 'id', null); + var gid = GetFastValue(singleConfig, 'gid', null); + var name = GetFastValue(singleConfig, 'name', null); + + var obj; + var toConvert = []; + + // Sweep to get all the objects we want to convert in this pass + for (var s = 0; s < objects.length; s++) + { + obj = objects[s]; + + if ( + (id === null && gid === null && name === null) || + (id !== null && obj.id === id) || + (gid !== null && obj.gid === gid) || + (name !== null && obj.name === name) + ) + { + toConvert.push(obj); + } + } + + // Now let's convert them ... + + var classType = GetFastValue(singleConfig, 'classType', Sprite); + var scene = GetFastValue(singleConfig, 'scene', this.scene); + var container = GetFastValue(singleConfig, 'container', null); + var texture = GetFastValue(singleConfig, 'key', null); + var frame = GetFastValue(singleConfig, 'frame', null); + + for (var i = 0; i < toConvert.length; i++) + { + obj = toConvert[i]; + + var sprite = new classType(scene); + + sprite.setName(obj.name); + sprite.setPosition(obj.x, obj.y); + sprite.setTexture(texture, frame); + + if (obj.width) + { + sprite.displayWidth = obj.width; + } + + if (obj.height) + { + sprite.displayHeight = obj.height; + } + + // Origin is (0, 1) in Tiled, so find the offset that matches the Sprites origin. + // Do not offset objects with zero dimensions (e.g. points). + var offset = { + x: sprite.originX * obj.width, + y: (sprite.originY - 1) * obj.height + }; + + // If the object is rotated, then the origin offset also needs to be rotated. + if (obj.rotation) + { + var angle = DegToRad(obj.rotation); + + Rotate(offset, angle); + + sprite.rotation = angle; + } + + sprite.x += offset.x; + sprite.y += offset.y; + + if (obj.flippedHorizontal !== undefined || obj.flippedVertical !== undefined) + { + sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical); + } + + if (!obj.visible) + { + sprite.visible = false; + } + + // Set properties the class may have, or setData those it doesn't + for (var key in obj.properties) + { + if (sprite[key] !== undefined) + { + sprite[key] = obj.properties[key]; + } + else + { + sprite.setData(key, obj.properties[key]); + } + } + + if (container) + { + container.add(sprite); + } + else + { + scene.add.existing(sprite); + } + + results.push(sprite); + } + } + + return results; + }, + + /** + * Creates a Sprite for every object matching the given tile indexes in the layer. You can + * optionally specify if each tile will be replaced with a new tile after the Sprite has been + * created. This is useful if you want to lay down special tiles in a level that are converted to + * Sprites, but want to replace the tile itself with a floor tile or similar once converted. + * + * @method Phaser.Tilemaps.Tilemap#createFromTiles + * @since 3.0.0 + * + * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. + * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted + * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a + * one-to-one mapping with the indexes array. + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} spriteConfig - The config object to pass into the Sprite creator (i.e. scene.make.sprite). + * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.GameObjects.Sprite[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); + }, + + /** + * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the + * specified index. Tiles will be set to collide if the given index is a colliding index. + * Collision information in the region will be recalculated. + * + * If no layer specified, the map's current layer is used. + * This cannot be applied to StaticTilemapLayers. + * + * @method Phaser.Tilemaps.Tilemap#fill + * @since 3.0.0 + * + * @param {number} index - The tile index to fill the area with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); + + return this; + }, + + /** + * For each object in the given object layer, run the given filter callback function. Any + * objects that pass the filter test (i.e. where the callback returns true) will returned as a + * new array. Similar to Array.prototype.Filter in vanilla JS. + * + * @method Phaser.Tilemaps.Tilemap#filterObjects + * @since 3.0.0 + * + * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. + * @param {TilemapFilterCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * + * @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid. + */ + filterObjects: function (objectLayer, callback, context) + { + if (typeof objectLayer === 'string') + { + var name = objectLayer; + + objectLayer = this.getObjectLayer(objectLayer); + + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; + } + } + + return objectLayer.objects.filter(callback, context); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns + * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#filterTiles + * @since 3.0.0 + * + * @param {function} callback - The callback. Each tile in the given area will be passed to this + * callback as the first and only parameter. The callback should return true for tiles that pass the + * filter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * Searches the entire map layer for the first tile matching the given index, then returns that Tile + * object. If no match is found, it returns null. The search starts from the top-left tile and + * continues horizontally until it hits the end of the row, then it drops down to the next column. + * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to + * the top-left. + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#findByIndex + * @since 3.0.0 + * + * @param {number} index - The tile index value to search for. + * @param {number} [skip=0] - The number of times to skip a matching tile before returning. + * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + */ + findByIndex: function (findIndex, skip, reverse, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); + }, + + /** + * Find the first object in the given object layer that satisfies the provided testing function. + * I.e. finds the first object for which `callback` returns true. Similar to + * Array.prototype.find in vanilla JS. + * + * @method Phaser.Tilemaps.Tilemap#findObject + * @since 3.0.0 + * + * @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance. + * @param {TilemapFindCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * + * @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found. + */ + findObject: function (objectLayer, callback, context) + { + if (typeof objectLayer === 'string') + { + var name = objectLayer; + + objectLayer = this.getObjectLayer(objectLayer); + + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; + } + } + + return objectLayer.objects.find(callback, context) || null; + }, + + /** + * Find the first tile in the given rectangular area (in tile coordinates) of the layer that + * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns + * true. Similar to Array.prototype.find in vanilla JS. + * If no layer specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#findTile + * @since 3.0.0 + * + * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + */ + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * callback. Similar to Array.prototype.forEach in vanilla JS. + * + * If no layer specified, the map's current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#forEachTile + * @since 3.0.0 + * + * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + + return this; + }, + + /** + * Gets the image layer index based on its name. + * + * @method Phaser.Tilemaps.Tilemap#getImageIndex + * @since 3.0.0 + * + * @param {string} name - The name of the image to get. + * + * @return {number} The index of the image in this tilemap, or null if not found. + */ + getImageIndex: function (name) + { + return this.getIndex(this.images, name); + }, + + /** + * Return a list of all valid imagelayer names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getImageLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap. + */ + getImageLayerNames: function () + { + if (!this.images || !Array.isArray(this.images)) + { + return []; + } + + return this.images.map(function (image) + { + return image.name; + }); + }, + + /** + * Internally used. Returns the index of the object in one of the Tilemaps arrays whose name + * property matches the given `name`. + * + * @method Phaser.Tilemaps.Tilemap#getIndex + * @since 3.0.0 + * + * @param {array} location - The Tilemap array to search. + * @param {string} name - The name of the array element to get. + * + * @return {number} The index of the element in the array, or null if not found. + */ + getIndex: function (location, name) + { + for (var i = 0; i < location.length; i++) + { + if (location[i].name === name) + { + return i; + } + } + + return null; + }, + + /** + * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. + * + * @method Phaser.Tilemaps.Tilemap#getLayer + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or Tilemap Layer. If not given will default to the maps current layer index. + * + * @return {Phaser.Tilemaps.LayerData} The corresponding LayerData within this.layers. + */ + getLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + return (index !== null) ? this.layers[index] : null; + }, + + /** + * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. + * + * @method Phaser.Tilemaps.Tilemap#getObjectLayer + * @since 3.0.0 + * + * @param {string} [name] - The name of the object layer from Tiled. + * + * @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null. + */ + getObjectLayer: function (name) + { + var index = this.getIndex(this.objects, name); + + return (index !== null) ? this.objects[index] : null; + }, + + /** + * Return a list of all valid objectgroup names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getObjectLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap. + */ + getObjectLayerNames: function () + { + if (!this.objects || !Array.isArray(this.objects)) + { + return []; + } + + return this.objects.map(function (object) + { + return object.name; + }); + }, + + /** + * Gets the LayerData index of the given `layer` within this.layers, or null if an invalid + * `layer` is given. + * + * @method Phaser.Tilemaps.Tilemap#getLayerIndex + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a Tilemap Layer. If not given will default to the map's current layer index. + * + * @return {number} The LayerData index within this.layers. + */ + getLayerIndex: function (layer) + { + if (layer === undefined) + { + return this.currentLayerIndex; + } + else if (typeof layer === 'string') + { + return this.getLayerIndexByName(layer); + } + else if (typeof layer === 'number' && layer < this.layers.length) + { + return layer; + } + else if (layer instanceof TilemapLayer) + { + return layer.layerIndex; + } + else + { + return null; + } + }, + + /** + * Gets the index of the LayerData within this.layers that has the given `name`, or null if an + * invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getLayerIndexByName + * @since 3.0.0 + * + * @param {string} name - The name of the layer to get. + * + * @return {number} The LayerData index within this.layers. + */ + getLayerIndexByName: function (name) + { + return this.getIndex(this.layers, name); + }, + + /** + * Gets a tile at the given tile coordinates from the given layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTileAt + * @since 3.0.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {boolean} [nonNull] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + getTileAt: function (tileX, tileY, nonNull, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); + }, + + /** + * Gets a tile at the given world coordinates from the given layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - X position to get the tile from (given in pixels) + * @param {number} worldY - Y position to get the tile from (given in pixels) + * @param {boolean} [nonNull] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); + }, + + /** + * Return a list of all valid tilelayer names loaded in this Tilemap. + * + * @method Phaser.Tilemaps.Tilemap#getTileLayerNames + * @since 3.21.0 + * + * @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap. + */ + getTileLayerNames: function () + { + if (!this.layers || !Array.isArray(this.layers)) + { + return []; + } + + return this.layers.map(function (layer) + { + return layer.name; + }); + }, + + /** + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithin + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithin: function (tileX, tileY, width, height, filteringOptions, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + }, + + /** + * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, + * Line, Rectangle or Triangle. The shape should be in world coordinates. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithinShape + * @since 3.0.0 + * + * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithinShape: function (shape, filteringOptions, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); + }, + + /** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + */ + getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); + }, + + /** + * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getTileset + * @since 3.14.0 + * + * @param {string} name - The name of the Tileset to get. + * + * @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found. + */ + getTileset: function (name) + { + var index = this.getIndex(this.tilesets, name); + + return (index !== null) ? this.tilesets[index] : null; + }, + + /** + * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an + * invalid `name` is given. + * + * @method Phaser.Tilemaps.Tilemap#getTilesetIndex + * @since 3.0.0 + * + * @param {string} name - The name of the Tileset to get. + * + * @return {number} The Tileset index within this.tilesets. + */ + getTilesetIndex: function (name) + { + return this.getIndex(this.tilesets, name); + }, + + /** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#hasTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ + hasTileAt: function (tileX, tileY, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.HasTileAt(tileX, tileY, layer); + }, + + /** + * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + */ + hasTileAtWorldXY: function (worldX, worldY, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); + }, + + /** + * The LayerData object that is currently selected in the map. You can set this property using + * any type supported by setLayer. + * + * @name Phaser.Tilemaps.Tilemap#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.0.0 + */ + layer: { + get: function () + { + return this.layers[this.currentLayerIndex]; + }, + + set: function (layer) + { + this.setLayer(layer); + } + }, + + /** + * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index + * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified + * location. If you pass in an index, only the index at the specified location will be changed. + * Collision information will be recalculated at the specified location. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTileAt + * @since 3.0.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid or the coordinates were out of bounds. + */ + putTileAt: function (tile, tileX, tileY, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer); + }, + + /** + * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either + * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the + * specified location. If you pass in an index, only the index at the specified location will be + * changed. Collision information will be recalculated at the specified location. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTileAtWorldXY + * @since 3.0.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer); + }, + + /** + * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified + * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, + * all attributes will be copied over to the specified location. If you pass in an index, only the + * index at the specified location will be changed. Collision information will be recalculated + * within the region tiles were changed. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#putTilesAt + * @since 3.0.0 + * + * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces, layer) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer); + + return this; + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then + * those will be used for randomly assigning new tile indexes. If an array is not provided, the + * indexes found within the region (excluding -1) will be used for randomly assigning new tile + * indexes. This method only modifies tile indexes and does not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#randomize + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + randomize: function (tileX, tileY, width, height, indexes, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer); + + return this; + }, + + /** + * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting + * faces are used internally for optimizing collisions against tiles. This method is mostly used + * internally to optimize recalculating faces when only one tile has been changed. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#calculateFacesAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + calculateFacesAt: function (tileX, tileY, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.CalculateFacesAt(tileX, tileY, layer); + + return this; + }, + + /** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#calculateFacesWithin + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + calculateFacesWithin: function (tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Removes the given TilemapLayer from this Tilemap without destroying it. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeLayer + * @since 3.17.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be removed. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + removeLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + SpliceOne(this.layers, index); + + for (var i = index; i < this.layers.length; i++) + { + if (this.layers[i].tilemapLayer) + { + this.layers[i].tilemapLayer.layerIndex--; + } + } + + if (this.currentLayerIndex === index) + { + this.currentLayerIndex = 0; + } + + return this; + } + else + { + return null; + } + }, + + /** + * Destroys the given TilemapLayer and removes it from this Tilemap. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#destroyLayer + * @since 3.17.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be destroyed. + * + * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + */ + destroyLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + layer = this.layers[index]; + + layer.destroy(); + + SpliceOne(this.layers, index); + + if (this.currentLayerIndex === index) + { + this.currentLayerIndex = 0; + } + + return this; + } + else + { + return null; + } + }, + + /** + * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. + * + * @method Phaser.Tilemaps.Tilemap#removeAllLayers + * @since 3.0.0 + * + * @return {this} This Tilemap object. + */ + removeAllLayers: function () + { + var layers = this.layers; + + for (var i = 0; i < layers.length; i++) + { + if (layers[i].tilemapLayer) + { + layers[i].tilemapLayer.destroy(false); + } + } + + layers.length = 0; + + this.currentLayerIndex = 0; + + return this; + }, + + /** + * Removes the given Tile, or an array of Tiles, from the layer to which they belong, + * and optionally recalculates the collision information. + * + * @method Phaser.Tilemaps.Tilemap#removeTile + * @since 3.17.0 + * + * @param {(Phaser.Tilemaps.Tile|Phaser.Tilemaps.Tile[])} tiles - The Tile to remove, or an array of Tiles. + * @param {number} [replaceIndex=-1] - After removing the Tile, insert a brand new Tile into its location with the given index. Leave as -1 to just remove the tile. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed. + */ + removeTile: function (tiles, replaceIndex, recalculateFaces) + { + if (replaceIndex === undefined) { replaceIndex = -1; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + var removed = []; + + if (!Array.isArray(tiles)) + { + tiles = [ tiles ]; + } + + for (var i = 0; i < tiles.length; i++) + { + var tile = tiles[i]; + + removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); + + if (replaceIndex > -1) + { + this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); + } + } + + return removed; + }, + + /** + * Removes the tile at the given tile coordinates in the specified layer and updates the layers collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeTileAt + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns the Tile that was removed, or null if the layer given was invalid. + */ + removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces, layer) + { + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); + }, + + /** + * Removes the tile at the given world coordinates in the specified layer and updates the layers collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#removeTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + */ + removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) + { + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); + }, + + /** + * Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to + * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles + * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation + * wherever you want on the screen. + * + * If no layer is specified, the maps current layer is used. + * + * **Note:** This method currently only works with orthogonal tilemap layers. + * + * @method Phaser.Tilemaps.Tilemap#renderDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + renderDebug: function (graphics, styleConfig, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + if (this.orientation === ORIENTATION.ORTHOGONAL) + { + TilemapComponents.RenderDebug(graphics, styleConfig, layer); + } + + return this; + }, + + /** + * Draws a debug representation of all layers within this Tilemap to the given Graphics object. + * + * This is helpful when you want to get a quick idea of which of your tiles are colliding and which + * have interesting faces. The tiles are drawn starting at (0, 0) in the Graphics, allowing you to + * place the debug representation wherever you want on the screen. + * + * @method Phaser.Tilemaps.Tilemap#renderDebugFull + * @since 3.17.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * + * @return {this} This Tilemap instance. + */ + renderDebugFull: function (graphics, styleConfig) + { + var layers = this.layers; + + for (var i = 0; i < layers.length; i++) + { + TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); + } + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#replaceByIndex + * @since 3.0.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Sets collision on the given tile or tiles within a layer by index. You can pass in either a + * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if + * collision will be enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollision + * @since 3.0.0 + * + * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollision: function (indexes, collides, recalculateFaces, layer, updateLayer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + if (updateLayer === undefined) { updateLayer = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); + + return this; + }, + + /** + * Sets collision on a range of tiles in a layer whose index is between the specified `start` and + * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set + * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be + * enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionBetween + * @since 3.0.0 + * + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property + * that matches the given properties object, its collision flag will be set. The `collides` + * parameter controls if collision will be enabled (true) or disabled (false). Passing in + * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that + * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can + * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a + * "types" property that matches any of those values, its collision flag will be updated. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionByProperty + * @since 3.0.0 + * + * @param {object} properties - An object with tile properties and corresponding values that should be checked. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionByProperty: function (properties, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on all tiles in the given layer, except for tiles that have an index specified in + * the given array. The `collides` parameter controls if collision will be enabled (true) or + * disabled (false). Tile indexes not currently in the layer are not affected. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion + * @since 3.0.0 + * + * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionByExclusion: function (indexes, collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking each tiles collision group data + * (typically defined in Tiled within the tileset collision editor). If any objects are found within + * a tiles collision group, the tiles colliding information will be set. The `collides` parameter + * controls if collision will be enabled (true) or disabled (false). + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup + * @since 3.0.0 + * + * @param {boolean} [collides] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setCollisionFromCollisionGroup: function (collides, recalculateFaces, layer) + { + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); + + return this; + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all + * tiles on this layer that have the same index. If a callback is already set for the tile index it + * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile + * at a specific location on the map then see `setTileLocationCallback`. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setTileIndexCallback + * @since 3.0.0 + * + * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. All values should be integers. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setTileIndexCallback: function (indexes, callback, callbackContext, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer); + + return this; + }, + + /** + * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to + * remove it. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#setTileLocationCallback + * @since 3.0.0 + * + * @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} width - How many tiles wide from the `tileX` index the area will be. + * @param {number} height - How many tiles tall from the `tileY` index the area will be. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} [callbackContext] - The context under which the callback is called. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); + + return this; + }, + + /** + * Sets the current layer to the LayerData associated with `layer`. + * + * @method Phaser.Tilemaps.Tilemap#setLayer + * @since 3.0.0 + * + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. + * + * @return {this} This Tilemap object. + */ + setLayer: function (layer) + { + var index = this.getLayerIndex(layer); + + if (index !== null) + { + this.currentLayerIndex = index; + } + + return this; + }, + + /** + * Sets the base tile size for the map. Note: this does not necessarily match the tileWidth and + * tileHeight for all layers. This also updates the base size on all tiles across all layers. + * + * @method Phaser.Tilemaps.Tilemap#setBaseTileSize + * @since 3.0.0 + * + * @param {number} tileWidth - The width of the tiles the map uses for calculations. + * @param {number} tileHeight - The height of the tiles the map uses for calculations. + * + * @return {this} This Tilemap object. + */ + setBaseTileSize: function (tileWidth, tileHeight) + { + this.tileWidth = tileWidth; + this.tileHeight = tileHeight; + this.widthInPixels = this.width * tileWidth; + this.heightInPixels = this.height * tileHeight; + + // Update the base tile size on all layers & tiles + for (var i = 0; i < this.layers.length; i++) + { + this.layers[i].baseTileWidth = tileWidth; + this.layers[i].baseTileHeight = tileHeight; + + var mapData = this.layers[i].data; + var mapWidth = this.layers[i].width; + var mapHeight = this.layers[i].height; + + for (var row = 0; row < mapHeight; row++) + { + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; + + if (tile !== null) + { + tile.setSize(undefined, undefined, tileWidth, tileHeight); + } + } + } + } + + return this; + }, + + /** + * Sets the tile size for a specific `layer`. Note: this does not necessarily match the maps + * tileWidth and tileHeight for all layers. This will set the tile size for the layer and any + * tiles the layer has. + * + * @method Phaser.Tilemaps.Tilemap#setLayerTileSize + * @since 3.0.0 + * + * @param {number} tileWidth - The width of the tiles (in pixels) in the layer. + * @param {number} tileHeight - The height of the tiles (in pixels) in the layer. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index. + * + * @return {this} This Tilemap object. + */ + setLayerTileSize: function (tileWidth, tileHeight, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return this; } + + layer.tileWidth = tileWidth; + layer.tileHeight = tileHeight; + + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + + for (var row = 0; row < mapHeight; row++) + { + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; + + if (tile !== null) + { + tile.setSize(tileWidth, tileHeight); + } + } + } + + return this; + }, + + /** + * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given + * layer. It will only randomize the tiles in that area, so if they're all the same nothing will + * appear to have changed! This method only modifies tile indexes and does not change collision + * information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#shuffle + * @since 3.0.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + shuffle: function (tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.Shuffle(tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision + * information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#swapByIndex + * @since 3.0.0 + * + * @param {number} tileA - First tile index. + * @param {number} tileB - Second tile index. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + swapByIndex: function (indexA, indexB, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); + + return this; + }, + + /** + * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldX + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + tileToWorldX: function (tileX, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldX(tileX, camera, layer); + }, + + /** + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldY + * @since 3.0.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + tileToWorldY: function (tileX, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldY(tileX, camera, layer); + }, + + /** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#tileToWorldXY + * @since 3.0.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid. + */ + tileToWorldXY: function (tileX, tileY, vec2, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. New indexes are drawn from the given + * weightedIndexes array. An example weighted array: + * + * [ + * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 + * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 + * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 + * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 + * ] + * + * The probability of any index being picked is (the indexs weight) / (sum of all weights). This + * method only modifies tile indexes and does not change collision information. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#weightedRandomize + * @since 3.0.0 + * + * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + */ + weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); + + return this; + }, + + /** + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileX + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + worldToTileX: function (worldX, snapToFloor, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); + }, + + /** + * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileY + * @since 3.0.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?number} Returns a number, or null if the layer given was invalid. + */ + worldToTileY: function (worldY, snapToFloor, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); + }, + + /** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#worldToTileXY + * @since 3.0.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used. + * + * @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid. + */ + worldToTileXY: function (worldX, worldY, snapToFloor, vec2, camera, layer) + { + layer = this.getLayer(layer); + + if (layer === null) { return null; } + + return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); + }, + + /** + * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any + * TilemapLayers that have been created. + * + * @method Phaser.Tilemaps.Tilemap#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.removeAllLayers(); + + this.tilesets.length = 0; + this.objects.length = 0; + + this.scene = null; + } + +}); + +module.exports = Tilemap; + + +/***/ }), +/* 577 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var Components = __webpack_require__(11); +var GameObject = __webpack_require__(15); +var TilemapComponents = __webpack_require__(247); +var TilemapLayerRender = __webpack_require__(1449); + +/** + * @classdesc + * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination + * with one, or more, Tilesets. + * + * @class TilemapLayer + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.50.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. + * @param {Phaser.Tilemaps.Tilemap} tilemap - The Tilemap this layer is a part of. + * @param {number} layerIndex - The index of the LayerData associated with this layer. + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + * @param {number} [x=0] - The world x position where the top left of this layer will be placed. + * @param {number} [y=0] - The world y position where the top left of this layer will be placed. + */ +var TilemapLayer = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.ComputedSize, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Origin, + Components.Pipeline, + Components.Transform, + Components.Visible, + Components.ScrollFactor, + TilemapLayerRender + ], + + initialize: + + function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) + { + GameObject.call(this, scene, 'TilemapLayer'); + + /** + * Used internally by physics system to perform fast type checks. + * + * @name Phaser.Tilemaps.TilemapLayer#isTilemap + * @type {boolean} + * @readonly + * @since 3.50.0 + */ + this.isTilemap = true; + + /** + * The Tilemap that this layer is a part of. + * + * @name Phaser.Tilemaps.TilemapLayer#tilemap + * @type {Phaser.Tilemaps.Tilemap} + * @since 3.50.0 + */ + this.tilemap = tilemap; + + /** + * The index of the LayerData associated with this layer. + * + * @name Phaser.Tilemaps.TilemapLayer#layerIndex + * @type {number} + * @since 3.50.0 + */ + this.layerIndex = layerIndex; + + /** + * The LayerData associated with this layer. LayerData can only be associated with one + * tilemap layer. + * + * @name Phaser.Tilemaps.TilemapLayer#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.50.0 + */ + this.layer = tilemap.layers[layerIndex]; + + // Link the LayerData with this static tilemap layer + this.layer.tilemapLayer = this; + + /** + * An array of `Tileset` objects associated with this layer. + * + * @name Phaser.Tilemaps.TilemapLayer#tileset + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 + */ + this.tileset = []; + + /** + * The total number of tiles drawn by the renderer in the last frame. + * + * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.tilesDrawn = 0; + + /** + * The total number of tiles in this layer. Updated every frame. + * + * @name Phaser.Tilemaps.TilemapLayer#tilesTotal + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.tilesTotal = this.layer.width * this.layer.height; + + /** + * Used internally during rendering. This holds the tiles that are visible within the Camera. + * + * @name Phaser.Tilemaps.TilemapLayer#culledTiles + * @type {Phaser.Tilemaps.Tile[]} + * @since 3.50.0 + */ + this.culledTiles = []; + + /** + * You can control if the camera should cull tiles on this layer before rendering them or not. + * + * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. + * + * However, there are some instances when you may wish to disable this, and toggling this flag allows + * you to do so. Also see `setSkipCull` for a chainable method that does the same thing. + * + * @name Phaser.Tilemaps.TilemapLayer#skipCull + * @type {boolean} + * @since 3.50.0 + */ + this.skipCull = false; + + /** + * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. + * + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX + * @type {number} + * @default 1 + * @since 3.50.0 + */ + this.cullPaddingX = 1; + + /** + * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. + * + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY + * @type {number} + * @default 1 + * @since 3.50.0 + */ + this.cullPaddingY = 1; + + /** + * The callback that is invoked when the tiles are culled. + * + * It will call a different function based on the map orientation: + * + * Orthogonal (the default) is `TilemapComponents.CullTiles` + * Isometric is `TilemapComponents.IsometricCullTiles` + * Hexagonal is `TilemapComponents.HexagonalCullTiles` + * Staggered is `TilemapComponents.StaggeredCullTiles` + * + * However, you can override this to call any function you like. + * + * It will be sent 4 arguments: + * + * 1. The Phaser.Tilemaps.LayerData object for this Layer + * 2. The Camera that is culling the layer. You can check its `dirty` property to see if it has changed since the last cull. + * 3. A reference to the `culledTiles` array, which should be used to store the tiles you want rendered. + * 4. The Render Order constant. + * + * See the `TilemapComponents.CullTiles` source code for details on implementing your own culling system. + * + * @name Phaser.Tilemaps.TilemapLayer#cullCallback + * @type {function} + * @since 3.50.0 + */ + this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); + + /** + * The rendering (draw) order of the tiles in this layer. + * + * The default is 0 which is 'right-down', meaning it will draw the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * This can be changed via the `setRenderOrder` method. + * + * @name Phaser.Tilemaps.TilemapLayer#_renderOrder + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + this._renderOrder = 0; + + /** + * An array holding the mapping between the tile indexes and the tileset they belong to. + * + * @name Phaser.Tilemaps.TilemapLayer#gidMap + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 + */ + this.gidMap = []; + + this.setTilesets(tileset); + this.setAlpha(this.layer.alpha); + this.setPosition(x, y); + this.setOrigin(); + this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height); + + this.initPipeline(); + }, + + /** + * Populates the internal `tileset` array with the Tileset references this Layer requires for rendering. + * + * @method Phaser.Tilemaps.TilemapLayer#setTilesets + * @private + * @since 3.50.0 + * + * @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object. + */ + setTilesets: function (tilesets) + { + var gidMap = []; + var setList = []; + var map = this.tilemap; + + if (!Array.isArray(tilesets)) + { + tilesets = [ tilesets ]; + } + + for (var i = 0; i < tilesets.length; i++) + { + var tileset = tilesets[i]; + + if (typeof tileset === 'string') + { + tileset = map.getTileset(tileset); + } + + if (tileset) + { + setList.push(tileset); + + var s = tileset.firstgid; + + for (var t = 0; t < tileset.total; t++) + { + gidMap[s + t] = tileset; + } + } + } + + this.gidMap = gidMap; + this.tileset = setList; + }, + + /** + * Sets the rendering (draw) order of the tiles in this layer. + * + * The default is 'right-down', meaning it will order the tiles starting from the top-left, + * drawing to the right and then moving down to the next row. + * + * The draw orders are: + * + * 0 = right-down + * 1 = left-down + * 2 = right-up + * 3 = left-up + * + * Setting the render order does not change the tiles or how they are stored in the layer, + * it purely impacts the order in which they are rendered. + * + * You can provide either an integer (0 to 3), or the string version of the order. + * + * @method Phaser.Tilemaps.TilemapLayer#setRenderOrder + * @since 3.50.0 + * + * @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'. + * + * @return {this} This Tilemap Layer object. + */ + setRenderOrder: function (renderOrder) + { + var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; + + if (typeof renderOrder === 'string') + { + renderOrder = orders.indexOf(renderOrder); + } + + if (renderOrder >= 0 && renderOrder < 4) + { + this._renderOrder = renderOrder; + } + + return this; + }, + + /** + * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting + * faces are used internally for optimizing collisions against tiles. This method is mostly used + * internally to optimize recalculating faces when only one tile has been changed. + * + * @method Phaser.Tilemaps.TilemapLayer#calculateFacesAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate. + * @param {number} tileY - The y coordinate. + * + * @return {this} This Tilemap Layer object. + */ + calculateFacesAt: function (tileX, tileY) + { + TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer); + + return this; + }, + + /** + * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the + * layer. Interesting faces are used internally for optimizing collisions against tiles. This method + * is mostly used internally. + * + * @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + calculateFacesWithin: function (tileX, tileY, width, height) + { + TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Creates a Sprite for every object matching the given tile indexes in the layer. You can + * optionally specify if each tile will be replaced with a new tile after the Sprite has been + * created. This is useful if you want to lay down special tiles in a level that are converted to + * Sprites, but want to replace the tile itself with a floor tile or similar once converted. + * + * @method Phaser.Tilemaps.TilemapLayer#createFromTiles + * @since 3.50.0 + * + * @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from. + * @param {(number|array)} replacements - The tile index, or array of indexes, to change a converted + * tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a + * one-to-one mapping with the indexes array. + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e. + * scene.make.sprite). + * @param {Phaser.Scene} [scene] - The Scene to create the Sprites within. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when determining the world XY + * + * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. + */ + createFromTiles: function (indexes, replacements, spriteConfig, scene, camera) + { + return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer); + }, + + /** + * Returns the tiles in the given layer that are within the cameras viewport. + * This is used internally during rendering. + * + * @method Phaser.Tilemaps.TilemapLayer#cull + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render. + */ + cull: function (camera) + { + return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder); + }, + + /** + * Copies the tiles in the source rectangular area to a new destination (all specified in tile + * coordinates) within the layer. This copies all tile properties & recalculates collision + * information in the destination region. + * + * @method Phaser.Tilemaps.TilemapLayer#copy + * @since 3.50.0 + * + * @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels. + * @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels. + * @param {number} width - The width of the area to copy, in tiles, not pixels. + * @param {number} height - The height of the area to copy, in tiles, not pixels. + * @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels. + * @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) + { + TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the + * specified index. Tiles will be set to collide if the given index is a colliding index. + * Collision information in the region will be recalculated. + * + * @method Phaser.Tilemaps.TilemapLayer#fill + * @since 3.50.0 + * + * @param {number} index - The tile index to fill the area with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + fill: function (index, tileX, tileY, width, height, recalculateFaces) + { + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); + + return this; + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * filter callback function. Any tiles that pass the filter test (i.e. where the callback returns + * true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#filterTiles + * @since 3.50.0 + * + * @param {function} callback - The callback. Each tile in the given area will be passed to this + * callback as the first and only parameter. The callback should return true for tiles that pass the + * filter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ + filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * Searches the entire map layer for the first tile matching the given index, then returns that Tile + * object. If no match is found, it returns null. The search starts from the top-left tile and + * continues horizontally until it hits the end of the row, then it drops down to the next column. + * If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to + * the top-left. + * + * @method Phaser.Tilemaps.TilemapLayer#findByIndex + * @since 3.50.0 + * + * @param {number} index - The tile index value to search for. + * @param {number} [skip=0] - The number of times to skip a matching tile before returning. + * @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. + * + * @return {Phaser.Tilemaps.Tile} The first matching Tile object. + */ + findByIndex: function (findIndex, skip, reverse) + { + return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer); + }, + + /** + * Find the first tile in the given rectangular area (in tile coordinates) of the layer that + * satisfies the provided testing function. I.e. finds the first tile for which `callback` returns + * true. Similar to Array.prototype.find in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#findTile + * @since 3.50.0 + * + * @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location. + */ + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given + * callback. Similar to Array.prototype.forEach in vanilla JS. + * + * @method Phaser.Tilemaps.TilemapLayer#forEachTile + * @since 3.50.0 + * + * @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. + * @param {object} [context] - The context, or scope, under which the callback should be run. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {this} This Tilemap Layer object. + */ + forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + { + TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + + return this; + }, + + /** + * Gets a tile at the given tile coordinates from the given layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTileAt + * @since 3.50.0 + * + * @param {number} tileX - X position to get the tile from (given in tile units, not pixels). + * @param {number} tileY - Y position to get the tile from (given in tile units, not pixels). + * @param {boolean} [nonNull=false] - If true getTile won't return null for empty tiles, but a Tile object with an index of -1. + * + * @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid. + */ + getTileAt: function (tileX, tileY, nonNull) + { + return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer); + }, + + /** + * Gets a tile at the given world coordinates from the given layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - X position to get the tile from (given in pixels) + * @param {number} worldY - Y position to get the tile from (given in pixels) + * @param {boolean} [nonNull=false] - If true, function won't return null for empty tiles, but a Tile object with an index of -1. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. + */ + getTileAtWorldXY: function (worldX, worldY, nonNull, camera) + { + return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer); + }, + + /** + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + */ + getTilesWithin: function (tileX, tileY, width, height, filteringOptions) + { + return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer); + }, + + /** + * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, + * Line, Rectangle or Triangle. The shape should be in world coordinates. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape + * @since 3.50.0 + * + * @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. + */ + getTilesWithinShape: function (shape, filteringOptions, camera) + { + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); + }, + + /** + * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The world x coordinate for the top-left of the area. + * @param {number} worldY - The world y coordinate for the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + */ + getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera) + { + return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer); + }, + + /** + * Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @method Phaser.Tilemaps.TilemapLayer#hasTileAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * + * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + */ + hasTileAt: function (tileX, tileY) + { + return TilemapComponents.HasTileAt(tileX, tileY, this.layer); + }, + + /** + * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns + * false if there is no tile or if the tile at that location has an index of -1. + * + * @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return. + * + * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + */ + hasTileAtWorldXY: function (worldX, worldY, camera) + { + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); + }, + + /** + * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index + * or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified + * location. If you pass in an index, only the index at the specified location will be changed. + * Collision information will be recalculated at the specified location. + * + * @method Phaser.Tilemaps.TilemapLayer#putTileAt + * @since 3.50.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + */ + putTileAt: function (tile, tileX, tileY, recalculateFaces) + { + return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer); + }, + + /** + * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either + * an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the + * specified location. If you pass in an index, only the index at the specified location will be + * changed. Collision information will be recalculated at the specified location. + * + * @method Phaser.Tilemaps.TilemapLayer#putTileAtWorldXY + * @since 3.50.0 + * + * @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object. + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + */ + putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera) + { + return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer); + }, + + /** + * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified + * layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile, + * all attributes will be copied over to the specified location. If you pass in an index, only the + * index at the specified location will be changed. Collision information will be recalculated + * within the region tiles were changed. + * + * @method Phaser.Tilemaps.TilemapLayer#putTilesAt + * @since 3.50.0 + * + * @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {this} This Tilemap Layer object. + */ + putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces) + { + TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer); + + return this; + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. If an array of indexes is passed in, then + * those will be used for randomly assigning new tile indexes. If an array is not provided, the + * indexes found within the region (excluding -1) will be used for randomly assigning new tile + * indexes. This method only modifies tile indexes and does not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#randomize + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization. + * + * @return {this} This Tilemap Layer object. + */ + randomize: function (tileX, tileY, width, height, indexes) + { + TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); + + return this; + }, + + /** + * Removes the tile at the given tile coordinates in the specified layer and updates the layers + * collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#removeTileAt + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * + * @return {Phaser.Tilemaps.Tile} A Tile object. + */ + removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces) + { + return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer); + }, + + /** + * Removes the tile at the given world coordinates in the specified layer and updates the layers + * collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate, in pixels. + * @param {number} worldY - The y coordinate, in pixels. + * @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1. + * @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location. + */ + removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera) + { + return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer); + }, + + /** + * Draws a debug representation of the layer to the given Graphics. This is helpful when you want to + * get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles + * are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation + * wherever you want on the screen. + * + * @method Phaser.Tilemaps.TilemapLayer#renderDebug + * @since 3.50.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing. + * + * @return {this} This Tilemap Layer object. + */ + renderDebug: function (graphics, styleConfig) + { + TilemapComponents.RenderDebug(graphics, styleConfig, this.layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `findIndex` and updates their index to match `newIndex`. This only modifies the index and does + * not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#replaceByIndex + * @since 3.50.0 + * + * @param {number} findIndex - The index of the tile to search for. + * @param {number} newIndex - The index of the tile to replace it with. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height) + { + TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * You can control if the Cameras should cull tiles before rendering them or not. + * + * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. + * + * However, there are some instances when you may wish to disable this. + * + * @method Phaser.Tilemaps.TilemapLayer#setSkipCull + * @since 3.50.0 + * + * @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again. + * + * @return {this} This Tilemap Layer object. + */ + setSkipCull: function (value) + { + if (value === undefined) { value = true; } + + this.skipCull = value; + + return this; + }, + + /** + * When a Camera culls the tiles in this layer it does so using its view into the world, building up a + * rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size + * of this 'cull rectangle', especially if you plan on rotating the Camera viewing the layer. Do so + * by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px + * and you set `paddingX` to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale) + * + * @method Phaser.Tilemaps.TilemapLayer#setCullPadding + * @since 3.50.0 + * + * @param {number} [paddingX=1] - The amount of extra horizontal tiles to add to the cull check padding. + * @param {number} [paddingY=1] - The amount of extra vertical tiles to add to the cull check padding. + * + * @return {this} This Tilemap Layer object. + */ + setCullPadding: function (paddingX, paddingY) + { + if (paddingX === undefined) { paddingX = 1; } + if (paddingY === undefined) { paddingY = 1; } + + this.cullPaddingX = paddingX; + this.cullPaddingY = paddingY; + + return this; + }, + + /** + * Sets collision on the given tile or tiles within a layer by index. You can pass in either a + * single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if + * collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollision + * @since 3.50.0 + * + * @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. + * + * @return {this} This Tilemap Layer object. + */ + setCollision: function (indexes, collides, recalculateFaces, updateLayer) + { + TilemapComponents.SetCollision(indexes, collides, recalculateFaces, this.layer, updateLayer); + + return this; + }, + + /** + * Sets collision on a range of tiles in a layer whose index is between the specified `start` and + * `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set + * collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be + * enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween + * @since 3.50.0 + * + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionBetween: function (start, stop, collides, recalculateFaces) + { + TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property + * that matches the given properties object, its collision flag will be set. The `collides` + * parameter controls if collision will be enabled (true) or disabled (false). Passing in + * `{ collides: true }` would update the collision flag on any tiles with a "collides" property that + * has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can + * also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a + * "types" property that matches any of those values, its collision flag will be updated. + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionByProperty + * @since 3.50.0 + * + * @param {object} properties - An object with tile properties and corresponding values that should be checked. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionByProperty: function (properties, collides, recalculateFaces) + { + TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on all tiles in the given layer, except for tiles that have an index specified in + * the given array. The `collides` parameter controls if collision will be enabled (true) or + * disabled (false). Tile indexes not currently in the layer are not affected. + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion + * @since 3.50.0 + * + * @param {number[]} indexes - An array of the tile indexes to not be counted for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionByExclusion: function (indexes, collides, recalculateFaces) + { + TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets collision on the tiles within a layer by checking each tiles collision group data + * (typically defined in Tiled within the tileset collision editor). If any objects are found within + * a tiles collision group, the tile's colliding information will be set. The `collides` parameter + * controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup + * @since 3.50.0 + * + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update. + * + * @return {this} This Tilemap Layer object. + */ + setCollisionFromCollisionGroup: function (collides, recalculateFaces) + { + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer); + + return this; + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all + * tiles on this layer that have the same index. If a callback is already set for the tile index it + * will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile + * at a specific location on the map then see setTileLocationCallback. + * + * @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback + * @since 3.50.0 + * + * @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * + * @return {this} This Tilemap Layer object. + */ + setTileIndexCallback: function (indexes, callback, callbackContext) + { + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer); + + return this; + }, + + /** + * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to + * remove it. + * + * @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * @param {function} [callback] - The callback that will be invoked when the tile is collided with. + * @param {object} [callbackContext] - The context, or scope, under which the callback is invoked. + * + * @return {this} This Tilemap Layer object. + */ + setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext) + { + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer); + + return this; + }, + + /** + * Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given + * layer. It will only randomize the tiles in that area, so if they're all the same nothing will + * appear to have changed! This method only modifies tile indexes and does not change collision + * information. + * + * @method Phaser.Tilemaps.TilemapLayer#shuffle + * @since 3.50.0 + * + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + shuffle: function (tileX, tileY, width, height) + { + TilemapComponents.Shuffle(tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching + * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision + * information. + * + * @method Phaser.Tilemaps.TilemapLayer#swapByIndex + * @since 3.50.0 + * + * @param {number} tileA - First tile index. + * @param {number} tileB - Second tile index. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + swapByIndex: function (indexA, indexB, tileX, tileY, width, height) + { + TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, this.layer); + + return this; + }, + + /** + * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldX + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The Tile X coordinate converted to pixels. + */ + tileToWorldX: function (tileX, camera) + { + return this.tilemap.tileToWorldX(tileX, camera, this); + }, + + /** + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldY + * @since 3.50.0 + * + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The Tile Y coordinate converted to pixels. + */ + tileToWorldY: function (tileY, camera) + { + return this.tilemap.tileToWorldY(tileY, camera, this); + }, + + /** + * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @method Phaser.Tilemaps.TilemapLayer#tileToWorldXY + * @since 3.50.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Math.Vector2} A Vector2 containing the world coordinates of the Tile. + */ + tileToWorldXY: function (tileX, tileY, point, camera) + { + return this.tilemap.tileToWorldXY(tileX, tileY, point, camera, this); + }, + + /** + * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the + * specified layer. Each tile will receive a new index. New indexes are drawn from the given + * weightedIndexes array. An example weighted array: + * + * [ + * { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8 + * { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8 + * { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8 + * { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8 + * ] + * + * The probability of any index being choose is (the index's weight) / (sum of all weights). This + * method only modifies tile indexes and does not change collision information. + * + * @method Phaser.Tilemaps.TilemapLayer#weightedRandomize + * @since 3.50.0 + * + * @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes. + * @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area. + * @param {number} [width] - How many tiles wide from the `tileX` index the area will be. + * @param {number} [height] - How many tiles tall from the `tileY` index the area will be. + * + * @return {this} This Tilemap Layer object. + */ + weightedRandomize: function (tileX, tileY, width, height, weightedIndexes) + { + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); + + return this; + }, + + /** + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileX + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The tile X coordinate based on the world value. + */ + worldToTileX: function (worldX, snapToFloor, camera) + { + return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this); + }, + + /** + * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the + * layers position, scale and scroll. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileY + * @since 3.50.0 + * + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {number} The tile Y coordinate based on the world value. + */ + worldToTileY: function (worldY, snapToFloor, camera) + { + return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); + }, + + /** + * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the + * layers position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @method Phaser.Tilemaps.TilemapLayer#worldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer. + * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values. + * + * @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values. + */ + worldToTileXY: function (worldX, worldY, snapToFloor, point, camera) + { + return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this); + }, + + /** + * Destroys this TilemapLayer and removes its link to the associated LayerData. + * + * @method Phaser.Tilemaps.TilemapLayer#destroy + * @since 3.50.0 + * + * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? + */ + destroy: function (removeFromTilemap) + { + if (removeFromTilemap === undefined) { removeFromTilemap = true; } + + if (!this.tilemap) + { + // Abort, we've already been destroyed + return; + } + + // Uninstall this layer only if it is still installed on the LayerData object + if (this.layer.tilemapLayer === this) + { + this.layer.tilemapLayer = undefined; + } + + if (removeFromTilemap) + { + this.tilemap.removeLayer(this); + } + + this.tilemap = undefined; + this.layer = undefined; + this.culledTiles.length = 0; + this.cullCallback = null; + + this.gidMap = []; + this.tileset = []; + + GameObject.prototype.destroy.call(this); + } + +}); + +module.exports = TilemapLayer; + + +/***/ }), +/* 578 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var GetFastValue = __webpack_require__(2); + +/** + * @classdesc + * A Timer Event represents a delayed function call. It's managed by a Scene's {@link Clock} and will call its function after a set amount of time has passed. The Timer Event can optionally repeat - i.e. call its function multiple times before finishing, or loop indefinitely. + * + * Because it's managed by a Clock, a Timer Event is based on game time, will be affected by its Clock's time scale, and will pause if its Clock pauses. + * + * @class TimerEvent + * @memberof Phaser.Time + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Time.TimerEventConfig} config - The configuration for the Timer Event, including its delay and callback. + */ +var TimerEvent = new Class({ + + initialize: + + function TimerEvent (config) + { + /** + * The delay in ms at which this TimerEvent fires. + * + * @name Phaser.Time.TimerEvent#delay + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 + */ + this.delay = 0; + + /** + * The total number of times this TimerEvent will repeat before finishing. + * + * @name Phaser.Time.TimerEvent#repeat + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 + */ + this.repeat = 0; + + /** + * If repeating this contains the current repeat count. + * + * @name Phaser.Time.TimerEvent#repeatCount + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatCount = 0; + + /** + * True if this TimerEvent loops, otherwise false. + * + * @name Phaser.Time.TimerEvent#loop + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.loop = false; + + /** + * The callback that will be called when the TimerEvent occurs. + * + * @name Phaser.Time.TimerEvent#callback + * @type {function} + * @since 3.0.0 + */ + this.callback; + + /** + * The scope in which the callback will be called. + * + * @name Phaser.Time.TimerEvent#callbackScope + * @type {object} + * @since 3.0.0 + */ + this.callbackScope; + + /** + * Additional arguments to be passed to the callback. + * + * @name Phaser.Time.TimerEvent#args + * @type {array} + * @since 3.0.0 + */ + this.args; + + /** + * Scale the time causing this TimerEvent to update. + * + * @name Phaser.Time.TimerEvent#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly) + * + * @name Phaser.Time.TimerEvent#startAt + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.startAt = 0; + + /** + * The time in milliseconds which has elapsed since the Timer Event's creation. + * + * This value is local for the Timer Event and is relative to its Clock. As such, it's influenced by the Clock's time scale and paused state, the Timer Event's initial {@link #startAt} property, and the Timer Event's {@link #timeScale} and {@link #paused} state. + * + * @name Phaser.Time.TimerEvent#elapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.elapsed = 0; + + /** + * Whether or not this timer is paused. + * + * @name Phaser.Time.TimerEvent#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + /** + * Whether the Timer Event's function has been called. + * + * When the Timer Event fires, this property will be set to `true` before the callback function is invoked and will be reset immediately afterward if the Timer Event should repeat. The value of this property does not directly influence whether the Timer Event will be removed from its Clock, but can prevent it from firing. + * + * @name Phaser.Time.TimerEvent#hasDispatched + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.hasDispatched = false; + + this.reset(config); + }, + + /** + * Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object. + * + * @method Phaser.Time.TimerEvent#reset + * @since 3.0.0 + * + * @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event. + * + * @return {Phaser.Time.TimerEvent} This TimerEvent object. + */ + reset: function (config) + { + this.delay = GetFastValue(config, 'delay', 0); + + // Can also be set to -1 for an infinite loop (same as setting loop: true) + this.repeat = GetFastValue(config, 'repeat', 0); + + this.loop = GetFastValue(config, 'loop', false); + + this.callback = GetFastValue(config, 'callback', undefined); + + this.callbackScope = GetFastValue(config, 'callbackScope', this.callback); + + this.args = GetFastValue(config, 'args', []); + + this.timeScale = GetFastValue(config, 'timeScale', 1); + + this.startAt = GetFastValue(config, 'startAt', 0); + + this.paused = GetFastValue(config, 'paused', false); + + this.elapsed = this.startAt; + this.hasDispatched = false; + this.repeatCount = (this.repeat === -1 || this.loop) ? 999999999999 : this.repeat; + + return this; + }, + + /** + * Gets the progress of the current iteration, not factoring in repeats. + * + * @method Phaser.Time.TimerEvent#getProgress + * @since 3.0.0 + * + * @return {number} A number between 0 and 1 representing the current progress. + */ + getProgress: function () + { + return (this.elapsed / this.delay); + }, + + /** + * Gets the progress of the timer overall, factoring in repeats. + * + * @method Phaser.Time.TimerEvent#getOverallProgress + * @since 3.0.0 + * + * @return {number} The overall progress of the Timer Event, between 0 and 1. + */ + getOverallProgress: function () + { + if (this.repeat > 0) + { + var totalDuration = this.delay + (this.delay * this.repeat); + var totalElapsed = this.elapsed + (this.delay * (this.repeat - this.repeatCount)); + + return (totalElapsed / totalDuration); + } + else + { + return this.getProgress(); + } + }, + + /** + * Returns the number of times this Timer Event will repeat before finishing. + * + * This should not be confused with the number of times the Timer Event will fire before finishing. A return value of 0 doesn't indicate that the Timer Event has finished running - it indicates that it will not repeat after the next time it fires. + * + * @method Phaser.Time.TimerEvent#getRepeatCount + * @since 3.0.0 + * + * @return {number} How many times the Timer Event will repeat. + */ + getRepeatCount: function () + { + return this.repeatCount; + }, + + /** + * Returns the local elapsed time for the current iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getElapsed + * @since 3.0.0 + * + * @return {number} The local elapsed time in milliseconds. + */ + getElapsed: function () + { + return this.elapsed; + }, + + /** + * Returns the local elapsed time for the current iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getElapsedSeconds + * @since 3.0.0 + * + * @return {number} The local elapsed time in seconds. + */ + getElapsedSeconds: function () + { + return this.elapsed * 0.001; + }, + + /** + * Returns the time interval until the next iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getRemaining + * @since 3.50.0 + * + * @return {number} The time interval in milliseconds. + */ + getRemaining: function () + { + return this.delay - this.elapsed; + }, + + /** + * Returns the time interval until the next iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getRemainingSeconds + * @since 3.50.0 + * + * @return {number} The time interval in seconds. + */ + getRemainingSeconds: function () + { + return this.getRemaining() * 0.001; + }, + + /** + * Returns the time interval until the last iteration of the Timer Event. + * + * @method Phaser.Time.TimerEvent#getOverallRemaining + * @since 3.50.0 + * + * @return {number} The time interval in milliseconds. + */ + getOverallRemaining: function () + { + return this.delay * (1 + this.repeatCount) - this.elapsed; + }, + + /** + * Returns the time interval until the last iteration of the Timer Event in seconds. + * + * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds + * @since 3.50.0 + * + * @return {number} The time interval in seconds. + */ + getOverallRemainingSeconds: function () + { + return this.getOverallRemaining() * 0.001; + }, + + /** + * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. + * + * @method Phaser.Time.TimerEvent#remove + * @since 3.0.0 + * + * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. + */ + remove: function (dispatchCallback) + { + if (dispatchCallback === undefined) { dispatchCallback = false; } + + this.elapsed = this.delay; + + this.hasDispatched = !dispatchCallback; + + this.repeatCount = 0; + }, + + /** + * Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments. + * + * Normally, this method is only called by the Clock when it shuts down. As such, it doesn't stop the Timer Event. If called manually, the Timer Event will still be updated by the Clock, but it won't do anything when it fires. + * + * @method Phaser.Time.TimerEvent#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.callback = undefined; + this.callbackScope = undefined; + this.args = []; + } + +}); + +module.exports = TimerEvent; + + +/***/ }), +/* 579 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var RESERVED = __webpack_require__(1458); + +/** + * Internal function used by the Tween Builder to return an array of properties + * that the Tween will be operating on. It takes a tween configuration object + * and then checks that none of the `props` entries start with an underscore, or that + * none of the direct properties are on the Reserved list. + * + * @function Phaser.Tweens.Builders.GetProps + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig} config - The configuration object of the Tween to get the properties from. + * + * @return {string[]} An array of all the properties the tween will operate on. + */ +var GetProps = function (config) +{ + var key; + var keys = []; + + // First see if we have a props object + + if (config.hasOwnProperty('props')) + { + for (key in config.props) + { + // Skip any property that starts with an underscore + if (key.substr(0, 1) !== '_') + { + keys.push({ key: key, value: config.props[key] }); + } + } + } + else + { + for (key in config) + { + // Skip any property that is in the ReservedProps list or that starts with an underscore + if (RESERVED.indexOf(key) === -1 && key.substr(0, 1) !== '_') + { + keys.push({ key: key, value: config[key] }); + } + } + } + + return keys; +}; + +module.exports = GetProps; + + +/***/ }), +/* 580 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetValue = __webpack_require__(6); + +/** + * Internal function used by the Timeline Builder. + * + * It returns an array of all tweens in the given timeline config. + * + * @function Phaser.Tweens.Builders.GetTweens + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. + * + * @return {Phaser.Tweens.Tween[]} An array of Tween instances that the Timeline will manage. + */ +var GetTweens = function (config) +{ + var tweens = GetValue(config, 'tweens', null); + + if (tweens === null) + { + return []; + } + else if (typeof tweens === 'function') + { + tweens = tweens.call(); + } + + if (!Array.isArray(tweens)) + { + tweens = [ tweens ]; + } + + return tweens; +}; + +module.exports = GetTweens; + + +/***/ }), +/* 581 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Defaults = __webpack_require__(261); +var GetAdvancedValue = __webpack_require__(13); +var GetBoolean = __webpack_require__(96); +var GetEaseFunction = __webpack_require__(80); +var GetNewValue = __webpack_require__(160); +var GetValue = __webpack_require__(6); +var GetValueOp = __webpack_require__(260); +var Tween = __webpack_require__(262); +var TweenData = __webpack_require__(264); + +/** + * Creates a new Number Tween. + * + * @function Phaser.Tweens.Builders.NumberTweenBuilder + * @since 3.0.0 + * + * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - The owner of the new Tween. + * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - Configuration for the new Tween. + * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. + * + * @return {Phaser.Tweens.Tween} The new tween. + */ +var NumberTweenBuilder = function (parent, config, defaults) +{ + if (defaults === undefined) + { + defaults = Defaults; + } + + // var tween = this.tweens.addCounter({ + // from: 100, + // to: 200, + // ... (normal tween properties) + // }) + // + // Then use it in your game via: + // + // tween.getValue() + + var from = GetValue(config, 'from', 0); + var to = GetValue(config, 'to', 1); + + var targets = [ { value: from } ]; + + var delay = GetNewValue(config, 'delay', defaults.delay); + var duration = GetNewValue(config, 'duration', defaults.duration); + var easeParams = GetValue(config, 'easeParams', defaults.easeParams); + var ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), easeParams); + var hold = GetNewValue(config, 'hold', defaults.hold); + var repeat = GetNewValue(config, 'repeat', defaults.repeat); + var repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); + var yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); + + var data = []; + + var ops = GetValueOp('value', to); + + var tweenData = TweenData( + targets[0], + 0, + 'value', + ops.getEnd, + ops.getStart, + ops.getActive, + ease, + delay, + duration, + yoyo, + hold, + repeat, + repeatDelay, + false, + false + ); + + tweenData.start = from; + tweenData.current = from; + tweenData.to = to; + + data.push(tweenData); + + var tween = new Tween(parent, data, targets); + + tween.offset = GetAdvancedValue(config, 'offset', null); + tween.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); + tween.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); + tween.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); + tween.paused = GetBoolean(config, 'paused', false); + tween.useFrames = GetBoolean(config, 'useFrames', false); + + // Set the Callbacks + var scope = GetValue(config, 'callbackScope', tween); + + // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params + var tweenArray = [ tween, null ]; + + var callbacks = Tween.TYPES; + + for (var i = 0; i < callbacks.length; i++) + { + var type = callbacks[i]; + + var callback = GetValue(config, type, false); + + if (callback) + { + var callbackScope = GetValue(config, type + 'Scope', scope); + var callbackParams = GetValue(config, type + 'Params', []); + + // The null is reset to be the Tween target + tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); + } + } + + return tween; +}; + +module.exports = NumberTweenBuilder; + + +/***/ }), +/* 582 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetEaseFunction = __webpack_require__(80); +var GetValue = __webpack_require__(6); +var MATH_CONST = __webpack_require__(14); + +/** + * Creates a Stagger function to be used by a Tween property. + * + * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. + * + * This is only worth using if the tween has multiple targets. + * + * The following will stagger the delay by 100ms across all targets of the tween, causing them to scale down to 0.2 + * over the duration specified: + * + * ```javascript + * this.tweens.add({ + * targets: [ ... ], + * scale: 0.2, + * ease: 'linear', + * duration: 1000, + * delay: this.tweens.stagger(100) + * }); + * ``` + * + * The following will stagger the delay by 500ms across all targets of the tween using a 10 x 6 grid, staggering + * from the center out, using a cubic ease. + * + * ```javascript + * this.tweens.add({ + * targets: [ ... ], + * scale: 0.2, + * ease: 'linear', + * duration: 1000, + * delay: this.tweens.stagger(500, { grid: [ 10, 6 ], from: 'center', ease: 'cubic.out' }) + * }); + * ``` + * + * @function Phaser.Tweens.Builders.StaggerBuilder + * @since 3.19.0 + * + * @param {(number|number[])} value - The amount to stagger by, or an array containing two elements representing the min and max values to stagger between. + * @param {Phaser.Types.Tweens.StaggerConfig} [config] - A Stagger Configuration object. + * + * @return {function} The stagger function. + */ +var StaggerBuilder = function (value, options) +{ + if (options === undefined) { options = {}; } + + var result; + + var start = GetValue(options, 'start', 0); + var ease = GetValue(options, 'ease', null); + var grid = GetValue(options, 'grid', null); + + var from = GetValue(options, 'from', 0); + + var fromFirst = (from === 'first'); + var fromCenter = (from === 'center'); + var fromLast = (from === 'last'); + var fromValue = (typeof(from) === 'number'); + + var isRange = (Array.isArray(value)); + var value1 = (isRange) ? parseFloat(value[0]) : parseFloat(value); + var value2 = (isRange) ? parseFloat(value[1]) : 0; + var maxValue = Math.max(value1, value2); + + if (isRange) + { + start += value1; + } + + if (grid) + { + // Pre-calc the grid to save doing it for ever tweendata update + var gridWidth = grid[0]; + var gridHeight = grid[1]; + + var fromX = 0; + var fromY = 0; + + var distanceX = 0; + var distanceY = 0; + + var gridValues = []; + + if (fromLast) + { + fromX = gridWidth - 1; + fromY = gridHeight - 1; + } + else if (fromValue) + { + fromX = from % gridWidth; + fromY = Math.floor(from / gridWidth); + } + else if (fromCenter) + { + fromX = (gridWidth - 1) / 2; + fromY = (gridHeight - 1) / 2; + } + + var gridMax = MATH_CONST.MIN_SAFE_INTEGER; + + for (var toY = 0; toY < gridHeight; toY++) + { + gridValues[toY] = []; + + for (var toX = 0; toX < gridWidth; toX++) + { + distanceX = fromX - toX; + distanceY = fromY - toY; + + var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); + + if (dist > gridMax) + { + gridMax = dist; + } + + gridValues[toY][toX] = dist; + } + } + } + + var easeFunction = (ease) ? GetEaseFunction(ease) : null; + + if (grid) + { + result = function (target, key, value, index) + { + var gridSpace = 0; + var toX = index % gridWidth; + var toY = Math.floor(index / gridWidth); + + if (toX >= 0 && toX < gridWidth && toY >= 0 && toY < gridHeight) + { + gridSpace = gridValues[toY][toX]; + } + + var output; + + if (isRange) + { + var diff = (value2 - value1); + + if (easeFunction) + { + output = ((gridSpace / gridMax) * diff) * easeFunction(gridSpace / gridMax); + } + else + { + output = (gridSpace / gridMax) * diff; + } + } + else if (easeFunction) + { + output = (gridSpace * value1) * easeFunction(gridSpace / gridMax); + } + else + { + output = gridSpace * value1; + } + + return output + start; + }; + } + else + { + result = function (target, key, value, index, total) + { + // zero offset + total--; + + var fromIndex; + + if (fromFirst) + { + fromIndex = index; + } + else if (fromCenter) + { + fromIndex = Math.abs((total / 2) - index); + } + else if (fromLast) + { + fromIndex = total - index; + } + else if (fromValue) + { + fromIndex = Math.abs(from - index); + } + + var output; + + if (isRange) + { + var spacing; + + if (fromCenter) + { + spacing = ((value2 - value1) / total) * (fromIndex * 2); + } + else + { + spacing = ((value2 - value1) / total) * fromIndex; + } + + if (easeFunction) + { + output = spacing * easeFunction(fromIndex / total); + } + else + { + output = spacing; + } + } + else if (easeFunction) + { + output = (total * maxValue) * easeFunction(fromIndex / total); + } + else + { + output = fromIndex * value1; + } + + return output + start; + }; + } + + return result; +}; + +module.exports = StaggerBuilder; + + +/***/ }), +/* 583 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clone = __webpack_require__(77); +var Defaults = __webpack_require__(261); +var GetAdvancedValue = __webpack_require__(13); +var GetBoolean = __webpack_require__(96); +var GetEaseFunction = __webpack_require__(80); +var GetNewValue = __webpack_require__(160); +var GetTargets = __webpack_require__(259); +var GetTweens = __webpack_require__(580); +var GetValue = __webpack_require__(6); +var Timeline = __webpack_require__(584); +var TweenBuilder = __webpack_require__(161); + +/** + * Builds a Timeline of Tweens based on a configuration object. + * + * @function Phaser.Tweens.Builders.TimelineBuilder + * @since 3.0.0 + * + * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager to which the Timeline will belong. + * @param {Phaser.Types.Tweens.TimelineBuilderConfig} config - The configuration object for the Timeline. + * + * @return {Phaser.Tweens.Timeline} The created Timeline. + */ +var TimelineBuilder = function (manager, config) +{ + var timeline = new Timeline(manager); + + timeline.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); + timeline.loop = Math.round(GetAdvancedValue(config, 'loop', 0)); + timeline.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', 0)); + timeline.paused = GetBoolean(config, 'paused', false); + timeline.useFrames = GetBoolean(config, 'useFrames', false); + + // Callbacks + + var scope = GetValue(config, 'callbackScope', timeline); + + var timelineArray = [ timeline ]; + + var onStart = GetValue(config, 'onStart', false); + + // The Start of the Timeline + if (onStart) + { + var onStartScope = GetValue(config, 'onStartScope', scope); + var onStartParams = GetValue(config, 'onStartParams', []); + + timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope); + } + + var onUpdate = GetValue(config, 'onUpdate', false); + + // Every time the Timeline updates (regardless which Tweens are running) + if (onUpdate) + { + var onUpdateScope = GetValue(config, 'onUpdateScope', scope); + var onUpdateParams = GetValue(config, 'onUpdateParams', []); + + timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope); + } + + var onLoop = GetValue(config, 'onLoop', false); + + // Called when the whole Timeline loops + if (onLoop) + { + var onLoopScope = GetValue(config, 'onLoopScope', scope); + var onLoopParams = GetValue(config, 'onLoopParams', []); + + timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope); + } + + var onYoyo = GetValue(config, 'onYoyo', false); + + // Called when a Timeline yoyos + if (onYoyo) + { + var onYoyoScope = GetValue(config, 'onYoyoScope', scope); + var onYoyoParams = GetValue(config, 'onYoyoParams', []); + + timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope); + } + + var onComplete = GetValue(config, 'onComplete', false); + + // Called when the Timeline completes, after the completeDelay, etc. + if (onComplete) + { + var onCompleteScope = GetValue(config, 'onCompleteScope', scope); + var onCompleteParams = GetValue(config, 'onCompleteParams', []); + + timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope); + } + + // Tweens + + var tweens = GetTweens(config); + + if (tweens.length === 0) + { + timeline.paused = true; + + return timeline; + } + + var defaults = Clone(Defaults); + + defaults.targets = GetTargets(config); + + // totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration + + var totalDuration = GetAdvancedValue(config, 'totalDuration', 0); + + if (totalDuration > 0) + { + defaults.duration = Math.floor(totalDuration / tweens.length); + } + else + { + defaults.duration = GetNewValue(config, 'duration', defaults.duration); + } + + defaults.delay = GetNewValue(config, 'delay', defaults.delay); + defaults.easeParams = GetValue(config, 'easeParams', defaults.easeParams); + defaults.ease = GetEaseFunction(GetValue(config, 'ease', defaults.ease), defaults.easeParams); + defaults.hold = GetNewValue(config, 'hold', defaults.hold); + defaults.repeat = GetNewValue(config, 'repeat', defaults.repeat); + defaults.repeatDelay = GetNewValue(config, 'repeatDelay', defaults.repeatDelay); + defaults.yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); + defaults.flipX = GetBoolean(config, 'flipX', defaults.flipX); + defaults.flipY = GetBoolean(config, 'flipY', defaults.flipY); + + // Create the Tweens + for (var i = 0; i < tweens.length; i++) + { + timeline.queue(TweenBuilder(timeline, tweens[i], defaults)); + } + + return timeline; +}; + +module.exports = TimelineBuilder; + + +/***/ }), +/* 584 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var EventEmitter = __webpack_require__(9); +var Events = __webpack_require__(263); +var TweenBuilder = __webpack_require__(161); +var TWEEN_CONST = __webpack_require__(97); + +/** + * @classdesc + * A Timeline combines multiple Tweens into one. Its overall behavior is otherwise similar to a single Tween. + * + * The Timeline updates all of its Tweens simultaneously. Its methods allow you to easily build a sequence + * of Tweens (each one starting after the previous one) or run multiple Tweens at once during given parts of the Timeline. + * + * @class Timeline + * @memberof Phaser.Tweens + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager which owns this Timeline. + */ +var Timeline = new Class({ + + Extends: EventEmitter, + + initialize: + + function Timeline (manager) + { + EventEmitter.call(this); + + /** + * The Tween Manager which owns this Timeline. + * + * @name Phaser.Tweens.Timeline#manager + * @type {Phaser.Tweens.TweenManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * A constant value which allows this Timeline to be easily identified as one. + * + * @name Phaser.Tweens.Timeline#isTimeline + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.isTimeline = true; + + /** + * An array of Tween objects, each containing a unique property and target being tweened. + * + * @name Phaser.Tweens.Timeline#data + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.data = []; + + /** + * The cached size of the data array. + * + * @name Phaser.Tweens.Timeline#totalData + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalData = 0; + + /** + * If true then duration, delay, etc values are all frame totals, rather than ms. + * + * @name Phaser.Tweens.Timeline#useFrames + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.useFrames = false; + + /** + * Scales the time applied to this Timeline. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. + * Value isn't used when calculating total duration of the Timeline, it's a run-time delta adjustment only. + * + * @name Phaser.Tweens.Timeline#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * Loop this Timeline? Can be -1 for an infinite loop, or an integer. + * When enabled it will play through ALL Tweens again (use Tween.repeat to loop a single tween) + * + * @name Phaser.Tweens.Timeline#loop + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loop = 0; + + /** + * Time in ms/frames before this Timeline loops. + * + * @name Phaser.Tweens.Timeline#loopDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loopDelay = 0; + + /** + * How many loops are left to run? + * + * @name Phaser.Tweens.Timeline#loopCounter + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loopCounter = 0; + + /** + * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes) + * + * @name Phaser.Tweens.Timeline#completeDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.completeDelay = 0; + + /** + * Countdown timer value, as used by `loopDelay` and `completeDelay`. + * + * @name Phaser.Tweens.Timeline#countdown + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.countdown = 0; + + /** + * The current state of the Timeline. + * + * @name Phaser.Tweens.Timeline#state + * @type {number} + * @since 3.0.0 + */ + this.state = TWEEN_CONST.PENDING_ADD; + + /** + * The state of the Timeline when it was paused (used by Resume) + * + * @name Phaser.Tweens.Timeline#_pausedState + * @type {number} + * @private + * @since 3.0.0 + */ + this._pausedState = TWEEN_CONST.PENDING_ADD; + + /** + * Does the Timeline start off paused? (if so it needs to be started with Timeline.play) + * + * @name Phaser.Tweens.Timeline#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + /** + * Elapsed time in ms/frames of this run through of the Timeline. + * + * @name Phaser.Tweens.Timeline#elapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.elapsed = 0; + + /** + * Total elapsed time in ms/frames of the entire Timeline, including looping. + * + * @name Phaser.Tweens.Timeline#totalElapsed + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalElapsed = 0; + + /** + * Time in ms/frames for the whole Timeline to play through once, excluding loop amounts and loop delays. + * + * @name Phaser.Tweens.Timeline#duration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.duration = 0; + + /** + * Value between 0 and 1. The amount of progress through the Timeline, _excluding loops_. + * + * @name Phaser.Tweens.Timeline#progress + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.progress = 0; + + /** + * Time in ms/frames for all Tweens in this Timeline to complete (including looping) + * + * @name Phaser.Tweens.Timeline#totalDuration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalDuration = 0; + + /** + * Value between 0 and 1. The amount through the entire Timeline, including looping. + * + * @name Phaser.Tweens.Timeline#totalProgress + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalProgress = 0; + + /** + * An object containing the different Tween callback functions. + * + * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * + * `onComplete` When the Timeline finishes playback fully or `Timeline.stop` is called. Never invoked if timeline is set to repeat infinitely. + * `onLoop` When a Timeline loops. + * `onStart` When the Timeline starts playing. + * `onUpdate` When a Timeline updates a child Tween. + * `onYoyo` When a Timeline starts a yoyo. + * + * @name Phaser.Tweens.Timeline#callbacks + * @type {object} + * @since 3.0.0 + */ + this.callbacks = { + onComplete: null, + onLoop: null, + onStart: null, + onUpdate: null, + onYoyo: null + }; + + /** + * The context in which all callbacks are invoked. + * + * @name Phaser.Tweens.Timeline#callbackScope + * @type {any} + * @since 3.0.0 + */ + this.callbackScope; + }, + + /** + * Internal method that will emit a Timeline based Event and invoke the given callback. + * + * @method Phaser.Tweens.Timeline#dispatchTimelineEvent + * @since 3.19.0 + * + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {function} callback - The callback to be invoked. Can be `null` or `undefined` to skip invocation. + */ + dispatchTimelineEvent: function (event, callback) + { + this.emit(event, this); + + if (callback) + { + callback.func.apply(callback.scope, callback.params); + } + }, + + /** + * Sets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. + * + * The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only. + * + * @method Phaser.Tweens.Timeline#setTimeScale + * @since 3.0.0 + * + * @param {number} value - The time scale value to set. + * + * @return {this} This Timeline object. + */ + setTimeScale: function (value) + { + this.timeScale = value; + + return this; + }, + + /** + * Gets the value of the time scale applied to this Timeline. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. + * + * @method Phaser.Tweens.Timeline#getTimeScale + * @since 3.0.0 + * + * @return {number} The value of the time scale applied to this Timeline. + */ + getTimeScale: function () + { + return this.timeScale; + }, + + /** + * Check whether or not the Timeline is playing. + * + * @method Phaser.Tweens.Timeline#isPlaying + * @since 3.0.0 + * + * @return {boolean} `true` if this Timeline is active, otherwise `false`. + */ + isPlaying: function () + { + return (this.state === TWEEN_CONST.ACTIVE); + }, + + /** + * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. + * + * @method Phaser.Tweens.Timeline#add + * @since 3.0.0 + * + * @param {(Phaser.Types.Tweens.TweenBuilderConfig|object)} config - The configuration object for the Tween. + * + * @return {this} This Timeline object. + */ + add: function (config) + { + return this.queue(TweenBuilder(this, config)); + }, + + /** + * Adds an existing Tween to this Timeline. + * + * @method Phaser.Tweens.Timeline#queue + * @since 3.0.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to be added to this Timeline. + * + * @return {this} This Timeline object. + */ + queue: function (tween) + { + if (!this.isPlaying()) + { + tween.parent = this; + tween.parentIsTimeline = true; + + this.data.push(tween); + + this.totalData = this.data.length; + } + + return this; + }, + + /** + * Checks whether a Tween has an offset value. + * + * @method Phaser.Tweens.Timeline#hasOffset + * @since 3.0.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to check. + * + * @return {boolean} `true` if the tween has a non-null offset. + */ + hasOffset: function (tween) + { + return (tween.offset !== null); + }, + + /** + * Checks whether the offset value is a number or a directive that is relative to previous tweens. + * + * @method Phaser.Tweens.Timeline#isOffsetAbsolute + * @since 3.0.0 + * + * @param {number} value - The offset value to be evaluated. + * + * @return {boolean} `true` if the result is a number, `false` if it is a directive like " -= 1000". + */ + isOffsetAbsolute: function (value) + { + return (typeof(value) === 'number'); + }, + + /** + * Checks if the offset is a relative value rather than an absolute one. + * If the value is just a number, this returns false. + * + * @method Phaser.Tweens.Timeline#isOffsetRelative + * @since 3.0.0 + * + * @param {string} value - The offset value to be evaluated. + * + * @return {boolean} `true` if the value is relative, i.e " -= 1000". If `false`, the offset is absolute. + */ + isOffsetRelative: function (value) + { + var t = typeof(value); + + if (t === 'string') + { + var op = value[0]; + + if (op === '-' || op === '+') + { + return true; + } + } + + return false; + }, + + /** + * Parses the relative offset value, returning a positive or negative number. + * + * @method Phaser.Tweens.Timeline#getRelativeOffset + * @since 3.0.0 + * + * @param {string} value - The relative offset, in the format of '-=500', for example. The first character determines whether it will be a positive or negative number. Spacing matters here. + * @param {number} base - The value to use as the offset. + * + * @return {number} The parsed offset value. + */ + getRelativeOffset: function (value, base) + { + var op = value[0]; + var num = parseFloat(value.substr(2)); + var result = base; + + switch (op) + { + case '+': + result += num; + break; + + case '-': + result -= num; + break; + } + + // Cannot ever be < 0 + return Math.max(0, result); + }, + + /** + * Calculates the total duration of the timeline. + * + * Computes all tween durations and returns the full duration of the timeline. + * + * The resulting number is stored in the timeline, not as a return value. + * + * @method Phaser.Tweens.Timeline#calcDuration + * @since 3.0.0 + */ + calcDuration: function () + { + var prevEnd = 0; + var totalDuration = 0; + var offsetDuration = 0; + + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + tween.init(); + + if (this.hasOffset(tween)) + { + if (this.isOffsetAbsolute(tween.offset)) + { + // An actual number, so it defines the start point from the beginning of the timeline + tween.calculatedOffset = tween.offset; + + if (tween.offset === 0) + { + offsetDuration = 0; + } + } + else if (this.isOffsetRelative(tween.offset)) + { + // A relative offset (i.e. '-=1000', so starts at 'offset' ms relative to the PREVIOUS Tweens ending time) + tween.calculatedOffset = this.getRelativeOffset(tween.offset, prevEnd); + } + } + else + { + // Sequential + tween.calculatedOffset = offsetDuration; + } + + prevEnd = tween.totalDuration + tween.calculatedOffset; + + totalDuration += tween.totalDuration; + offsetDuration += tween.totalDuration; + } + + // Excludes loop values + this.duration = totalDuration; + + this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; + + if (this.loopCounter > 0) + { + this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter); + } + else + { + this.totalDuration = this.duration + this.completeDelay; + } + }, + + /** + * Initializes the timeline, which means all Tweens get their init() called, and the total duration will be computed. + * Returns a boolean indicating whether the timeline is auto-started or not. + * + * @method Phaser.Tweens.Timeline#init + * @since 3.0.0 + * + * @return {boolean} `true` if the Timeline is started. `false` if it is paused. + */ + init: function () + { + this.calcDuration(); + + this.progress = 0; + this.totalProgress = 0; + + if (this.paused) + { + this.state = TWEEN_CONST.PAUSED; + + return false; + } + else + { + return true; + } + }, + + /** + * Resets all of the timeline's tweens back to their initial states. + * The boolean parameter indicates whether tweens that are looping should reset as well, or not. + * + * @method Phaser.Tweens.Timeline#resetTweens + * @since 3.0.0 + * + * @param {boolean} resetFromLoop - If `true`, resets all looping tweens to their initial values. + */ + resetTweens: function (resetFromLoop) + { + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + tween.play(resetFromLoop); + } + }, + + /** + * Sets a callback for the Timeline. + * + * @method Phaser.Tweens.Timeline#setCallback + * @since 3.0.0 + * + * @param {string} type - The internal type of callback to set. + * @param {function} callback - Timeline allows multiple tweens to be linked together to create a streaming sequence. + * @param {array} [params] - The parameters to pass to the callback. + * @param {object} [scope] - The context scope of the callback. + * + * @return {this} This Timeline object. + */ + setCallback: function (type, callback, params, scope) + { + if (Timeline.TYPES.indexOf(type) !== -1) + { + this.callbacks[type] = { func: callback, scope: scope, params: params }; + } + + return this; + }, + + /** + * Passed a Tween to the Tween Manager and requests it be made active. + * + * @method Phaser.Tweens.Timeline#makeActive + * @since 3.3.0 + * + * @param {Phaser.Tweens.Tween} tween - The tween object to make active. + * + * @return {Phaser.Tweens.TweenManager} The Timeline's Tween Manager reference. + */ + makeActive: function (tween) + { + return this.manager.makeActive(tween); + }, + + /** + * Starts playing the Timeline. + * + * @method Phaser.Tweens.Timeline#play + * @fires Phaser.Tweens.Events#TIMELINE_START + * @since 3.0.0 + */ + play: function () + { + if (this.state === TWEEN_CONST.ACTIVE) + { + return; + } + + if (this.paused) + { + this.paused = false; + + this.manager.makeActive(this); + + return; + } + else + { + this.resetTweens(false); + + this.state = TWEEN_CONST.ACTIVE; + } + + this.dispatchTimelineEvent(Events.TIMELINE_START, this.callbacks.onStart); + }, + + /** + * Updates the Timeline's `state` and fires callbacks and events. + * + * @method Phaser.Tweens.Timeline#nextState + * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE + * @fires Phaser.Tweens.Events#TIMELINE_LOOP + * @since 3.0.0 + * + * @see Phaser.Tweens.Timeline#update + */ + nextState: function () + { + if (this.loopCounter > 0) + { + // Reset the elapsed time + this.elapsed = 0; + this.progress = 0; + + this.loopCounter--; + + this.resetTweens(true); + + if (this.loopDelay > 0) + { + this.countdown = this.loopDelay; + + this.state = TWEEN_CONST.LOOP_DELAY; + } + else + { + this.state = TWEEN_CONST.ACTIVE; + + this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); + } + } + else if (this.completeDelay > 0) + { + this.state = TWEEN_CONST.COMPLETE_DELAY; + + this.countdown = this.completeDelay; + } + else + { + this.state = TWEEN_CONST.PENDING_REMOVE; + + this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); + } + }, + + /** + * Returns 'true' if this Timeline has finished and should be removed from the Tween Manager. + * Otherwise, returns false. + * + * @method Phaser.Tweens.Timeline#update + * @fires Phaser.Tweens.Events#TIMELINE_COMPLETE + * @fires Phaser.Tweens.Events#TIMELINE_UPDATE + * @since 3.0.0 + * + * @param {number} timestamp - 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. + * + * @return {boolean} Returns `true` if this Timeline has finished and should be removed from the Tween Manager. + */ + update: function (timestamp, delta) + { + if (this.state === TWEEN_CONST.PAUSED) + { + return; + } + + if (this.useFrames) + { + delta = 1 * this.manager.timeScale; + } + + delta *= this.timeScale; + + this.elapsed += delta; + this.progress = Math.min(this.elapsed / this.duration, 1); + + this.totalElapsed += delta; + this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); + + switch (this.state) + { + case TWEEN_CONST.ACTIVE: + + var stillRunning = this.totalData; + + for (var i = 0; i < this.totalData; i++) + { + var tween = this.data[i]; + + if (tween.update(timestamp, delta)) + { + stillRunning--; + } + } + + this.dispatchTimelineEvent(Events.TIMELINE_UPDATE, this.callbacks.onUpdate); + + // Anything still running? If not, we're done + if (stillRunning === 0) + { + this.nextState(); + } + + break; + + case TWEEN_CONST.LOOP_DELAY: + + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.state = TWEEN_CONST.ACTIVE; + + this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); + } + + break; + + case TWEEN_CONST.COMPLETE_DELAY: + + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.state = TWEEN_CONST.PENDING_REMOVE; + + this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); + } + + break; + } + + return (this.state === TWEEN_CONST.PENDING_REMOVE); + }, + + /** + * Stops the Timeline immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. + * + * @method Phaser.Tweens.Timeline#stop + * @since 3.0.0 + */ + stop: function () + { + this.state = TWEEN_CONST.PENDING_REMOVE; + }, + + /** + * Pauses the Timeline, retaining its internal state. + * + * Calling this on a Timeline that is already paused has no effect and fires no event. + * + * @method Phaser.Tweens.Timeline#pause + * @fires Phaser.Tweens.Events#TIMELINE_PAUSE + * @since 3.0.0 + * + * @return {this} This Timeline object. + */ + pause: function () + { + if (this.state === TWEEN_CONST.PAUSED) + { + return; + } + + this.paused = true; + + this._pausedState = this.state; + + this.state = TWEEN_CONST.PAUSED; + + this.emit(Events.TIMELINE_PAUSE, this); + + return this; + }, + + /** + * Resumes a paused Timeline from where it was when it was paused. + * + * Calling this on a Timeline that isn't paused has no effect and fires no event. + * + * @method Phaser.Tweens.Timeline#resume + * @fires Phaser.Tweens.Events#TIMELINE_RESUME + * @since 3.0.0 + * + * @return {this} This Timeline object. + */ + resume: function () + { + if (this.state === TWEEN_CONST.PAUSED) + { + this.paused = false; + + this.state = this._pausedState; + + this.emit(Events.TIMELINE_RESUME, this); + } + + return this; + }, + + /** + * Checks if any of the Tweens in this Timeline as operating on the target object. + * + * Returns `false` if no Tweens operate on the target object. + * + * @method Phaser.Tweens.Timeline#hasTarget + * @since 3.0.0 + * + * @param {object} target - The target to check all Tweens against. + * + * @return {boolean} `true` if there is at least a single Tween that operates on the target object, otherwise `false`. + */ + hasTarget: function (target) + { + for (var i = 0; i < this.data.length; i++) + { + if (this.data[i].hasTarget(target)) + { + return true; + } + } + + return false; + }, + + /** + * Stops all the Tweens in the Timeline immediately, whatever stage of progress they are at and flags + * them for removal by the TweenManager. + * + * @method Phaser.Tweens.Timeline#destroy + * @since 3.0.0 + */ + destroy: function () + { + for (var i = 0; i < this.data.length; i++) + { + this.data[i].stop(); + } + } + +}); + +Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ]; + +module.exports = Timeline; + + /***/ }), /* 585 */ /***/ (function(module, exports, __webpack_require__) { @@ -138951,7 +138977,7 @@ var Axes = {}; module.exports = Axes; -var Vector = __webpack_require__(114); +var Vector = __webpack_require__(116); var Common = __webpack_require__(50); (function() { @@ -139023,22 +139049,22 @@ var Common = __webpack_require__(50); module.exports = { - AFTER_ADD: __webpack_require__(1502), - AFTER_REMOVE: __webpack_require__(1503), - AFTER_UPDATE: __webpack_require__(1504), - BEFORE_ADD: __webpack_require__(1505), - BEFORE_REMOVE: __webpack_require__(1506), - BEFORE_UPDATE: __webpack_require__(1507), - COLLISION_ACTIVE: __webpack_require__(1508), - COLLISION_END: __webpack_require__(1509), - COLLISION_START: __webpack_require__(1510), - DRAG_END: __webpack_require__(1511), - DRAG: __webpack_require__(1512), - DRAG_START: __webpack_require__(1513), - PAUSE: __webpack_require__(1514), - RESUME: __webpack_require__(1515), - SLEEP_END: __webpack_require__(1516), - SLEEP_START: __webpack_require__(1517) + AFTER_ADD: __webpack_require__(1509), + AFTER_REMOVE: __webpack_require__(1510), + AFTER_UPDATE: __webpack_require__(1511), + BEFORE_ADD: __webpack_require__(1512), + BEFORE_REMOVE: __webpack_require__(1513), + BEFORE_UPDATE: __webpack_require__(1514), + COLLISION_ACTIVE: __webpack_require__(1515), + COLLISION_END: __webpack_require__(1516), + COLLISION_START: __webpack_require__(1517), + DRAG_END: __webpack_require__(1518), + DRAG: __webpack_require__(1519), + DRAG_START: __webpack_require__(1520), + PAUSE: __webpack_require__(1521), + RESUME: __webpack_require__(1522), + SLEEP_END: __webpack_require__(1523), + SLEEP_START: __webpack_require__(1524) }; @@ -139060,8 +139086,8 @@ var Detector = {}; module.exports = Detector; var SAT = __webpack_require__(588); -var Pair = __webpack_require__(519); -var Bounds = __webpack_require__(115); +var Pair = __webpack_require__(535); +var Bounds = __webpack_require__(117); (function() { @@ -139172,8 +139198,8 @@ var SAT = {}; module.exports = SAT; -var Vertices = __webpack_require__(93); -var Vector = __webpack_require__(114); +var Vertices = __webpack_require__(94); +var Vector = __webpack_require__(116); (function() { @@ -140144,7 +140170,7 @@ module.exports = GetLast; */ var AlignIn = __webpack_require__(283); -var CONST = __webpack_require__(120); +var CONST = __webpack_require__(122); var GetFastValue = __webpack_require__(2); var NOOP = __webpack_require__(1); var Zone = __webpack_require__(127); @@ -140262,7 +140288,7 @@ module.exports = GridAlign; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); // bitmask flag for GameObject.renderMask var _FLAG = 2; // 0010 @@ -142029,7 +142055,7 @@ module.exports = Origin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var GetBoolean = __webpack_require__(96); var GetValue = __webpack_require__(6); var TWEEN_CONST = __webpack_require__(97); @@ -143981,7 +144007,7 @@ module.exports = PlaceOnEllipse; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetPoints = __webpack_require__(167); +var GetPoints = __webpack_require__(168); /** * Positions an array of Game Objects on evenly spaced points of a Line. @@ -144026,8 +144052,8 @@ module.exports = PlaceOnLine; */ var MarchingAnts = __webpack_require__(310); -var RotateLeft = __webpack_require__(174); -var RotateRight = __webpack_require__(175); +var RotateLeft = __webpack_require__(175); +var RotateRight = __webpack_require__(176); /** * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Rectangle. @@ -144181,7 +144207,7 @@ module.exports = PlayAnimation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(165); +var Random = __webpack_require__(166); /** * Takes an array of Game Objects and positions them at random locations within the Circle. @@ -144221,7 +144247,7 @@ module.exports = RandomCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(176); +var Random = __webpack_require__(177); /** * Takes an array of Game Objects and positions them at random locations within the Ellipse. @@ -144261,7 +144287,7 @@ module.exports = RandomEllipse; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(168); +var Random = __webpack_require__(169); /** * Takes an array of Game Objects and positions them at random locations on the Line. @@ -144301,7 +144327,7 @@ module.exports = RandomLine; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(169); +var Random = __webpack_require__(170); /** * Takes an array of Game Objects and positions them at random locations within the Rectangle. @@ -144339,7 +144365,7 @@ module.exports = RandomRectangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(177); +var Random = __webpack_require__(178); /** * Takes an array of Game Objects and positions them at random locations within the Triangle. @@ -144420,7 +144446,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundDistance = __webpack_require__(178); +var RotateAroundDistance = __webpack_require__(179); var DistanceBetween = __webpack_require__(48); /** @@ -144466,7 +144492,7 @@ module.exports = RotateAround; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathRotateAroundDistance = __webpack_require__(178); +var MathRotateAroundDistance = __webpack_require__(179); /** * Rotates an array of Game Objects around a point by the given angle and distance. @@ -145526,7 +145552,7 @@ module.exports = Shuffle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathSmootherStep = __webpack_require__(179); +var MathSmootherStep = __webpack_require__(180); /** * Smootherstep is a sigmoid-like interpolation and clamping function. @@ -145584,7 +145610,7 @@ module.exports = SmootherStep; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathSmoothStep = __webpack_require__(180); +var MathSmoothStep = __webpack_require__(181); /** * Smoothstep is a sigmoid-like interpolation and clamping function. @@ -145742,7 +145768,7 @@ module.exports = ToggleVisible; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Wrap = __webpack_require__(64); +var Wrap = __webpack_require__(66); /** * Wrap each item's coordinates within a rectangle's area. @@ -145796,10 +145822,10 @@ module.exports = WrapInRectangle; module.exports = { - Animation: __webpack_require__(181), + Animation: __webpack_require__(182), AnimationFrame: __webpack_require__(313), AnimationManager: __webpack_require__(315), - AnimationState: __webpack_require__(161), + AnimationState: __webpack_require__(162), Events: __webpack_require__(130) }; @@ -147143,7 +147169,7 @@ module.exports = { BaseCamera: __webpack_require__(131), CameraManager: __webpack_require__(775), Effects: __webpack_require__(327), - Events: __webpack_require__(34) + Events: __webpack_require__(35) }; @@ -147626,9 +147652,9 @@ module.exports = 'camerazoomstart'; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -148014,9 +148040,9 @@ module.exports = Fade; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -148365,10 +148391,10 @@ module.exports = Flash; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var EaseMap = __webpack_require__(132); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Vector2 = __webpack_require__(3); /** @@ -149849,9 +149875,9 @@ module.exports = Stepped; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var Vector2 = __webpack_require__(3); /** @@ -150168,9 +150194,9 @@ module.exports = Shake; * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); var EaseMap = __webpack_require__(132); /** @@ -150601,10 +150627,10 @@ module.exports = RotateTo; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var EaseMap = __webpack_require__(132); -var Events = __webpack_require__(34); +var Events = __webpack_require__(35); /** * @classdesc @@ -152463,10 +152489,10 @@ module.exports = { Config: __webpack_require__(340), CreateRenderer: __webpack_require__(360), - DebugHeader: __webpack_require__(362), + DebugHeader: __webpack_require__(378), Events: __webpack_require__(22), - TimeStep: __webpack_require__(363), - VisibilityHandler: __webpack_require__(365) + TimeStep: __webpack_require__(379), + VisibilityHandler: __webpack_require__(381) }; @@ -153078,8 +153104,8 @@ module.exports = { Reverse: __webpack_require__(815), RotateTo: __webpack_require__(816), ShortestBetween: __webpack_require__(817), - Wrap: __webpack_require__(264), - WrapDegrees: __webpack_require__(265) + Wrap: __webpack_require__(265), + WrapDegrees: __webpack_require__(266) }; @@ -153607,7 +153633,7 @@ module.exports = { module.exports = { Ceil: __webpack_require__(825), - Equal: __webpack_require__(121), + Equal: __webpack_require__(123), Floor: __webpack_require__(826), GreaterThan: __webpack_require__(348), LessThan: __webpack_require__(349) @@ -153753,7 +153779,7 @@ module.exports = BezierInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CatmullRom = __webpack_require__(190); +var CatmullRom = __webpack_require__(191); /** * A Catmull-Rom interpolation method. @@ -153857,7 +153883,7 @@ module.exports = LinearInterpolation; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SmootherStep = __webpack_require__(179); +var SmootherStep = __webpack_require__(180); /** * A Smoother Step interpolation method. @@ -154618,9 +154644,9 @@ module.exports = Difference; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); -var Matrix4 = __webpack_require__(65); +var Matrix4 = __webpack_require__(67); var NOOP = __webpack_require__(1); var tempMatrix = new Matrix4(); @@ -155495,8 +155521,8 @@ module.exports = Within; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Vector3 = __webpack_require__(36); -var Matrix4 = __webpack_require__(65); +var Vector3 = __webpack_require__(37); +var Matrix4 = __webpack_require__(67); var Quaternion = __webpack_require__(359); var tmpMat4 = new Matrix4(); @@ -156354,7 +156380,7 @@ module.exports = [ module.exports = { - GenerateTexture: __webpack_require__(366), + GenerateTexture: __webpack_require__(382), Palettes: __webpack_require__(885) }; @@ -156376,7 +156402,7 @@ module.exports = { module.exports = { - ARNE16: __webpack_require__(367), + ARNE16: __webpack_require__(383), C64: __webpack_require__(886), CGA: __webpack_require__(887), JMP: __webpack_require__(888), @@ -156553,14 +156579,14 @@ module.exports = { module.exports = { Path: __webpack_require__(891), - MoveTo: __webpack_require__(371), + MoveTo: __webpack_require__(387), - CubicBezier: __webpack_require__(368), - Curve: __webpack_require__(89), - Ellipse: __webpack_require__(369), - Line: __webpack_require__(370), - QuadraticBezier: __webpack_require__(372), - Spline: __webpack_require__(373) + CubicBezier: __webpack_require__(384), + Curve: __webpack_require__(90), + Ellipse: __webpack_require__(385), + Line: __webpack_require__(386), + QuadraticBezier: __webpack_require__(388), + Spline: __webpack_require__(389) }; @@ -156577,14 +156603,14 @@ module.exports = { // Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) var Class = __webpack_require__(0); -var CubicBezierCurve = __webpack_require__(368); -var EllipseCurve = __webpack_require__(369); +var CubicBezierCurve = __webpack_require__(384); +var EllipseCurve = __webpack_require__(385); var GameObjectFactory = __webpack_require__(5); -var LineCurve = __webpack_require__(370); -var MovePathTo = __webpack_require__(371); -var QuadraticBezierCurve = __webpack_require__(372); +var LineCurve = __webpack_require__(386); +var MovePathTo = __webpack_require__(387); +var QuadraticBezierCurve = __webpack_require__(388); var Rectangle = __webpack_require__(10); -var SplineCurve = __webpack_require__(373); +var SplineCurve = __webpack_require__(389); var Vector2 = __webpack_require__(3); var MATH_CONST = __webpack_require__(14); @@ -157620,13 +157646,13 @@ module.exports = DataManagerPlugin; module.exports = { Align: __webpack_require__(895), - BaseShader: __webpack_require__(374), + BaseShader: __webpack_require__(390), Bounds: __webpack_require__(898), Canvas: __webpack_require__(902), - Color: __webpack_require__(375), - ColorMatrix: __webpack_require__(266), + Color: __webpack_require__(391), + ColorMatrix: __webpack_require__(195), Masks: __webpack_require__(912), - RGB: __webpack_require__(195) + RGB: __webpack_require__(197) }; @@ -157641,8 +157667,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(120); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(122); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Display.Align @@ -157882,7 +157908,7 @@ module.exports = { CanvasInterpolation: __webpack_require__(361), CanvasPool: __webpack_require__(31), - Smoothing: __webpack_require__(188), + Smoothing: __webpack_require__(189), TouchAction: __webpack_require__(903), UserSelect: __webpack_require__(904) @@ -158118,8 +158144,8 @@ module.exports = ColorToRGBA; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(35); -var HueToComponent = __webpack_require__(377); +var Color = __webpack_require__(36); +var HueToComponent = __webpack_require__(393); /** * Converts HSL (hue, saturation and lightness) values to a Phaser Color object. @@ -158168,7 +158194,7 @@ module.exports = HSLToColor; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HSVToRGB = __webpack_require__(184); +var HSVToRGB = __webpack_require__(185); /** * Get HSV color wheel values in an array which will be 360 elements in size. @@ -158317,8 +158343,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Between = __webpack_require__(191); -var Color = __webpack_require__(35); +var Between = __webpack_require__(192); +var Color = __webpack_require__(36); /** * Creates a new Color object where the r, g, and b values have been set to random values @@ -158353,7 +158379,7 @@ module.exports = RandomRGB; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ComponentToHex = __webpack_require__(376); +var ComponentToHex = __webpack_require__(392); /** * Converts the color values into an HTML compatible color string, prefixed with either `#` or `0x`. @@ -158425,14 +158451,14 @@ module.exports = { var Dom = { - AddToDOM: __webpack_require__(139), - DOMContentLoaded: __webpack_require__(378), - GetInnerHeight: __webpack_require__(379), - GetScreenOrientation: __webpack_require__(380), - GetTarget: __webpack_require__(385), - ParseXML: __webpack_require__(386), - RemoveFromDOM: __webpack_require__(197), - RequestAnimationFrame: __webpack_require__(364) + AddToDOM: __webpack_require__(140), + DOMContentLoaded: __webpack_require__(394), + GetInnerHeight: __webpack_require__(395), + GetScreenOrientation: __webpack_require__(396), + GetTarget: __webpack_require__(401), + ParseXML: __webpack_require__(402), + RemoveFromDOM: __webpack_require__(199), + RequestAnimationFrame: __webpack_require__(380) }; @@ -158650,7 +158676,7 @@ module.exports = EventEmitter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var AnimationManager = __webpack_require__(315); var CacheManager = __webpack_require__(319); var CanvasPool = __webpack_require__(31); @@ -158659,24 +158685,24 @@ var Config = __webpack_require__(340); var CreateDOMContainer = __webpack_require__(917); var CreateRenderer = __webpack_require__(360); var DataManager = __webpack_require__(98); -var DebugHeader = __webpack_require__(362); +var DebugHeader = __webpack_require__(378); var Device = __webpack_require__(341); -var DOMContentLoaded = __webpack_require__(378); +var DOMContentLoaded = __webpack_require__(394); var EventEmitter = __webpack_require__(9); var Events = __webpack_require__(22); -var InputManager = __webpack_require__(387); +var InputManager = __webpack_require__(403); var PluginCache = __webpack_require__(24); -var PluginManager = __webpack_require__(392); -var ScaleManager = __webpack_require__(393); -var SceneManager = __webpack_require__(395); +var PluginManager = __webpack_require__(408); +var ScaleManager = __webpack_require__(409); +var SceneManager = __webpack_require__(411); var TextureEvents = __webpack_require__(103); -var TextureManager = __webpack_require__(400); -var TimeStep = __webpack_require__(363); -var VisibilityHandler = __webpack_require__(365); +var TextureManager = __webpack_require__(416); +var TimeStep = __webpack_require__(379); +var VisibilityHandler = __webpack_require__(381); if (true) { - var SoundManagerCreator = __webpack_require__(404); + var SoundManagerCreator = __webpack_require__(420); } if (false) @@ -159353,7 +159379,7 @@ module.exports = Game; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(139); +var AddToDOM = __webpack_require__(140); var CreateDOMContainer = function (game) { @@ -162855,52 +162881,52 @@ var GameObjects = { UpdateList: __webpack_require__(1034), Components: __webpack_require__(11), - GetCalcMatrix: __webpack_require__(18), + GetCalcMatrix: __webpack_require__(19), BuildGameObject: __webpack_require__(28), - BuildGameObjectAnimation: __webpack_require__(417), + BuildGameObjectAnimation: __webpack_require__(433), GameObject: __webpack_require__(15), - BitmapText: __webpack_require__(146), - Blitter: __webpack_require__(208), - Bob: __webpack_require__(418), - Container: __webpack_require__(209), - DOMElement: __webpack_require__(420), - DynamicBitmapText: __webpack_require__(210), - Extern: __webpack_require__(422), - Graphics: __webpack_require__(211), - Group: __webpack_require__(108), + BitmapText: __webpack_require__(147), + Blitter: __webpack_require__(210), + Bob: __webpack_require__(434), + Container: __webpack_require__(211), + DOMElement: __webpack_require__(436), + DynamicBitmapText: __webpack_require__(212), + Extern: __webpack_require__(438), + Graphics: __webpack_require__(213), + Group: __webpack_require__(110), Image: __webpack_require__(124), - Layer: __webpack_require__(214), + Layer: __webpack_require__(216), Particles: __webpack_require__(1068), - PathFollower: __webpack_require__(435), - RenderTexture: __webpack_require__(216), + PathFollower: __webpack_require__(451), + RenderTexture: __webpack_require__(218), RetroFont: __webpack_require__(1076), - Rope: __webpack_require__(218), + Rope: __webpack_require__(220), Sprite: __webpack_require__(73), - Text: __webpack_require__(219), - GetTextSize: __webpack_require__(436), - MeasureText: __webpack_require__(438), - TextStyle: __webpack_require__(437), + Text: __webpack_require__(221), + GetTextSize: __webpack_require__(452), + MeasureText: __webpack_require__(454), + TextStyle: __webpack_require__(453), - TileSprite: __webpack_require__(220), + TileSprite: __webpack_require__(222), Zone: __webpack_require__(127), - Video: __webpack_require__(221), + Video: __webpack_require__(223), // Shapes Shape: __webpack_require__(32), - Arc: __webpack_require__(439), - Curve: __webpack_require__(440), - Ellipse: __webpack_require__(441), - Grid: __webpack_require__(442), - IsoBox: __webpack_require__(443), - IsoTriangle: __webpack_require__(444), - Line: __webpack_require__(445), - Polygon: __webpack_require__(446), - Rectangle: __webpack_require__(451), - Star: __webpack_require__(452), - Triangle: __webpack_require__(453), + Arc: __webpack_require__(455), + Curve: __webpack_require__(456), + Ellipse: __webpack_require__(457), + Grid: __webpack_require__(458), + IsoBox: __webpack_require__(459), + IsoTriangle: __webpack_require__(460), + Line: __webpack_require__(461), + Polygon: __webpack_require__(462), + Rectangle: __webpack_require__(467), + Star: __webpack_require__(468), + Triangle: __webpack_require__(469), // Game Object Factories @@ -162963,9 +162989,9 @@ var GameObjects = { // WebGL only Game Objects if (true) { - GameObjects.Shader = __webpack_require__(224); - GameObjects.Mesh = __webpack_require__(225); - GameObjects.PointLight = __webpack_require__(148); + GameObjects.Shader = __webpack_require__(226); + GameObjects.Mesh = __webpack_require__(227); + GameObjects.PointLight = __webpack_require__(149); GameObjects.Factories.Shader = __webpack_require__(1178); GameObjects.Factories.Mesh = __webpack_require__(1179); @@ -162975,8 +163001,8 @@ if (true) GameObjects.Creators.Mesh = __webpack_require__(1182); GameObjects.Creators.PointLight = __webpack_require__(1183); - GameObjects.Light = __webpack_require__(459); - GameObjects.LightsManager = __webpack_require__(460); + GameObjects.Light = __webpack_require__(475); + GameObjects.LightsManager = __webpack_require__(476); GameObjects.LightsPlugin = __webpack_require__(1184); } @@ -162994,7 +163020,7 @@ module.exports = GameObjects; */ var Class = __webpack_require__(0); -var List = __webpack_require__(105); +var List = __webpack_require__(107); var PluginCache = __webpack_require__(24); var GameObjectEvents = __webpack_require__(75); var SceneEvents = __webpack_require__(21); @@ -163270,16 +163296,16 @@ module.exports = DisplayList; module.exports = { - CheckMatrix: __webpack_require__(204), + CheckMatrix: __webpack_require__(206), MatrixToString: __webpack_require__(1010), ReverseColumns: __webpack_require__(1011), ReverseRows: __webpack_require__(1012), Rotate180: __webpack_require__(1013), RotateLeft: __webpack_require__(1014), - RotateMatrix: __webpack_require__(145), + RotateMatrix: __webpack_require__(146), RotateRight: __webpack_require__(1015), Translate: __webpack_require__(1016), - TransposeMatrix: __webpack_require__(413) + TransposeMatrix: __webpack_require__(429) }; @@ -163294,8 +163320,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Pad = __webpack_require__(182); -var CheckMatrix = __webpack_require__(204); +var Pad = __webpack_require__(183); +var CheckMatrix = __webpack_require__(206); /** * Generates a string (which you can pass to console.log) from the given Array Matrix. @@ -163484,7 +163510,7 @@ module.exports = ReverseRows; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix 180 degrees. @@ -163531,7 +163557,7 @@ module.exports = Rotate180; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix to the left (or 90 degrees) @@ -163578,7 +163604,7 @@ module.exports = RotateLeft; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(145); +var RotateMatrix = __webpack_require__(146); /** * Rotates the array matrix to the left (or -90 degrees) @@ -163625,8 +163651,8 @@ module.exports = RotateRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateLeft = __webpack_require__(174); -var RotateRight = __webpack_require__(175); +var RotateLeft = __webpack_require__(175); +var RotateRight = __webpack_require__(176); /** * Translates the given Array Matrix by shifting each column and row the @@ -164691,7 +164717,7 @@ module.exports = Swap; */ var Class = __webpack_require__(0); -var ProcessQueue = __webpack_require__(206); +var ProcessQueue = __webpack_require__(208); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); @@ -165570,7 +165596,7 @@ module.exports = GetBitmapTextSize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ParseXMLBitmapFont = __webpack_require__(207); +var ParseXMLBitmapFont = __webpack_require__(209); /** * Parse an XML Bitmap Font from an Atlas. @@ -165656,7 +165682,7 @@ module.exports = { */ var BatchChar = __webpack_require__(1041); -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -166617,12 +166643,12 @@ var renderCanvas = __webpack_require__(1); if (true) { - renderWebGL = __webpack_require__(421); + renderWebGL = __webpack_require__(437); } if (true) { - renderCanvas = __webpack_require__(421); + renderCanvas = __webpack_require__(437); } module.exports = { @@ -166716,7 +166742,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var TransformMatrix = __webpack_require__(25); var Utils = __webpack_require__(12); @@ -167243,7 +167269,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -167297,12 +167323,12 @@ if (true) renderWebGL = __webpack_require__(1058); // Needed for Graphics.generateTexture - renderCanvas = __webpack_require__(426); + renderCanvas = __webpack_require__(442); } if (true) { - renderCanvas = __webpack_require__(426); + renderCanvas = __webpack_require__(442); } module.exports = { @@ -167323,8 +167349,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Commands = __webpack_require__(212); -var GetCalcMatrix = __webpack_require__(18); +var Commands = __webpack_require__(214); +var GetCalcMatrix = __webpack_require__(19); var TransformMatrix = __webpack_require__(25); var Utils = __webpack_require__(12); @@ -168112,11 +168138,11 @@ module.exports = LayerCanvasRenderer; module.exports = { - EmitterOp: __webpack_require__(427), - GravityWell: __webpack_require__(428), - Particle: __webpack_require__(429), - ParticleEmitter: __webpack_require__(430), - ParticleEmitterManager: __webpack_require__(215), + EmitterOp: __webpack_require__(443), + GravityWell: __webpack_require__(444), + Particle: __webpack_require__(445), + ParticleEmitter: __webpack_require__(446), + ParticleEmitterManager: __webpack_require__(217), Zones: __webpack_require__(1072) }; @@ -168463,9 +168489,9 @@ module.exports = ParticleManagerCanvasRenderer; module.exports = { - DeathZone: __webpack_require__(431), - EdgeZone: __webpack_require__(432), - RandomZone: __webpack_require__(434) + DeathZone: __webpack_require__(447), + EdgeZone: __webpack_require__(448), + RandomZone: __webpack_require__(450) }; @@ -168618,7 +168644,7 @@ module.exports = RenderTextureCanvasRenderer; */ var RETRO_FONT_CONST = __webpack_require__(1077); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.GameObjects.RetroFont @@ -168922,7 +168948,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -169476,8 +169502,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); -var FillPathWebGL = __webpack_require__(109); +var GetCalcMatrix = __webpack_require__(19); +var FillPathWebGL = __webpack_require__(111); var StrokePathWebGL = __webpack_require__(81); /** @@ -169535,9 +169561,9 @@ module.exports = ArcWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -169641,8 +169667,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -169701,7 +169727,7 @@ module.exports = CurveWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -169818,8 +169844,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -169878,7 +169904,7 @@ module.exports = EllipseWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -169992,7 +170018,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -170192,7 +170218,7 @@ module.exports = GridWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -170410,7 +170436,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -170675,7 +170701,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -170973,7 +170999,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var Utils = __webpack_require__(12); /** @@ -171048,7 +171074,7 @@ module.exports = LineWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -171135,8 +171161,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -171195,7 +171221,7 @@ module.exports = PolygonWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -171309,7 +171335,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); var Utils = __webpack_require__(12); @@ -171381,7 +171407,7 @@ module.exports = RectangleWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -171484,8 +171510,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(109); -var GetCalcMatrix = __webpack_require__(18); +var FillPathWebGL = __webpack_require__(111); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); /** @@ -171544,7 +171570,7 @@ module.exports = StarWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -171658,7 +171684,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); var StrokePathWebGL = __webpack_require__(81); var Utils = __webpack_require__(12); @@ -171741,7 +171767,7 @@ module.exports = TriangleWebGLRenderer; */ var FillStyleCanvas = __webpack_require__(46); -var LineStyleCanvas = __webpack_require__(57); +var LineStyleCanvas = __webpack_require__(58); var SetTransform = __webpack_require__(30); /** @@ -171814,7 +171840,7 @@ module.exports = TriangleCanvasRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(208); +var Blitter = __webpack_require__(210); var GameObjectFactory = __webpack_require__(5); /** @@ -171857,7 +171883,7 @@ GameObjectFactory.register('blitter', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Container = __webpack_require__(209); +var Container = __webpack_require__(211); var GameObjectFactory = __webpack_require__(5); /** @@ -171890,7 +171916,7 @@ GameObjectFactory.register('container', function (x, y, children) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DOMElement = __webpack_require__(420); +var DOMElement = __webpack_require__(436); var GameObjectFactory = __webpack_require__(5); /** @@ -171979,7 +172005,7 @@ GameObjectFactory.register('dom', function (x, y, element, style, innerText) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DynamicBitmapText = __webpack_require__(210); +var DynamicBitmapText = __webpack_require__(212); var GameObjectFactory = __webpack_require__(5); /** @@ -172048,7 +172074,7 @@ GameObjectFactory.register('dynamicBitmapText', function (x, y, font, text, size * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extern = __webpack_require__(422); +var Extern = __webpack_require__(438); var GameObjectFactory = __webpack_require__(5); /** @@ -172089,7 +172115,7 @@ GameObjectFactory.register('extern', function () * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Graphics = __webpack_require__(211); +var Graphics = __webpack_require__(213); var GameObjectFactory = __webpack_require__(5); /** @@ -172128,7 +172154,7 @@ GameObjectFactory.register('graphics', function (config) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Group = __webpack_require__(108); +var Group = __webpack_require__(110); var GameObjectFactory = __webpack_require__(5); /** @@ -172202,7 +172228,7 @@ GameObjectFactory.register('image', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Layer = __webpack_require__(214); +var Layer = __webpack_require__(216); var GameObjectFactory = __webpack_require__(5); /** @@ -172234,7 +172260,7 @@ GameObjectFactory.register('layer', function (children) */ var GameObjectFactory = __webpack_require__(5); -var ParticleEmitterManager = __webpack_require__(215); +var ParticleEmitterManager = __webpack_require__(217); /** * Creates a new Particle Emitter Manager Game Object and adds it to the Scene. @@ -172267,7 +172293,7 @@ GameObjectFactory.register('particles', function (key, frame, emitters) */ var GameObjectFactory = __webpack_require__(5); -var PathFollower = __webpack_require__(435); +var PathFollower = __webpack_require__(451); /** * Creates a new PathFollower Game Object and adds it to the Scene. @@ -172315,7 +172341,7 @@ GameObjectFactory.register('follower', function (path, x, y, key, frame) */ var GameObjectFactory = __webpack_require__(5); -var RenderTexture = __webpack_require__(216); +var RenderTexture = __webpack_require__(218); /** * Creates a new Render Texture Game Object and adds it to the Scene. @@ -172354,7 +172380,7 @@ GameObjectFactory.register('renderTexture', function (x, y, width, height, key, * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Rope = __webpack_require__(218); +var Rope = __webpack_require__(220); var GameObjectFactory = __webpack_require__(5); /** @@ -172442,7 +172468,7 @@ GameObjectFactory.register('sprite', function (x, y, key, frame) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var GameObjectFactory = __webpack_require__(5); /** @@ -172506,7 +172532,7 @@ GameObjectFactory.register('bitmapText', function (x, y, font, text, size, align * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Text = __webpack_require__(219); +var Text = __webpack_require__(221); var GameObjectFactory = __webpack_require__(5); /** @@ -172571,7 +172597,7 @@ GameObjectFactory.register('text', function (x, y, text, style) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TileSprite = __webpack_require__(220); +var TileSprite = __webpack_require__(222); var GameObjectFactory = __webpack_require__(5); /** @@ -172657,7 +172683,7 @@ GameObjectFactory.register('zone', function (x, y, width, height) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Video = __webpack_require__(221); +var Video = __webpack_require__(223); var GameObjectFactory = __webpack_require__(5); /** @@ -172690,7 +172716,7 @@ GameObjectFactory.register('video', function (x, y, key) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Arc = __webpack_require__(439); +var Arc = __webpack_require__(455); var GameObjectFactory = __webpack_require__(5); /** @@ -172764,7 +172790,7 @@ GameObjectFactory.register('circle', function (x, y, radius, fillColor, fillAlph */ var GameObjectFactory = __webpack_require__(5); -var Curve = __webpack_require__(440); +var Curve = __webpack_require__(456); /** * Creates a new Curve Shape Game Object and adds it to the Scene. @@ -172813,7 +172839,7 @@ GameObjectFactory.register('curve', function (x, y, curve, fillColor, fillAlpha) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(441); +var Ellipse = __webpack_require__(457); var GameObjectFactory = __webpack_require__(5); /** @@ -172866,7 +172892,7 @@ GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, */ var GameObjectFactory = __webpack_require__(5); -var Grid = __webpack_require__(442); +var Grid = __webpack_require__(458); /** * Creates a new Grid Shape Game Object and adds it to the Scene. @@ -172921,7 +172947,7 @@ GameObjectFactory.register('grid', function (x, y, width, height, cellWidth, cel */ var GameObjectFactory = __webpack_require__(5); -var IsoBox = __webpack_require__(443); +var IsoBox = __webpack_require__(459); /** * Creates a new IsoBox Shape Game Object and adds it to the Scene. @@ -172972,7 +172998,7 @@ GameObjectFactory.register('isobox', function (x, y, size, height, fillTop, fill */ var GameObjectFactory = __webpack_require__(5); -var IsoTriangle = __webpack_require__(444); +var IsoTriangle = __webpack_require__(460); /** * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. @@ -173025,7 +173051,7 @@ GameObjectFactory.register('isotriangle', function (x, y, size, height, reversed */ var GameObjectFactory = __webpack_require__(5); -var Line = __webpack_require__(445); +var Line = __webpack_require__(461); /** * Creates a new Line Shape Game Object and adds it to the Scene. @@ -173076,7 +173102,7 @@ GameObjectFactory.register('line', function (x, y, x1, y1, x2, y2, strokeColor, */ var GameObjectFactory = __webpack_require__(5); -var Polygon = __webpack_require__(446); +var Polygon = __webpack_require__(462); /** * Creates a new Polygon Shape Game Object and adds it to the Scene. @@ -173129,7 +173155,7 @@ GameObjectFactory.register('polygon', function (x, y, points, fillColor, fillAlp */ var GameObjectFactory = __webpack_require__(5); -var Rectangle = __webpack_require__(451); +var Rectangle = __webpack_require__(467); /** * Creates a new Rectangle Shape Game Object and adds it to the Scene. @@ -173173,7 +173199,7 @@ GameObjectFactory.register('rectangle', function (x, y, width, height, fillColor * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Star = __webpack_require__(452); +var Star = __webpack_require__(468); var GameObjectFactory = __webpack_require__(5); /** @@ -173226,7 +173252,7 @@ GameObjectFactory.register('star', function (x, y, points, innerRadius, outerRad */ var GameObjectFactory = __webpack_require__(5); -var Triangle = __webpack_require__(453); +var Triangle = __webpack_require__(469); /** * Creates a new Triangle Shape Game Object and adds it to the Scene. @@ -173276,7 +173302,7 @@ GameObjectFactory.register('triangle', function (x, y, x1, y1, x2, y2, x3, y3, f * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(208); +var Blitter = __webpack_require__(210); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -173328,7 +173354,7 @@ GameObjectCreator.register('blitter', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var Container = __webpack_require__(209); +var Container = __webpack_require__(211); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -173376,7 +173402,7 @@ GameObjectCreator.register('container', function (config, addToScene) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(210); +var BitmapText = __webpack_require__(212); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -173428,7 +173454,7 @@ GameObjectCreator.register('dynamicBitmapText', function (config, addToScene) */ var GameObjectCreator = __webpack_require__(16); -var Graphics = __webpack_require__(211); +var Graphics = __webpack_require__(213); /** * Creates a new Graphics Game Object and returns it. @@ -173476,7 +173502,7 @@ GameObjectCreator.register('graphics', function (config, addToScene) */ var GameObjectCreator = __webpack_require__(16); -var Group = __webpack_require__(108); +var Group = __webpack_require__(110); /** * Creates a new Group Game Object and returns it. @@ -173559,7 +173585,7 @@ GameObjectCreator.register('image', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var Layer = __webpack_require__(214); +var Layer = __webpack_require__(216); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -173608,7 +173634,7 @@ GameObjectCreator.register('layer', function (config, addToScene) var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetFastValue = __webpack_require__(2); -var ParticleEmitterManager = __webpack_require__(215); +var ParticleEmitterManager = __webpack_require__(217); /** * Creates a new Particle Emitter Manager Game Object and returns it. @@ -173667,7 +173693,7 @@ GameObjectCreator.register('particles', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var RenderTexture = __webpack_require__(216); +var RenderTexture = __webpack_require__(218); /** * Creates a new Render Texture Game Object and returns it. @@ -173720,7 +173746,7 @@ var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetValue = __webpack_require__(6); -var Rope = __webpack_require__(218); +var Rope = __webpack_require__(220); /** * Creates a new Rope Game Object and returns it. @@ -173777,7 +173803,7 @@ GameObjectCreator.register('rope', function (config, addToScene) */ var BuildGameObject = __webpack_require__(28); -var BuildGameObjectAnimation = __webpack_require__(417); +var BuildGameObjectAnimation = __webpack_require__(433); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var Sprite = __webpack_require__(73); @@ -173829,7 +173855,7 @@ GameObjectCreator.register('sprite', function (config, addToScene) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(146); +var BitmapText = __webpack_require__(147); var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); @@ -173885,7 +173911,7 @@ GameObjectCreator.register('bitmapText', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Text = __webpack_require__(219); +var Text = __webpack_require__(221); /** * Creates a new Text Game Object and returns it. @@ -173972,7 +173998,7 @@ GameObjectCreator.register('text', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var TileSprite = __webpack_require__(220); +var TileSprite = __webpack_require__(222); /** * Creates a new TileSprite Game Object and returns it. @@ -174063,7 +174089,7 @@ GameObjectCreator.register('zone', function (config) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Video = __webpack_require__(221); +var Video = __webpack_require__(223); /** * Creates a new Video Game Object and returns it. @@ -174145,7 +174171,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -174264,7 +174290,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -174428,7 +174454,7 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(18); +var GetCalcMatrix = __webpack_require__(19); /** * Renders this Game Object with the WebGL Renderer to the given Camera. @@ -174494,7 +174520,7 @@ module.exports = PointLightWebGLRenderer; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Shader = __webpack_require__(224); +var Shader = __webpack_require__(226); var GameObjectFactory = __webpack_require__(5); /** @@ -174535,7 +174561,7 @@ if (true) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Mesh = __webpack_require__(225); +var Mesh = __webpack_require__(227); var GameObjectFactory = __webpack_require__(5); /** @@ -174581,7 +174607,7 @@ if (true) */ var GameObjectFactory = __webpack_require__(5); -var PointLight = __webpack_require__(148); +var PointLight = __webpack_require__(149); /** * Creates a new Point Light Game Object and adds it to the Scene. @@ -174643,7 +174669,7 @@ GameObjectFactory.register('pointlight', function (x, y, color, radius, intensit var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var Shader = __webpack_require__(224); +var Shader = __webpack_require__(226); /** * Creates a new Shader Game Object and returns it. @@ -174697,7 +174723,7 @@ var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); var GetValue = __webpack_require__(6); -var Mesh = __webpack_require__(225); +var Mesh = __webpack_require__(227); /** * Creates a new Mesh Game Object and returns it. @@ -174752,7 +174778,7 @@ GameObjectCreator.register('mesh', function (config, addToScene) var BuildGameObject = __webpack_require__(28); var GameObjectCreator = __webpack_require__(16); var GetAdvancedValue = __webpack_require__(13); -var PointLight = __webpack_require__(148); +var PointLight = __webpack_require__(149); /** * Creates a new Point Light Game Object and returns it. @@ -174800,7 +174826,7 @@ GameObjectCreator.register('pointlight', function (config, addToScene) */ var Class = __webpack_require__(0); -var LightsManager = __webpack_require__(460); +var LightsManager = __webpack_require__(476); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); @@ -174917,13 +174943,13 @@ module.exports = LightsPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); Circle.Area = __webpack_require__(1186); Circle.Circumference = __webpack_require__(296); -Circle.CircumferencePoint = __webpack_require__(164); +Circle.CircumferencePoint = __webpack_require__(165); Circle.Clone = __webpack_require__(1187); -Circle.Contains = __webpack_require__(62); +Circle.Contains = __webpack_require__(63); Circle.ContainsPoint = __webpack_require__(1188); Circle.ContainsRect = __webpack_require__(1189); Circle.CopyFrom = __webpack_require__(1190); @@ -174933,7 +174959,7 @@ Circle.GetPoint = __webpack_require__(294); Circle.GetPoints = __webpack_require__(295); Circle.Offset = __webpack_require__(1193); Circle.OffsetPoint = __webpack_require__(1194); -Circle.Random = __webpack_require__(165); +Circle.Random = __webpack_require__(166); module.exports = Circle; @@ -174976,7 +175002,7 @@ module.exports = Area; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); /** * Creates a new Circle instance based on the values contained in the given source. @@ -175006,7 +175032,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); /** * Check to see if the Circle contains the given Point object. @@ -175037,7 +175063,7 @@ module.exports = ContainsPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(62); +var Contains = __webpack_require__(63); /** * Check to see if the Circle contains all four points of the given Rectangle object. @@ -175248,23 +175274,23 @@ module.exports = OffsetPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); Ellipse.Area = __webpack_require__(1196); -Ellipse.Circumference = __webpack_require__(425); -Ellipse.CircumferencePoint = __webpack_require__(213); +Ellipse.Circumference = __webpack_require__(441); +Ellipse.CircumferencePoint = __webpack_require__(215); Ellipse.Clone = __webpack_require__(1197); -Ellipse.Contains = __webpack_require__(107); +Ellipse.Contains = __webpack_require__(109); Ellipse.ContainsPoint = __webpack_require__(1198); Ellipse.ContainsRect = __webpack_require__(1199); Ellipse.CopyFrom = __webpack_require__(1200); Ellipse.Equals = __webpack_require__(1201); Ellipse.GetBounds = __webpack_require__(1202); -Ellipse.GetPoint = __webpack_require__(423); -Ellipse.GetPoints = __webpack_require__(424); +Ellipse.GetPoint = __webpack_require__(439); +Ellipse.GetPoints = __webpack_require__(440); Ellipse.Offset = __webpack_require__(1203); Ellipse.OffsetPoint = __webpack_require__(1204); -Ellipse.Random = __webpack_require__(176); +Ellipse.Random = __webpack_require__(177); module.exports = Ellipse; @@ -175313,7 +175339,7 @@ module.exports = Area; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Ellipse = __webpack_require__(106); +var Ellipse = __webpack_require__(108); /** * Creates a new Ellipse instance based on the values contained in the given source. @@ -175343,7 +175369,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(107); +var Contains = __webpack_require__(109); /** * Check to see if the Ellipse contains the given Point object. @@ -175374,7 +175400,7 @@ module.exports = ContainsPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(107); +var Contains = __webpack_require__(109); /** * Check to see if the Ellipse contains all four points of the given Rectangle object. @@ -175588,7 +175614,7 @@ module.exports = OffsetPoint; */ var Point = __webpack_require__(4); -var CircleToCircle = __webpack_require__(226); +var CircleToCircle = __webpack_require__(228); /** * Checks if two Circles intersect and returns the intersection points as a Point object array. @@ -175681,8 +175707,8 @@ module.exports = GetCircleToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToCircle = __webpack_require__(227); -var CircleToRectangle = __webpack_require__(149); +var GetLineToCircle = __webpack_require__(229); +var CircleToRectangle = __webpack_require__(150); /** * Checks for intersection between a circle and a rectangle, @@ -175731,7 +175757,7 @@ module.exports = GetCircleToRectangle; */ var Vector4 = __webpack_require__(138); -var GetLineToPolygon = __webpack_require__(465); +var GetLineToPolygon = __webpack_require__(481); var Line = __webpack_require__(45); // Temp calculation segment @@ -175833,7 +175859,7 @@ module.exports = GetRaysFromPointToPolygon; */ var Rectangle = __webpack_require__(10); -var RectangleToRectangle = __webpack_require__(112); +var RectangleToRectangle = __webpack_require__(114); /** * Checks if two Rectangle shapes intersect and returns the area of this intersection as Rectangle object. @@ -175882,8 +175908,8 @@ module.exports = GetRectangleIntersection; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToRectangle = __webpack_require__(229); -var RectangleToRectangle = __webpack_require__(112); +var GetLineToRectangle = __webpack_require__(231); +var RectangleToRectangle = __webpack_require__(114); /** * Checks if two Rectangles intersect and returns the intersection points as a Point object array. @@ -175933,8 +175959,8 @@ module.exports = GetRectangleToRectangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RectangleToTriangle = __webpack_require__(467); -var GetLineToRectangle = __webpack_require__(229); +var RectangleToTriangle = __webpack_require__(483); +var GetLineToRectangle = __webpack_require__(231); /** * Checks for intersection between Rectangle shape and Triangle shape, @@ -175981,8 +176007,8 @@ module.exports = GetRectangleToTriangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToCircle = __webpack_require__(227); -var TriangleToCircle = __webpack_require__(469); +var GetLineToCircle = __webpack_require__(229); +var TriangleToCircle = __webpack_require__(485); /** * Checks if a Triangle and a Circle intersect, and returns the intersection points as a Point object array. @@ -176030,8 +176056,8 @@ module.exports = GetTriangleToCircle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TriangleToTriangle = __webpack_require__(472); -var GetTriangleToLine = __webpack_require__(470); +var TriangleToTriangle = __webpack_require__(488); +var GetTriangleToLine = __webpack_require__(486); /** * Checks if two Triangles intersect, and returns the intersection points as a Point object array. @@ -176078,7 +176104,7 @@ module.exports = GetTriangleToTriangle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PointToLine = __webpack_require__(474); +var PointToLine = __webpack_require__(490); /** * Checks if a Point is located on the given line segment. @@ -176161,7 +176187,7 @@ module.exports = RectangleToValues; var Line = __webpack_require__(45); -Line.Angle = __webpack_require__(92); +Line.Angle = __webpack_require__(93); Line.BresenhamPoints = __webpack_require__(311); Line.CenterOn = __webpack_require__(1216); Line.Clone = __webpack_require__(1217); @@ -176173,20 +176199,20 @@ Line.GetMidPoint = __webpack_require__(1222); Line.GetNearestPoint = __webpack_require__(1223); Line.GetNormal = __webpack_require__(1224); Line.GetPoint = __webpack_require__(301); -Line.GetPoints = __webpack_require__(167); +Line.GetPoints = __webpack_require__(168); Line.GetShortestDistance = __webpack_require__(1225); Line.Height = __webpack_require__(1226); -Line.Length = __webpack_require__(63); -Line.NormalAngle = __webpack_require__(475); +Line.Length = __webpack_require__(64); +Line.NormalAngle = __webpack_require__(491); Line.NormalX = __webpack_require__(1227); Line.NormalY = __webpack_require__(1228); Line.Offset = __webpack_require__(1229); Line.PerpSlope = __webpack_require__(1230); -Line.Random = __webpack_require__(168); +Line.Random = __webpack_require__(169); Line.ReflectAngle = __webpack_require__(1231); Line.Rotate = __webpack_require__(1232); Line.RotateAroundPoint = __webpack_require__(1233); -Line.RotateAroundXY = __webpack_require__(231); +Line.RotateAroundXY = __webpack_require__(233); Line.SetToAngle = __webpack_require__(1234); Line.Slope = __webpack_require__(1235); Line.Width = __webpack_require__(1236); @@ -176339,7 +176365,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); /** * Extends the start and end points of a Line by the given amounts. @@ -176611,7 +176637,7 @@ module.exports = GetNearestPoint; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); var Point = __webpack_require__(4); /** @@ -176730,7 +176756,7 @@ module.exports = Height; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); /** * Returns the x component of the normal vector of the given line. @@ -176761,7 +176787,7 @@ module.exports = NormalX; */ var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(92); +var Angle = __webpack_require__(93); /** * The Y value of the normal of the given line. @@ -176858,8 +176884,8 @@ module.exports = PerpSlope; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Angle = __webpack_require__(92); -var NormalAngle = __webpack_require__(475); +var Angle = __webpack_require__(93); +var NormalAngle = __webpack_require__(491); /** * Calculate the reflected angle between two lines. @@ -176892,7 +176918,7 @@ module.exports = ReflectAngle; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(231); +var RotateAroundXY = __webpack_require__(233); /** * Rotate a line around its midpoint by the given angle in radians. @@ -176928,7 +176954,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(231); +var RotateAroundXY = __webpack_require__(233); /** * Rotate a line around a point by the given angle in radians. @@ -177064,14 +177090,14 @@ module.exports = Width; var Mesh = { - Face: __webpack_require__(111), + Face: __webpack_require__(113), GenerateGridVerts: __webpack_require__(1238), - GenerateObjVerts: __webpack_require__(458), - GenerateVerts: __webpack_require__(457), - ParseObj: __webpack_require__(476), - ParseObjMaterial: __webpack_require__(477), + GenerateObjVerts: __webpack_require__(474), + GenerateVerts: __webpack_require__(473), + ParseObj: __webpack_require__(492), + ParseObjMaterial: __webpack_require__(493), RotateFace: __webpack_require__(1239), - Vertex: __webpack_require__(113) + Vertex: __webpack_require__(115) }; @@ -177088,11 +177114,11 @@ module.exports = Mesh; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Face = __webpack_require__(111); +var Face = __webpack_require__(113); var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(65); -var Vector3 = __webpack_require__(36); -var Vertex = __webpack_require__(113); +var Matrix4 = __webpack_require__(67); +var Vector3 = __webpack_require__(37); +var Vertex = __webpack_require__(115); var tempPosition = new Vector3(); var tempRotation = new Vector3(); @@ -177403,8 +177429,8 @@ Point.CopyFrom = __webpack_require__(1243); Point.Equals = __webpack_require__(1244); Point.Floor = __webpack_require__(1245); Point.GetCentroid = __webpack_require__(1246); -Point.GetMagnitude = __webpack_require__(478); -Point.GetMagnitudeSq = __webpack_require__(479); +Point.GetMagnitude = __webpack_require__(494); +Point.GetMagnitudeSq = __webpack_require__(495); Point.GetRectangleFromPoints = __webpack_require__(1247); Point.Interpolate = __webpack_require__(1248); Point.Invert = __webpack_require__(1249); @@ -177817,7 +177843,7 @@ module.exports = Negative; */ var Point = __webpack_require__(4); -var GetMagnitudeSq = __webpack_require__(479); +var GetMagnitudeSq = __webpack_require__(495); /** * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the @@ -177908,7 +177934,7 @@ module.exports = ProjectUnit; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetMagnitude = __webpack_require__(478); +var GetMagnitude = __webpack_require__(494); /** * Changes the magnitude (length) of a two-dimensional vector without changing its direction. @@ -177952,19 +177978,19 @@ module.exports = SetMagnitude; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Polygon = __webpack_require__(222); +var Polygon = __webpack_require__(224); Polygon.Clone = __webpack_require__(1255); -Polygon.Contains = __webpack_require__(223); +Polygon.Contains = __webpack_require__(225); Polygon.ContainsPoint = __webpack_require__(1256); -Polygon.Earcut = __webpack_require__(67); -Polygon.GetAABB = __webpack_require__(447); +Polygon.Earcut = __webpack_require__(68); +Polygon.GetAABB = __webpack_require__(463); Polygon.GetNumberArray = __webpack_require__(1257); -Polygon.GetPoints = __webpack_require__(448); -Polygon.Perimeter = __webpack_require__(449); +Polygon.GetPoints = __webpack_require__(464); +Polygon.Perimeter = __webpack_require__(465); Polygon.Reverse = __webpack_require__(1258); Polygon.Simplify = __webpack_require__(1259); -Polygon.Smooth = __webpack_require__(450); +Polygon.Smooth = __webpack_require__(466); Polygon.Translate = __webpack_require__(1260); module.exports = Polygon; @@ -177980,7 +178006,7 @@ module.exports = Polygon; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Polygon = __webpack_require__(222); +var Polygon = __webpack_require__(224); /** * Create a new polygon which is a copy of the specified polygon @@ -178010,7 +178036,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(223); +var Contains = __webpack_require__(225); /** * Checks the given Point again the Polygon to see if the Point lays within its vertices. @@ -178583,7 +178609,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetAspectRatio = __webpack_require__(232); +var GetAspectRatio = __webpack_require__(234); /** * Adjusts the target rectangle, changing its width, height and position, @@ -178636,7 +178662,7 @@ module.exports = FitInside; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetAspectRatio = __webpack_require__(232); +var GetAspectRatio = __webpack_require__(234); /** * Adjusts the target rectangle, changing its width, height and position, @@ -178878,7 +178904,7 @@ module.exports = GetSize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CenterOn = __webpack_require__(186); +var CenterOn = __webpack_require__(187); /** @@ -178921,7 +178947,7 @@ module.exports = Inflate; */ var Rectangle = __webpack_require__(10); -var Intersects = __webpack_require__(112); +var Intersects = __webpack_require__(114); /** * Takes two Rectangles and first checks to see if they intersect. @@ -179215,7 +179241,7 @@ module.exports = Overlaps; */ var Point = __webpack_require__(4); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); /** * Returns a Point from the perimeter of a Rectangle based on the given angle. @@ -179271,8 +179297,8 @@ module.exports = PerimeterPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Between = __webpack_require__(191); -var ContainsRect = __webpack_require__(481); +var Between = __webpack_require__(192); +var ContainsRect = __webpack_require__(497); var Point = __webpack_require__(4); /** @@ -179417,25 +179443,25 @@ Triangle.BuildEquilateral = __webpack_require__(1289); Triangle.BuildFromPolygon = __webpack_require__(1290); Triangle.BuildRight = __webpack_require__(1291); Triangle.CenterOn = __webpack_require__(1292); -Triangle.Centroid = __webpack_require__(482); +Triangle.Centroid = __webpack_require__(498); Triangle.CircumCenter = __webpack_require__(1293); Triangle.CircumCircle = __webpack_require__(1294); Triangle.Clone = __webpack_require__(1295); -Triangle.Contains = __webpack_require__(110); -Triangle.ContainsArray = __webpack_require__(230); +Triangle.Contains = __webpack_require__(112); +Triangle.ContainsArray = __webpack_require__(232); Triangle.ContainsPoint = __webpack_require__(1296); Triangle.CopyFrom = __webpack_require__(1297); -Triangle.Decompose = __webpack_require__(473); +Triangle.Decompose = __webpack_require__(489); Triangle.Equals = __webpack_require__(1298); -Triangle.GetPoint = __webpack_require__(454); -Triangle.GetPoints = __webpack_require__(455); -Triangle.InCenter = __webpack_require__(484); +Triangle.GetPoint = __webpack_require__(470); +Triangle.GetPoints = __webpack_require__(471); +Triangle.InCenter = __webpack_require__(500); Triangle.Perimeter = __webpack_require__(1299); -Triangle.Offset = __webpack_require__(483); -Triangle.Random = __webpack_require__(177); +Triangle.Offset = __webpack_require__(499); +Triangle.Random = __webpack_require__(178); Triangle.Rotate = __webpack_require__(1300); Triangle.RotateAroundPoint = __webpack_require__(1301); -Triangle.RotateAroundXY = __webpack_require__(233); +Triangle.RotateAroundXY = __webpack_require__(235); module.exports = Triangle; @@ -179533,7 +179559,7 @@ module.exports = BuildEquilateral; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var EarCut = __webpack_require__(67); +var EarCut = __webpack_require__(68); var Triangle = __webpack_require__(82); /** @@ -179658,8 +179684,8 @@ module.exports = BuildRight; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Centroid = __webpack_require__(482); -var Offset = __webpack_require__(483); +var Centroid = __webpack_require__(498); +var Offset = __webpack_require__(499); /** * @callback CenterFunction @@ -179787,7 +179813,7 @@ module.exports = CircumCenter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); +var Circle = __webpack_require__(62); // Adapted from https://gist.github.com/mutoo/5617691 @@ -179900,7 +179926,7 @@ module.exports = Clone; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(110); +var Contains = __webpack_require__(112); /** * Tests if a triangle contains a point. @@ -179998,7 +180024,7 @@ module.exports = Equals; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(63); +var Length = __webpack_require__(64); /** * Gets the length of the perimeter of the given triangle. @@ -180033,8 +180059,8 @@ module.exports = Perimeter; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(233); -var InCenter = __webpack_require__(484); +var RotateAroundXY = __webpack_require__(235); +var InCenter = __webpack_require__(500); /** * Rotates a Triangle about its incenter, which is the point at which its three angle bisectors meet. @@ -180069,7 +180095,7 @@ module.exports = Rotate; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(233); +var RotateAroundXY = __webpack_require__(235); /** * Rotates a Triangle at a certain angle about a given Point or object with public `x` and `y` properties. @@ -180103,8 +180129,8 @@ module.exports = RotateAroundPoint; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(198); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(200); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Input @@ -180112,16 +180138,16 @@ var Extend = __webpack_require__(19); var Input = { - CreatePixelPerfectHandler: __webpack_require__(485), - CreateInteractiveObject: __webpack_require__(486), + CreatePixelPerfectHandler: __webpack_require__(501), + CreateInteractiveObject: __webpack_require__(502), Events: __webpack_require__(49), Gamepad: __webpack_require__(1303), - InputManager: __webpack_require__(387), + InputManager: __webpack_require__(403), InputPlugin: __webpack_require__(1315), - InputPluginCache: __webpack_require__(150), + InputPluginCache: __webpack_require__(151), Keyboard: __webpack_require__(1316), Mouse: __webpack_require__(1330), - Pointer: __webpack_require__(390), + Pointer: __webpack_require__(406), Touch: __webpack_require__(1331) }; @@ -180148,10 +180174,10 @@ module.exports = Input; module.exports = { - Axis: __webpack_require__(487), - Button: __webpack_require__(488), - Events: __webpack_require__(234), - Gamepad: __webpack_require__(489), + Axis: __webpack_require__(503), + Button: __webpack_require__(504), + Events: __webpack_require__(236), + Gamepad: __webpack_require__(505), GamepadPlugin: __webpack_require__(1310), Configs: __webpack_require__(1311) @@ -180349,10 +180375,10 @@ module.exports = 'up'; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(234); -var Gamepad = __webpack_require__(489); +var Events = __webpack_require__(236); +var Gamepad = __webpack_require__(505); var GetValue = __webpack_require__(6); -var InputPluginCache = __webpack_require__(150); +var InputPluginCache = __webpack_require__(151); var InputEvents = __webpack_require__(49); /** @@ -181156,27 +181182,27 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(61); -var CircleContains = __webpack_require__(62); +var Circle = __webpack_require__(62); +var CircleContains = __webpack_require__(63); var Class = __webpack_require__(0); -var CONST = __webpack_require__(198); -var CreateInteractiveObject = __webpack_require__(486); -var CreatePixelPerfectHandler = __webpack_require__(485); +var CONST = __webpack_require__(200); +var CreateInteractiveObject = __webpack_require__(502); +var CreatePixelPerfectHandler = __webpack_require__(501); var DistanceBetween = __webpack_require__(48); -var Ellipse = __webpack_require__(106); -var EllipseContains = __webpack_require__(107); +var Ellipse = __webpack_require__(108); +var EllipseContains = __webpack_require__(109); var Events = __webpack_require__(49); var EventEmitter = __webpack_require__(9); var GetFastValue = __webpack_require__(2); var GEOM_CONST = __webpack_require__(55); -var InputPluginCache = __webpack_require__(150); +var InputPluginCache = __webpack_require__(151); var IsPlainObject = __webpack_require__(7); var PluginCache = __webpack_require__(24); var Rectangle = __webpack_require__(10); var RectangleContains = __webpack_require__(56); var SceneEvents = __webpack_require__(21); var Triangle = __webpack_require__(82); -var TriangleContains = __webpack_require__(110); +var TriangleContains = __webpack_require__(112); /** * @classdesc @@ -184344,19 +184370,19 @@ module.exports = InputPlugin; module.exports = { - Events: __webpack_require__(151), + Events: __webpack_require__(152), - KeyboardManager: __webpack_require__(388), + KeyboardManager: __webpack_require__(404), KeyboardPlugin: __webpack_require__(1324), - Key: __webpack_require__(490), - KeyCodes: __webpack_require__(140), + Key: __webpack_require__(506), + KeyCodes: __webpack_require__(141), - KeyCombo: __webpack_require__(491), + KeyCombo: __webpack_require__(507), - AdvanceKeyCombo: __webpack_require__(493), - ProcessKeyCombo: __webpack_require__(492), - ResetKeyCombo: __webpack_require__(494), + AdvanceKeyCombo: __webpack_require__(509), + ProcessKeyCombo: __webpack_require__(508), + ResetKeyCombo: __webpack_require__(510), JustDown: __webpack_require__(1326), JustUp: __webpack_require__(1327), @@ -184616,14 +184642,14 @@ module.exports = 'up'; var Class = __webpack_require__(0); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(151); +var Events = __webpack_require__(152); var GameEvents = __webpack_require__(22); var GetValue = __webpack_require__(6); var InputEvents = __webpack_require__(49); -var InputPluginCache = __webpack_require__(150); -var Key = __webpack_require__(490); -var KeyCodes = __webpack_require__(140); -var KeyCombo = __webpack_require__(491); +var InputPluginCache = __webpack_require__(151); +var Key = __webpack_require__(506); +var KeyCodes = __webpack_require__(141); +var KeyCombo = __webpack_require__(507); var KeyMap = __webpack_require__(1325); var SceneEvents = __webpack_require__(21); var SnapFloor = __webpack_require__(76); @@ -185549,7 +185575,7 @@ module.exports = KeyboardPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var KeyCodes = __webpack_require__(140); +var KeyCodes = __webpack_require__(141); var KeyMap = {}; @@ -185730,7 +185756,7 @@ module.exports = UpDuration; /* eslint-disable */ module.exports = { - MouseManager: __webpack_require__(389) + MouseManager: __webpack_require__(405) }; /* eslint-enable */ @@ -185753,7 +185779,7 @@ module.exports = { /* eslint-disable */ module.exports = { - TouchManager: __webpack_require__(391) + TouchManager: __webpack_require__(407) }; /* eslint-enable */ @@ -185770,7 +185796,7 @@ module.exports = { */ var CONST = __webpack_require__(20); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Loader @@ -185778,18 +185804,18 @@ var Extend = __webpack_require__(19); var Loader = { - Events: __webpack_require__(90), + Events: __webpack_require__(91), FileTypes: __webpack_require__(1333), File: __webpack_require__(23), FileTypesManager: __webpack_require__(8), - GetURL: __webpack_require__(152), + GetURL: __webpack_require__(153), LoaderPlugin: __webpack_require__(1359), - MergeXHRSettings: __webpack_require__(235), + MergeXHRSettings: __webpack_require__(237), MultiFile: __webpack_require__(47), - XHRLoader: __webpack_require__(495), - XHRSettings: __webpack_require__(153) + XHRLoader: __webpack_require__(511), + XHRSettings: __webpack_require__(154) }; @@ -185819,17 +185845,17 @@ module.exports = { AsepriteFile: __webpack_require__(1335), AtlasJSONFile: __webpack_require__(1336), AtlasXMLFile: __webpack_require__(1337), - AudioFile: __webpack_require__(496), + AudioFile: __webpack_require__(512), AudioSpriteFile: __webpack_require__(1338), BinaryFile: __webpack_require__(1339), BitmapFontFile: __webpack_require__(1340), CSSFile: __webpack_require__(1341), GLSLFile: __webpack_require__(1342), - HTML5AudioFile: __webpack_require__(497), + HTML5AudioFile: __webpack_require__(513), HTMLFile: __webpack_require__(1343), HTMLTextureFile: __webpack_require__(1344), - ImageFile: __webpack_require__(69), - JSONFile: __webpack_require__(58), + ImageFile: __webpack_require__(70), + JSONFile: __webpack_require__(59), MultiAtlasFile: __webpack_require__(1345), MultiScriptFile: __webpack_require__(1346), OBJFile: __webpack_require__(1347), @@ -185837,16 +185863,16 @@ module.exports = { PluginFile: __webpack_require__(1349), SceneFile: __webpack_require__(1350), ScenePluginFile: __webpack_require__(1351), - ScriptFile: __webpack_require__(498), + ScriptFile: __webpack_require__(514), SpriteSheetFile: __webpack_require__(1352), SVGFile: __webpack_require__(1353), - TextFile: __webpack_require__(237), + TextFile: __webpack_require__(239), TilemapCSVFile: __webpack_require__(1354), TilemapImpactFile: __webpack_require__(1355), TilemapJSONFile: __webpack_require__(1356), UnityAtlasFile: __webpack_require__(1357), VideoFile: __webpack_require__(1358), - XMLFile: __webpack_require__(236) + XMLFile: __webpack_require__(238) }; @@ -185863,8 +185889,8 @@ module.exports = { var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var LoaderEvents = __webpack_require__(90); +var JSONFile = __webpack_require__(59); +var LoaderEvents = __webpack_require__(91); /** * @classdesc @@ -186065,9 +186091,9 @@ module.exports = AnimationJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -186335,9 +186361,9 @@ module.exports = AsepriteFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -186582,10 +186608,10 @@ module.exports = AtlasJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var XMLFile = __webpack_require__(236); +var XMLFile = __webpack_require__(238); /** * @classdesc @@ -186820,12 +186846,12 @@ module.exports = AtlasXMLFile; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AudioFile = __webpack_require__(496); +var AudioFile = __webpack_require__(512); var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -187295,11 +187321,11 @@ module.exports = BinaryFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ParseXMLBitmapFont = __webpack_require__(207); -var XMLFile = __webpack_require__(236); +var ParseXMLBitmapFont = __webpack_require__(209); +var XMLFile = __webpack_require__(238); /** * @classdesc @@ -187712,7 +187738,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var Shader = __webpack_require__(374); +var Shader = __webpack_require__(390); /** * @classdesc @@ -188553,9 +188579,9 @@ module.exports = HTMLTextureFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); var MultiFile = __webpack_require__(47); /** @@ -188888,7 +188914,7 @@ var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ScriptFile = __webpack_require__(498); +var ScriptFile = __webpack_require__(514); /** * @classdesc @@ -189105,9 +189131,9 @@ var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var ParseObj = __webpack_require__(476); -var ParseObjMaterial = __webpack_require__(477); -var TextFile = __webpack_require__(237); +var ParseObj = __webpack_require__(492); +var ParseObjMaterial = __webpack_require__(493); +var TextFile = __webpack_require__(239); /** * @classdesc @@ -189357,7 +189383,7 @@ module.exports = OBJFile; var Class = __webpack_require__(0); var CONST = __webpack_require__(20); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); +var JSONFile = __webpack_require__(59); /** * @classdesc @@ -190212,7 +190238,7 @@ module.exports = ScenePluginFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); /** * @classdesc @@ -190746,7 +190772,7 @@ var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); -var TILEMAP_FORMATS = __webpack_require__(37); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -190937,8 +190963,8 @@ module.exports = TilemapCSVFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var TILEMAP_FORMATS = __webpack_require__(37); +var JSONFile = __webpack_require__(59); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -191093,8 +191119,8 @@ module.exports = TilemapImpactFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(58); -var TILEMAP_FORMATS = __webpack_require__(37); +var JSONFile = __webpack_require__(59); +var TILEMAP_FORMATS = __webpack_require__(38); /** * @classdesc @@ -191250,10 +191276,10 @@ module.exports = TilemapJSONFile; var Class = __webpack_require__(0); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(69); +var ImageFile = __webpack_require__(70); var IsPlainObject = __webpack_require__(7); var MultiFile = __webpack_require__(47); -var TextFile = __webpack_require__(237); +var TextFile = __webpack_require__(239); /** * @classdesc @@ -191491,7 +191517,7 @@ var Class = __webpack_require__(0); var CONST = __webpack_require__(20); var File = __webpack_require__(23); var FileTypesManager = __webpack_require__(8); -var GetURL = __webpack_require__(152); +var GetURL = __webpack_require__(153); var GetFastValue = __webpack_require__(2); var IsPlainObject = __webpack_require__(7); @@ -191883,14 +191909,14 @@ module.exports = VideoFile; var Class = __webpack_require__(0); var CONST = __webpack_require__(20); -var CustomSet = __webpack_require__(147); +var CustomSet = __webpack_require__(148); var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(90); +var Events = __webpack_require__(91); var FileTypesManager = __webpack_require__(8); var GetFastValue = __webpack_require__(2); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var XHRSettings = __webpack_require__(153); +var XHRSettings = __webpack_require__(154); /** * @classdesc @@ -192964,8 +192990,8 @@ module.exports = LoaderPlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(59); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(60); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Physics.Arcade @@ -192974,22 +193000,22 @@ var Extend = __webpack_require__(19); var Arcade = { ArcadePhysics: __webpack_require__(1361), - Body: __webpack_require__(505), - Collider: __webpack_require__(506), - Components: __webpack_require__(238), - Events: __webpack_require__(240), - Factory: __webpack_require__(499), - GetOverlapX: __webpack_require__(241), - GetOverlapY: __webpack_require__(242), - SeparateX: __webpack_require__(515), - SeparateY: __webpack_require__(516), - Group: __webpack_require__(502), - Image: __webpack_require__(500), - Sprite: __webpack_require__(154), - StaticBody: __webpack_require__(517), - StaticGroup: __webpack_require__(503), + Body: __webpack_require__(521), + Collider: __webpack_require__(522), + Components: __webpack_require__(240), + Events: __webpack_require__(242), + Factory: __webpack_require__(515), + GetOverlapX: __webpack_require__(243), + GetOverlapY: __webpack_require__(244), + SeparateX: __webpack_require__(531), + SeparateY: __webpack_require__(532), + Group: __webpack_require__(518), + Image: __webpack_require__(516), + Sprite: __webpack_require__(155), + StaticBody: __webpack_require__(533), + StaticGroup: __webpack_require__(519), Tilemap: __webpack_require__(1385), - World: __webpack_require__(504) + World: __webpack_require__(520) }; @@ -193010,18 +193036,18 @@ module.exports = Arcade; */ var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(33); +var DegToRad = __webpack_require__(34); var DistanceBetween = __webpack_require__(48); var DistanceSquared = __webpack_require__(347); -var Factory = __webpack_require__(499); +var Factory = __webpack_require__(515); var GetFastValue = __webpack_require__(2); -var Merge = __webpack_require__(142); -var OverlapCirc = __webpack_require__(501); -var OverlapRect = __webpack_require__(239); +var Merge = __webpack_require__(143); +var OverlapCirc = __webpack_require__(517); +var OverlapRect = __webpack_require__(241); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); var Vector2 = __webpack_require__(3); -var World = __webpack_require__(504); +var World = __webpack_require__(520); /** * @classdesc @@ -195952,13 +195978,13 @@ module.exports = { var Tilemap = { - ProcessTileCallbacks: __webpack_require__(508), - ProcessTileSeparationX: __webpack_require__(512), - ProcessTileSeparationY: __webpack_require__(514), - SeparateTile: __webpack_require__(510), - TileCheckX: __webpack_require__(511), - TileCheckY: __webpack_require__(513), - TileIntersectsBody: __webpack_require__(243) + ProcessTileCallbacks: __webpack_require__(524), + ProcessTileSeparationX: __webpack_require__(528), + ProcessTileSeparationY: __webpack_require__(530), + SeparateTile: __webpack_require__(526), + TileCheckX: __webpack_require__(527), + TileCheckY: __webpack_require__(529), + TileIntersectsBody: __webpack_require__(245) }; @@ -195978,10 +196004,10 @@ module.exports = Tilemap; */ var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var Common = __webpack_require__(50); var GetFastValue = __webpack_require__(2); -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); /** * Use PhysicsEditorParser.parseBody() to build a Matter body object, based on a physics data file @@ -196118,7 +196144,7 @@ module.exports = PhysicsEditorParser; */ var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); /** * Creates a body using the supplied physics data, as provided by a JSON file. @@ -196242,9 +196268,9 @@ var Composites = {}; module.exports = Composites; var Composite = __webpack_require__(163); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Common = __webpack_require__(50); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var Bodies = __webpack_require__(126); (function() { @@ -196575,7 +196601,7 @@ var Svg = {}; module.exports = Svg; -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); var Common = __webpack_require__(50); (function() { @@ -196799,13 +196825,13 @@ var Common = __webpack_require__(50); */ var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var Class = __webpack_require__(0); -var Components = __webpack_require__(518); +var Components = __webpack_require__(534); var EventEmitter = __webpack_require__(9); var GetFastValue = __webpack_require__(2); var HasValue = __webpack_require__(125); -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); /** * @classdesc @@ -197122,24 +197148,24 @@ module.exports = MatterTileBody; * @namespace Phaser.Physics.Matter.Matter */ -var Matter = __webpack_require__(1486); +var Matter = __webpack_require__(1493); -Matter.Body = __webpack_require__(70); +Matter.Body = __webpack_require__(71); Matter.Composite = __webpack_require__(163); Matter.World = __webpack_require__(1393); Matter.Detector = __webpack_require__(587); Matter.Grid = __webpack_require__(1394); Matter.Pairs = __webpack_require__(1395); -Matter.Pair = __webpack_require__(519); -Matter.Query = __webpack_require__(1487); +Matter.Pair = __webpack_require__(535); +Matter.Query = __webpack_require__(1494); Matter.Resolver = __webpack_require__(1396); Matter.SAT = __webpack_require__(588); -Matter.Constraint = __webpack_require__(244); +Matter.Constraint = __webpack_require__(246); Matter.Common = __webpack_require__(50); -Matter.Engine = __webpack_require__(1488); +Matter.Engine = __webpack_require__(1495); Matter.Events = __webpack_require__(268); Matter.Sleeping = __webpack_require__(267); Matter.Plugin = __webpack_require__(1392); @@ -197148,10 +197174,10 @@ Matter.Bodies = __webpack_require__(126); Matter.Composites = __webpack_require__(1388); Matter.Axes = __webpack_require__(585); -Matter.Bounds = __webpack_require__(115); +Matter.Bounds = __webpack_require__(117); Matter.Svg = __webpack_require__(1389); -Matter.Vector = __webpack_require__(114); -Matter.Vertices = __webpack_require__(93); +Matter.Vector = __webpack_require__(116); +Matter.Vertices = __webpack_require__(94); // aliases @@ -197537,7 +197563,7 @@ var World = {}; module.exports = World; var Composite = __webpack_require__(163); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Common = __webpack_require__(50); (function() { @@ -197682,7 +197708,7 @@ var Grid = {}; module.exports = Grid; -var Pair = __webpack_require__(519); +var Pair = __webpack_require__(535); var Detector = __webpack_require__(587); var Common = __webpack_require__(50); @@ -198009,7 +198035,7 @@ var Pairs = {}; module.exports = Pairs; -var Pair = __webpack_require__(519); +var Pair = __webpack_require__(535); var Common = __webpack_require__(50); (function() { @@ -198174,10 +198200,10 @@ var Resolver = {}; module.exports = Resolver; -var Vertices = __webpack_require__(93); -var Vector = __webpack_require__(114); +var Vertices = __webpack_require__(94); +var Vector = __webpack_require__(116); var Common = __webpack_require__(50); -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); (function() { @@ -198532,10 +198558,10 @@ var Bounds = __webpack_require__(115); module.exports = { - BasePlugin: __webpack_require__(520), - DefaultPlugins: __webpack_require__(193), + BasePlugin: __webpack_require__(536), + DefaultPlugins: __webpack_require__(194), PluginCache: __webpack_require__(24), - PluginManager: __webpack_require__(392), + PluginManager: __webpack_require__(408), ScenePlugin: __webpack_require__(1398) }; @@ -198551,7 +198577,7 @@ module.exports = { * @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License} */ -var BasePlugin = __webpack_require__(520); +var BasePlugin = __webpack_require__(536); var Class = __webpack_require__(0); var SceneEvents = __webpack_require__(21); @@ -198679,8 +198705,675 @@ module.exports = ScenePlugin; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var CONST = __webpack_require__(196); +/** + * @namespace Phaser.Renderer + */ + +/** + * @namespace Phaser.Types.Renderer + */ + +module.exports = { + + Canvas: __webpack_require__(1400), + Events: __webpack_require__(88), + Snapshot: __webpack_require__(1401), + WebGL: __webpack_require__(1402) + +}; + + +/***/ }), +/* 1400 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Canvas + */ + +module.exports = { + + CanvasRenderer: __webpack_require__(362), + GetBlendModes: __webpack_require__(364), + SetTransform: __webpack_require__(30) + +}; + + +/***/ }), +/* 1401 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Renderer.Snapshot + */ + +module.exports = { + + Canvas: __webpack_require__(363), + WebGL: __webpack_require__(377) + +}; + + +/***/ }), +/* 1402 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var WEBGL_CONST = __webpack_require__(104); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Renderer.WebGL + */ + +var WebGL = { + + PipelineManager: __webpack_require__(366), + Pipelines: __webpack_require__(1403), + RenderTarget: __webpack_require__(139), + Utils: __webpack_require__(12), + WebGLPipeline: __webpack_require__(57), + WebGLRenderer: __webpack_require__(365), + WebGLShader: __webpack_require__(369) + +}; + +// Merge in the consts + +WebGL = Extend(false, WebGL, WEBGL_CONST); + +// Export it + +module.exports = WebGL; + + +/***/ }), +/* 1403 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(65); +var Extend = __webpack_require__(17); + +/** + * @namespace Phaser.Renderer.WebGL.Pipelines + */ + +var Pipelines = { + + BitmapMaskPipeline: __webpack_require__(367), + Events: __webpack_require__(368), + GraphicsPipeline: __webpack_require__(370), + LightPipeline: __webpack_require__(371), + MultiPipeline: __webpack_require__(105), + PointLightPipeline: __webpack_require__(372), + PostFXPipeline: __webpack_require__(1404), + RopePipeline: __webpack_require__(373), + SinglePipeline: __webpack_require__(374), + UtilityPipeline: __webpack_require__(375) + +}; + +// Merge in the consts + +Pipelines = Extend(false, Pipelines, CONST); + +// Export it + +module.exports = Pipelines; + + +/***/ }), +/* 1404 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(0); +var ColorMatrix = __webpack_require__(195); +var GetFastValue = __webpack_require__(2); +var ShaderSourceFS = __webpack_require__(1405); +var ShaderSourceVS = __webpack_require__(376); +var WebGLPipeline = __webpack_require__(57); + +/** + * @classdesc + * The Post FX Pipeline is a special kind of pipeline specifically for handling post + * processing effects. Where-as a standard Pipeline allows you to control the process + * of rendering Game Objects by configuring the shaders and attributes used to draw them, + * a Post FX Pipeline is designed to allow you to apply processing _after_ the Game Object/s + * have been rendered. Typical examples of post processing effects are bloom filters, + * blurs, light effects and color manipulation. + * + * The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad + * in it. Game Objects can have a Post Pipeline set on them. Those objects are then rendered + * using their standard pipeline, but are redirected to the Render Targets owned by the + * post pipeline, which can then apply their own shaders and effects, before passing them + * back to the main renderer. + * + * Please see the Phaser 3 examples for further details on this extensive subject. + * + * The default fragment shader it uses can be found in `shaders/src/PostFX.frag`. + * The default vertex shader it uses can be found in `shaders/src/Quad.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * + * The vertices array layout is: + * + * -1, 1 B----C 1, 1 + * 0, 1 | /| 1, 1 + * | / | + * | / | + * |/ | + * -1, -1 A----D 1, -1 + * 0, 0 1, 0 + * + * A = -1, -1 (pos) and 0, 0 (uv) + * B = -1, 1 (pos) and 0, 1 (uv) + * C = 1, 1 (pos) and 1, 1 (uv) + * D = 1, -1 (pos) and 1, 0 (uv) + * + * First tri: A, B, C + * Second tri: A, C, D + * + * Array index: + * + * 0 = Tri 1 - Vert A - x pos + * 1 = Tri 1 - Vert A - y pos + * 2 = Tri 1 - Vert A - uv u + * 3 = Tri 1 - Vert A - uv v + * + * 4 = Tri 1 - Vert B - x pos + * 5 = Tri 1 - Vert B - y pos + * 6 = Tri 1 - Vert B - uv u + * 7 = Tri 1 - Vert B - uv v + * + * 8 = Tri 1 - Vert C - x pos + * 9 = Tri 1 - Vert C - y pos + * 10 = Tri 1 - Vert C - uv u + * 11 = Tri 1 - Vert C - uv v + * + * 12 = Tri 2 - Vert A - x pos + * 13 = Tri 2 - Vert A - y pos + * 14 = Tri 2 - Vert A - uv u + * 15 = Tri 2 - Vert A - uv v + * + * 16 = Tri 2 - Vert C - x pos + * 17 = Tri 2 - Vert C - y pos + * 18 = Tri 2 - Vert C - uv u + * 19 = Tri 2 - Vert C - uv v + * + * 20 = Tri 2 - Vert D - x pos + * 21 = Tri 2 - Vert D - y pos + * 22 = Tri 2 - Vert D - uv u + * 23 = Tri 2 - Vert D - uv v + * + * @class PostFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var PostFXPipeline = new Class({ + + Extends: WebGLPipeline, + + initialize: + + function PostFXPipeline (config) + { + config.renderTarget = GetFastValue(config, 'renderTarget', 1); + config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS); + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inTexCoord', + size: 2 + } + ]); + config.batchSize = 1; + config.vertices = [ + -1, -1, 0, 0, + -1, 1, 0, 1, + 1, 1, 1, 1, + -1, -1, 0, 0, + 1, 1, 1, 1, + 1, -1, 1, 0 + ]; + + WebGLPipeline.call(this, config); + + this.isPostFX = true; + + /** + * If this post-pipeline belongs to a Game Object or Camera, this contains a reference to it. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.50.0 + */ + this.gameObject; + + /** + * A Color Matrix instance belonging to this pipeline. + * + * Used during calls to the `drawFrame` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#colorMatrix + * @type {Phaser.Display.ColorMatrix} + * @since 3.50.0 + */ + this.colorMatrix = new ColorMatrix(); + + /** + * A reference to the Full Frame 1 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is the full size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.fullFrame1; + + /** + * A reference to the Full Frame 2 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is the full size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.fullFrame2; + + /** + * A reference to the Half Frame 1 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is half the size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.halfFrame1; + + /** + * A reference to the Half Frame 2 Render Target that belongs to the + * Utility Pipeline. This property is set during the `boot` method. + * + * This Render Target is half the size of the renderer. + * + * You can use this directly in Post FX Pipelines for multi-target effects. + * However, be aware that these targets are shared between all post fx pipelines. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 + */ + this.halfFrame2; + + if (this.renderer.isBooted) + { + this.manager = this.renderer.pipelines; + + this.boot(); + } + }, + + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + var utility = this.manager.UTILITY_PIPELINE; + + this.fullFrame1 = utility.fullFrame1; + this.fullFrame2 = utility.fullFrame2; + this.halfFrame1 = utility.halfFrame1; + this.halfFrame2 = utility.halfFrame2; + + this.set1i('uMainSampler', 0); + }, + + onDraw: function (renderTarget) + { + this.bindAndDraw(renderTarget); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * You can optionally set the brightness factor of the copy. + * + * The difference between this method and `drawFrame` is that this method + * uses a faster copy shader, where only the brightness can be modified. + * If you need color level manipulation, see `drawFrame` instead. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [brightness=1] - The brightness value applied to the frame copy. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + copyFrame: function (source, target, brightness, clear, clearAlpha) + { + this.manager.copyFrame(source, target, brightness, clear, clearAlpha); + }, + + /** + * Pops the framebuffer from the renderers FBO stack and sets that as the active target, + * then draws the `source` Render Target to it. It then resets the renderer textures. + * + * This should be done when you need to draw the _final_ results of a pipeline to the game + * canvas, or the next framebuffer in line on the FBO stack. You should only call this once + * in the `onDraw` handler and it should be the final thing called. Be careful not to call + * this if you need to actually use the pipeline shader, instead of the copy shader. In + * those cases, use the `bindAndDraw` method. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyToGame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + */ + copyToGame: function (source) + { + this.manager.copyToGame(source); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target, using the + * given Color Matrix. + * + * The difference between this method and `copyFrame` is that this method + * uses a color matrix shader, where you have full control over the luminance + * values used during the copy. If you don't need this, you can use the faster + * `copyFrame` method instead. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#drawFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + drawFrame: function (source, target, clearAlpha) + { + this.manager.drawFrame(source, target, clearAlpha, this.colorMatrix); + }, + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using a linear blend effect, which is controlled by the `strength` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFrames + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [strength=1] - The strength of the blend. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + blendFrames: function (source1, source2, target, strength, clearAlpha) + { + this.manager.blendFrames(source1, source2, target, strength, clearAlpha); + }, + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using an additive blend effect, which is controlled by the `strength` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFramesAdditive + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. + * @param {number} [strength=1] - The strength of the blend. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) + { + this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha); + }, + + /** + * Clears the given Render Target. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#clearFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + clearFrame: function (target, clearAlpha) + { + this.manager.clearFrame(target, clearAlpha); + }, + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * The difference with this copy is that no resizing takes place. If the `source` + * Render Target is larger than the `target` then only a portion the same size as + * the `target` dimensions is copied across. + * + * You can optionally set the brightness factor of the copy. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blitFrame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + * @param {number} [brightness=1] - The brightness value applied to the frame copy. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + * @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode? + */ + blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) + { + this.manager.blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); + }, + + /** + * Binds the `source` Render Target and then copies a section of it to the `target` Render Target. + * + * This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't + * require the use of any shaders. Remember the coordinates are given in standard WebGL format, + * where x and y specify the lower-left corner of the section, not the top-left. Also, the + * copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes + * place. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrameRect + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + * @param {number} x - The x coordinate of the lower left corner where to start copying. + * @param {number} y - The y coordinate of the lower left corner where to start copying. + * @param {number} width - The width of the texture. + * @param {number} height - The height of the texture. + * @param {boolean} [clear=true] - Clear the target before copying? + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + */ + copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) + { + this.manager.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); + }, + + /** + * Binds this pipeline and draws the `source` Render Target to the `target` Render Target. + * + * If no `target` is specified, it will pop the framebuffer from the Renderers FBO stack + * and use that instead, which should be done when you need to draw the final results of + * this pipeline to the game canvas. + * + * You can optionally set the shader to be used for the draw here, if this is a multi-shader + * pipeline. By default `currentShader` will be used. If you need to set a shader but not + * a target, just pass `null` as the `target` parameter. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bindAndDraw + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to draw to. If not set, it will pop the fbo from the stack. + * @param {boolean} [clear=true] - Clear the target before copying? Only used if `target` parameter is set. + * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to use during the draw. + */ + bindAndDraw: function (source, target, clear, clearAlpha, currentShader) + { + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } + + var gl = this.gl; + var renderer = this.renderer; + + this.bind(currentShader); + + this.set1i('uMainSampler', 0); + + if (target) + { + gl.viewport(0, 0, target.width, target.height); + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); + + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } + + gl.clear(gl.COLOR_BUFFER_BIT); + } + } + else + { + renderer.popFramebuffer(false, false, false); + + if (!renderer.currentFramebuffer) + { + gl.viewport(0, 0, renderer.width, renderer.height); + } + } + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); + + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); + + if (!target) + { + renderer.resetTextures(); + } + else + { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + } + +}); + +module.exports = PostFXPipeline; + + +/***/ }), +/* 1405 */ +/***/ (function(module, exports) { + +module.exports = [ + '#define SHADER_NAME PHASER_POSTFX_FS', + '', + 'precision mediump float;', + '', + 'uniform sampler2D uMainSampler;', + '', + 'varying vec2 outTexCoord;', + '', + 'void main ()', + '{', + ' gl_FragColor = texture2D(uMainSampler, outTexCoord);', + '}', + '' +].join('\n'); + + +/***/ }), +/* 1406 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Extend = __webpack_require__(17); +var CONST = __webpack_require__(198); /** * @namespace Phaser.Scale @@ -198708,12 +199401,12 @@ var CONST = __webpack_require__(196); var Scale = { - Center: __webpack_require__(381), + Center: __webpack_require__(397), Events: __webpack_require__(101), - Orientation: __webpack_require__(382), - ScaleManager: __webpack_require__(393), - ScaleModes: __webpack_require__(383), - Zoom: __webpack_require__(384) + Orientation: __webpack_require__(398), + ScaleManager: __webpack_require__(409), + ScaleModes: __webpack_require__(399), + Zoom: __webpack_require__(400) }; @@ -198726,7 +199419,7 @@ module.exports = Scale; /***/ }), -/* 1400 */ +/* 1407 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -198735,8 +199428,8 @@ module.exports = Scale; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(141); -var Extend = __webpack_require__(19); +var CONST = __webpack_require__(142); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Scenes @@ -198745,12 +199438,12 @@ var Extend = __webpack_require__(19); var Scene = { Events: __webpack_require__(21), - GetPhysicsPlugins: __webpack_require__(397), - GetScenePlugins: __webpack_require__(398), - SceneManager: __webpack_require__(395), - ScenePlugin: __webpack_require__(1401), - Settings: __webpack_require__(399), - Systems: __webpack_require__(199) + GetPhysicsPlugins: __webpack_require__(413), + GetScenePlugins: __webpack_require__(414), + SceneManager: __webpack_require__(411), + ScenePlugin: __webpack_require__(1408), + Settings: __webpack_require__(415), + Systems: __webpack_require__(201) }; @@ -198761,7 +199454,7 @@ module.exports = Scene; /***/ }), -/* 1401 */ +/* 1408 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -198770,7 +199463,7 @@ module.exports = Scene; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); var Class = __webpack_require__(0); var Events = __webpack_require__(21); var GetFastValue = __webpack_require__(2); @@ -199771,7 +200464,7 @@ module.exports = ScenePlugin; /***/ }), -/* 1402 */ +/* 1409 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -199786,19 +200479,19 @@ module.exports = ScenePlugin; module.exports = { - Events: __webpack_require__(416), - List: __webpack_require__(105), + Events: __webpack_require__(432), + List: __webpack_require__(107), Map: __webpack_require__(99), - ProcessQueue: __webpack_require__(206), - RTree: __webpack_require__(509), - Set: __webpack_require__(147), - Size: __webpack_require__(394) + ProcessQueue: __webpack_require__(208), + RTree: __webpack_require__(525), + Set: __webpack_require__(148), + Size: __webpack_require__(410) }; /***/ }), -/* 1403 */ +/* 1410 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -199807,8 +200500,8 @@ module.exports = { * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var FilterMode = __webpack_require__(1404); +var Extend = __webpack_require__(17); +var FilterMode = __webpack_require__(1411); /** * @namespace Phaser.Textures @@ -199834,14 +200527,14 @@ var FilterMode = __webpack_require__(1404); var Textures = { - CanvasTexture: __webpack_require__(401), + CanvasTexture: __webpack_require__(417), Events: __webpack_require__(103), FilterMode: FilterMode, - Frame: __webpack_require__(104), - Parsers: __webpack_require__(403), - Texture: __webpack_require__(201), - TextureManager: __webpack_require__(400), - TextureSource: __webpack_require__(402) + Frame: __webpack_require__(106), + Parsers: __webpack_require__(419), + Texture: __webpack_require__(203), + TextureManager: __webpack_require__(416), + TextureSource: __webpack_require__(418) }; @@ -199851,7 +200544,7 @@ module.exports = Textures; /***/ }), -/* 1404 */ +/* 1411 */ /***/ (function(module, exports) { /** @@ -199895,7 +200588,7 @@ module.exports = CONST; /***/ }), -/* 1405 */ +/* 1412 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -199904,8 +200597,8 @@ module.exports = CONST; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(19); -var CONST = __webpack_require__(1406); +var Extend = __webpack_require__(17); +var CONST = __webpack_require__(1413); /** * @namespace Phaser.Tilemaps @@ -199918,23 +200611,23 @@ var CONST = __webpack_require__(1406); var Tilemaps = { - Components: __webpack_require__(245), - Parsers: __webpack_require__(1439), + Components: __webpack_require__(247), + Parsers: __webpack_require__(1446), - Formats: __webpack_require__(37), - ImageCollection: __webpack_require__(556), - ParseToTilemap: __webpack_require__(256), + Formats: __webpack_require__(38), + ImageCollection: __webpack_require__(572), + ParseToTilemap: __webpack_require__(258), Tile: __webpack_require__(83), - Tilemap: __webpack_require__(560), - TilemapCreator: __webpack_require__(1445), - TilemapFactory: __webpack_require__(1446), - Tileset: __webpack_require__(119), - TilemapLayer: __webpack_require__(561), + Tilemap: __webpack_require__(576), + TilemapCreator: __webpack_require__(1452), + TilemapFactory: __webpack_require__(1453), + Tileset: __webpack_require__(121), + TilemapLayer: __webpack_require__(577), Orientation: __webpack_require__(29), - LayerData: __webpack_require__(117), - MapData: __webpack_require__(118), - ObjectLayer: __webpack_require__(552) + LayerData: __webpack_require__(119), + MapData: __webpack_require__(120), + ObjectLayer: __webpack_require__(568) }; @@ -199944,7 +200637,7 @@ module.exports = Tilemaps; /***/ }), -/* 1406 */ +/* 1413 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -199963,7 +200656,7 @@ module.exports = CONST; /***/ }), -/* 1407 */ +/* 1414 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -199973,7 +200666,7 @@ module.exports = CONST; */ var GetTilesWithin = __webpack_require__(26); -var CalculateFacesWithin = __webpack_require__(60); +var CalculateFacesWithin = __webpack_require__(61); /** * Copies the tiles in the source rectangular area to a new destination (all specified in tile @@ -200029,7 +200722,7 @@ module.exports = Copy; /***/ }), -/* 1408 */ +/* 1415 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200039,7 +200732,7 @@ module.exports = Copy; */ var GetTilesWithin = __webpack_require__(26); -var ReplaceByIndex = __webpack_require__(522); +var ReplaceByIndex = __webpack_require__(538); /** * Creates a Sprite for every object matching the given tile indexes in the layer. You can @@ -200116,7 +200809,7 @@ module.exports = CreateFromTiles; /***/ }), -/* 1409 */ +/* 1416 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200126,8 +200819,8 @@ module.exports = CreateFromTiles; */ var GetTilesWithin = __webpack_require__(26); -var CalculateFacesWithin = __webpack_require__(60); -var SetTileCollision = __webpack_require__(71); +var CalculateFacesWithin = __webpack_require__(61); +var SetTileCollision = __webpack_require__(72); /** * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the @@ -200169,7 +200862,7 @@ module.exports = Fill; /***/ }), -/* 1410 */ +/* 1417 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200212,7 +200905,7 @@ module.exports = FilterTiles; /***/ }), -/* 1411 */ +/* 1418 */ /***/ (function(module, exports) { /** @@ -200298,7 +200991,7 @@ module.exports = FindByIndex; /***/ }), -/* 1412 */ +/* 1419 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200349,7 +201042,7 @@ module.exports = FindTile; /***/ }), -/* 1413 */ +/* 1420 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200395,7 +201088,7 @@ module.exports = ForEachTile; /***/ }), -/* 1414 */ +/* 1421 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200405,11 +201098,11 @@ module.exports = ForEachTile; */ var CONST = __webpack_require__(29); -var CullTiles = __webpack_require__(524); -var HexagonalCullTiles = __webpack_require__(525); -var IsometricCullTiles = __webpack_require__(527); +var CullTiles = __webpack_require__(540); +var HexagonalCullTiles = __webpack_require__(541); +var IsometricCullTiles = __webpack_require__(543); var NOOP = __webpack_require__(1); -var StaggeredCullTiles = __webpack_require__(528); +var StaggeredCullTiles = __webpack_require__(544); /** * Gets the correct function to use to cull tiles, based on the map orientation. @@ -200449,7 +201142,7 @@ module.exports = GetCullTilesFunction; /***/ }), -/* 1415 */ +/* 1422 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200458,7 +201151,7 @@ module.exports = GetCullTilesFunction; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTileAt = __webpack_require__(155); +var GetTileAt = __webpack_require__(156); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -200488,7 +201181,7 @@ module.exports = GetTileAtWorldXY; /***/ }), -/* 1416 */ +/* 1423 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200497,9 +201190,9 @@ module.exports = GetTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Geom = __webpack_require__(461); +var Geom = __webpack_require__(477); var GetTilesWithin = __webpack_require__(26); -var Intersects = __webpack_require__(462); +var Intersects = __webpack_require__(478); var NOOP = __webpack_require__(1); var Vector2 = __webpack_require__(3); @@ -200603,7 +201296,7 @@ module.exports = GetTilesWithinShape; /***/ }), -/* 1417 */ +/* 1424 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200614,7 +201307,7 @@ module.exports = GetTilesWithinShape; var CONST = __webpack_require__(29); var NOOP = __webpack_require__(1); -var TileToWorldX = __webpack_require__(247); +var TileToWorldX = __webpack_require__(249); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200642,7 +201335,7 @@ module.exports = GetTileToWorldXFunction; /***/ }), -/* 1418 */ +/* 1425 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200652,11 +201345,11 @@ module.exports = GetTileToWorldXFunction; */ var CONST = __webpack_require__(29); -var HexagonalTileToWorldXY = __webpack_require__(530); -var IsometricTileToWorldXY = __webpack_require__(531); +var HexagonalTileToWorldXY = __webpack_require__(546); +var IsometricTileToWorldXY = __webpack_require__(547); var NOOP = __webpack_require__(1); -var StaggeredTileToWorldXY = __webpack_require__(532); -var TileToWorldXY = __webpack_require__(533); +var StaggeredTileToWorldXY = __webpack_require__(548); +var TileToWorldXY = __webpack_require__(549); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200696,7 +201389,7 @@ module.exports = GetTileToWorldXYFunction; /***/ }), -/* 1419 */ +/* 1426 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200706,10 +201399,10 @@ module.exports = GetTileToWorldXYFunction; */ var CONST = __webpack_require__(29); -var HexagonalTileToWorldY = __webpack_require__(534); +var HexagonalTileToWorldY = __webpack_require__(550); var NOOP = __webpack_require__(1); -var StaggeredTileToWorldY = __webpack_require__(535); -var TileToWorldY = __webpack_require__(248); +var StaggeredTileToWorldY = __webpack_require__(551); +var TileToWorldY = __webpack_require__(250); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200745,7 +201438,7 @@ module.exports = GetTileToWorldYFunction; /***/ }), -/* 1420 */ +/* 1427 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200756,7 +201449,7 @@ module.exports = GetTileToWorldYFunction; var CONST = __webpack_require__(29); var NOOP = __webpack_require__(1); -var WorldToTileX = __webpack_require__(249); +var WorldToTileX = __webpack_require__(251); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200784,7 +201477,7 @@ module.exports = GetWorldToTileXFunction; /***/ }), -/* 1421 */ +/* 1428 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200794,11 +201487,11 @@ module.exports = GetWorldToTileXFunction; */ var CONST = __webpack_require__(29); -var HexagonalWorldToTileXY = __webpack_require__(536); -var IsometricWorldToTileXY = __webpack_require__(537); +var HexagonalWorldToTileXY = __webpack_require__(552); +var IsometricWorldToTileXY = __webpack_require__(553); var NOOP = __webpack_require__(1); -var StaggeredWorldToTileXY = __webpack_require__(538); -var WorldToTileXY = __webpack_require__(539); +var StaggeredWorldToTileXY = __webpack_require__(554); +var WorldToTileXY = __webpack_require__(555); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200838,7 +201531,7 @@ module.exports = GetWorldToTileXYFunction; /***/ }), -/* 1422 */ +/* 1429 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200848,10 +201541,10 @@ module.exports = GetWorldToTileXYFunction; */ var CONST = __webpack_require__(29); -var HexagonalWorldToTileY = __webpack_require__(540); +var HexagonalWorldToTileY = __webpack_require__(556); var NOOP = __webpack_require__(1); -var StaggeredWorldToTileY = __webpack_require__(541); -var WorldToTileY = __webpack_require__(250); +var StaggeredWorldToTileY = __webpack_require__(557); +var WorldToTileY = __webpack_require__(252); /** * Gets the correct function to use to translate tiles, based on the map orientation. @@ -200887,7 +201580,7 @@ module.exports = GetWorldToTileYFunction; /***/ }), -/* 1423 */ +/* 1430 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200896,7 +201589,7 @@ module.exports = GetWorldToTileYFunction; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HasTileAt = __webpack_require__(542); +var HasTileAt = __webpack_require__(558); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -200929,7 +201622,7 @@ module.exports = HasTileAtWorldXY; /***/ }), -/* 1424 */ +/* 1431 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200938,7 +201631,7 @@ module.exports = HasTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PutTileAt = __webpack_require__(251); +var PutTileAt = __webpack_require__(253); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -200972,7 +201665,7 @@ module.exports = PutTileAtWorldXY; /***/ }), -/* 1425 */ +/* 1432 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -200981,8 +201674,8 @@ module.exports = PutTileAtWorldXY; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CalculateFacesWithin = __webpack_require__(60); -var PutTileAt = __webpack_require__(251); +var CalculateFacesWithin = __webpack_require__(61); +var PutTileAt = __webpack_require__(253); /** * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified @@ -201039,7 +201732,7 @@ module.exports = PutTilesAt; /***/ }), -/* 1426 */ +/* 1433 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201049,7 +201742,7 @@ module.exports = PutTilesAt; */ var GetTilesWithin = __webpack_require__(26); -var GetRandom = __webpack_require__(205); +var GetRandom = __webpack_require__(207); /** * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the @@ -201097,7 +201790,7 @@ module.exports = Randomize; /***/ }), -/* 1427 */ +/* 1434 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201106,7 +201799,7 @@ module.exports = Randomize; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RemoveTileAt = __webpack_require__(543); +var RemoveTileAt = __webpack_require__(559); var Vector2 = __webpack_require__(3); var point = new Vector2(); @@ -201138,7 +201831,7 @@ module.exports = RemoveTileAtWorldXY; /***/ }), -/* 1428 */ +/* 1435 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201148,7 +201841,7 @@ module.exports = RemoveTileAtWorldXY; */ var GetTilesWithin = __webpack_require__(26); -var Color = __webpack_require__(375); +var Color = __webpack_require__(391); var defaultTileColor = new Color(105, 210, 231, 150); var defaultCollidingTileColor = new Color(243, 134, 48, 200); @@ -201220,7 +201913,7 @@ module.exports = RenderDebug; /***/ }), -/* 1429 */ +/* 1436 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201229,9 +201922,9 @@ module.exports = RenderDebug; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on the given tile or tiles within a layer by index. You can pass in either a @@ -201291,7 +201984,7 @@ module.exports = SetCollision; /***/ }), -/* 1430 */ +/* 1437 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201300,9 +201993,9 @@ module.exports = SetCollision; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on a range of tiles in a layer whose index is between the specified `start` and @@ -201367,7 +202060,7 @@ module.exports = SetCollisionBetween; /***/ }), -/* 1431 */ +/* 1438 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201376,9 +202069,9 @@ module.exports = SetCollisionBetween; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); -var SetLayerCollisionIndex = __webpack_require__(157); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); +var SetLayerCollisionIndex = __webpack_require__(158); /** * Sets collision on all tiles in the given layer, except for tiles that have an index specified in @@ -201428,7 +202121,7 @@ module.exports = SetCollisionByExclusion; /***/ }), -/* 1432 */ +/* 1439 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201437,8 +202130,8 @@ module.exports = SetCollisionByExclusion; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); var HasValue = __webpack_require__(125); /** @@ -201503,7 +202196,7 @@ module.exports = SetCollisionByProperty; /***/ }), -/* 1433 */ +/* 1440 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201512,8 +202205,8 @@ module.exports = SetCollisionByProperty; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(71); -var CalculateFacesWithin = __webpack_require__(60); +var SetTileCollision = __webpack_require__(72); +var CalculateFacesWithin = __webpack_require__(61); /** * Sets collision on the tiles within a layer by checking each tile's collision group data @@ -201562,7 +202255,7 @@ module.exports = SetCollisionFromCollisionGroup; /***/ }), -/* 1434 */ +/* 1441 */ /***/ (function(module, exports) { /** @@ -201608,7 +202301,7 @@ module.exports = SetTileIndexCallback; /***/ }), -/* 1435 */ +/* 1442 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201649,7 +202342,7 @@ module.exports = SetTileLocationCallback; /***/ }), -/* 1436 */ +/* 1443 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201694,7 +202387,7 @@ module.exports = Shuffle; /***/ }), -/* 1437 */ +/* 1444 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201745,7 +202438,7 @@ module.exports = SwapByIndex; /***/ }), -/* 1438 */ +/* 1445 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201828,7 +202521,7 @@ module.exports = WeightedRandomize; /***/ }), -/* 1439 */ +/* 1446 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201843,19 +202536,19 @@ module.exports = WeightedRandomize; module.exports = { - FromOrientationString: __webpack_require__(252), - Parse: __webpack_require__(544), - Parse2DArray: __webpack_require__(253), - ParseCSV: __webpack_require__(545), + FromOrientationString: __webpack_require__(254), + Parse: __webpack_require__(560), + Parse2DArray: __webpack_require__(255), + ParseCSV: __webpack_require__(561), - Impact: __webpack_require__(1440), - Tiled: __webpack_require__(1441) + Impact: __webpack_require__(1447), + Tiled: __webpack_require__(1448) }; /***/ }), -/* 1440 */ +/* 1447 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201870,15 +202563,15 @@ module.exports = { module.exports = { - ParseTileLayers: __webpack_require__(558), - ParseTilesets: __webpack_require__(559), - ParseWeltmeister: __webpack_require__(557) + ParseTileLayers: __webpack_require__(574), + ParseTilesets: __webpack_require__(575), + ParseWeltmeister: __webpack_require__(573) }; /***/ }), -/* 1441 */ +/* 1448 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201893,23 +202586,23 @@ module.exports = { module.exports = { - AssignTileProperties: __webpack_require__(547), - Base64Decode: __webpack_require__(554), - BuildTilesetIndex: __webpack_require__(548), - CreateGroupLayer: __webpack_require__(158), - ParseGID: __webpack_require__(255), - ParseImageLayers: __webpack_require__(549), - ParseJSONTiled: __webpack_require__(546), - ParseObject: __webpack_require__(254), - ParseObjectLayers: __webpack_require__(550), - ParseTileLayers: __webpack_require__(553), - ParseTilesets: __webpack_require__(555) + AssignTileProperties: __webpack_require__(563), + Base64Decode: __webpack_require__(570), + BuildTilesetIndex: __webpack_require__(564), + CreateGroupLayer: __webpack_require__(159), + ParseGID: __webpack_require__(257), + ParseImageLayers: __webpack_require__(565), + ParseJSONTiled: __webpack_require__(562), + ParseObject: __webpack_require__(256), + ParseObjectLayers: __webpack_require__(566), + ParseTileLayers: __webpack_require__(569), + ParseTilesets: __webpack_require__(571) }; /***/ }), -/* 1442 */ +/* 1449 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -201923,12 +202616,12 @@ var renderCanvas = __webpack_require__(1); if (true) { - renderWebGL = __webpack_require__(1443); + renderWebGL = __webpack_require__(1450); } if (true) { - renderCanvas = __webpack_require__(1444); + renderCanvas = __webpack_require__(1451); } module.exports = { @@ -201940,7 +202633,7 @@ module.exports = { /***/ }), -/* 1443 */ +/* 1450 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202053,7 +202746,7 @@ module.exports = TilemapLayerWebGLRenderer; /***/ }), -/* 1444 */ +/* 1451 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202191,7 +202884,7 @@ module.exports = TilemapLayerCanvasRenderer; /***/ }), -/* 1445 */ +/* 1452 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202201,7 +202894,7 @@ module.exports = TilemapLayerCanvasRenderer; */ var GameObjectCreator = __webpack_require__(16); -var ParseToTilemap = __webpack_require__(256); +var ParseToTilemap = __webpack_require__(258); /** * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. @@ -202235,7 +202928,7 @@ GameObjectCreator.register('tilemap', function (config) /***/ }), -/* 1446 */ +/* 1453 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202245,7 +202938,7 @@ GameObjectCreator.register('tilemap', function (config) */ var GameObjectFactory = __webpack_require__(5); -var ParseToTilemap = __webpack_require__(256); +var ParseToTilemap = __webpack_require__(258); /** * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. @@ -202301,7 +202994,7 @@ GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, widt /***/ }), -/* 1447 */ +/* 1454 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202316,14 +203009,14 @@ GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, widt module.exports = { - Clock: __webpack_require__(1448), - TimerEvent: __webpack_require__(562) + Clock: __webpack_require__(1455), + TimerEvent: __webpack_require__(578) }; /***/ }), -/* 1448 */ +/* 1455 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202335,8 +203028,8 @@ module.exports = { var Class = __webpack_require__(0); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var TimerEvent = __webpack_require__(562); -var Remove = __webpack_require__(88); +var TimerEvent = __webpack_require__(578); +var Remove = __webpack_require__(89); /** * @classdesc @@ -202779,7 +203472,7 @@ module.exports = Clock; /***/ }), -/* 1449 */ +/* 1456 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202789,7 +203482,7 @@ module.exports = Clock; */ var CONST = __webpack_require__(97); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser.Tweens @@ -202797,13 +203490,13 @@ var Extend = __webpack_require__(19); var Tweens = { - Builders: __webpack_require__(1450), - Events: __webpack_require__(261), + Builders: __webpack_require__(1457), + Events: __webpack_require__(263), - TweenManager: __webpack_require__(1466), - Tween: __webpack_require__(260), - TweenData: __webpack_require__(262), - Timeline: __webpack_require__(568) + TweenManager: __webpack_require__(1473), + Tween: __webpack_require__(262), + TweenData: __webpack_require__(264), + Timeline: __webpack_require__(584) }; @@ -202814,7 +203507,7 @@ module.exports = Tweens; /***/ }), -/* 1450 */ +/* 1457 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -202831,21 +203524,21 @@ module.exports = { GetBoolean: __webpack_require__(96), GetEaseFunction: __webpack_require__(80), - GetNewValue: __webpack_require__(159), - GetProps: __webpack_require__(563), - GetTargets: __webpack_require__(257), - GetTweens: __webpack_require__(564), - GetValueOp: __webpack_require__(258), - NumberTweenBuilder: __webpack_require__(565), - StaggerBuilder: __webpack_require__(566), - TimelineBuilder: __webpack_require__(567), - TweenBuilder: __webpack_require__(160) + GetNewValue: __webpack_require__(160), + GetProps: __webpack_require__(579), + GetTargets: __webpack_require__(259), + GetTweens: __webpack_require__(580), + GetValueOp: __webpack_require__(260), + NumberTweenBuilder: __webpack_require__(581), + StaggerBuilder: __webpack_require__(582), + TimelineBuilder: __webpack_require__(583), + TweenBuilder: __webpack_require__(161) }; /***/ }), -/* 1451 */ +/* 1458 */ /***/ (function(module, exports) { /** @@ -202923,7 +203616,7 @@ module.exports = [ /***/ }), -/* 1452 */ +/* 1459 */ /***/ (function(module, exports) { /** @@ -202959,7 +203652,7 @@ module.exports = 'complete'; /***/ }), -/* 1453 */ +/* 1460 */ /***/ (function(module, exports) { /** @@ -202996,7 +203689,7 @@ module.exports = 'loop'; /***/ }), -/* 1454 */ +/* 1461 */ /***/ (function(module, exports) { /** @@ -203033,7 +203726,7 @@ module.exports = 'pause'; /***/ }), -/* 1455 */ +/* 1462 */ /***/ (function(module, exports) { /** @@ -203070,7 +203763,7 @@ module.exports = 'resume'; /***/ }), -/* 1456 */ +/* 1463 */ /***/ (function(module, exports) { /** @@ -203106,7 +203799,7 @@ module.exports = 'start'; /***/ }), -/* 1457 */ +/* 1464 */ /***/ (function(module, exports) { /** @@ -203143,7 +203836,7 @@ module.exports = 'update'; /***/ }), -/* 1458 */ +/* 1465 */ /***/ (function(module, exports) { /** @@ -203183,7 +203876,7 @@ module.exports = 'active'; /***/ }), -/* 1459 */ +/* 1466 */ /***/ (function(module, exports) { /** @@ -203224,7 +203917,7 @@ module.exports = 'complete'; /***/ }), -/* 1460 */ +/* 1467 */ /***/ (function(module, exports) { /** @@ -203268,7 +203961,7 @@ module.exports = 'loop'; /***/ }), -/* 1461 */ +/* 1468 */ /***/ (function(module, exports) { /** @@ -203313,7 +204006,7 @@ module.exports = 'repeat'; /***/ }), -/* 1462 */ +/* 1469 */ /***/ (function(module, exports) { /** @@ -203353,7 +204046,7 @@ module.exports = 'start'; /***/ }), -/* 1463 */ +/* 1470 */ /***/ (function(module, exports) { /** @@ -203389,7 +204082,7 @@ module.exports = 'stop'; /***/ }), -/* 1464 */ +/* 1471 */ /***/ (function(module, exports) { /** @@ -203432,7 +204125,7 @@ module.exports = 'update'; /***/ }), -/* 1465 */ +/* 1472 */ /***/ (function(module, exports) { /** @@ -203478,7 +204171,7 @@ module.exports = 'yoyo'; /***/ }), -/* 1466 */ +/* 1473 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -203487,15 +204180,15 @@ module.exports = 'yoyo'; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(88); +var ArrayRemove = __webpack_require__(89); var Class = __webpack_require__(0); -var NumberTweenBuilder = __webpack_require__(565); +var NumberTweenBuilder = __webpack_require__(581); var PluginCache = __webpack_require__(24); var SceneEvents = __webpack_require__(21); -var StaggerBuilder = __webpack_require__(566); -var TimelineBuilder = __webpack_require__(567); +var StaggerBuilder = __webpack_require__(582); +var TimelineBuilder = __webpack_require__(583); var TWEEN_CONST = __webpack_require__(97); -var TweenBuilder = __webpack_require__(160); +var TweenBuilder = __webpack_require__(161); /** * @classdesc @@ -204267,7 +204960,7 @@ module.exports = TweenManager; /***/ }), -/* 1467 */ +/* 1474 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204282,17 +204975,17 @@ module.exports = TweenManager; module.exports = { - Array: __webpack_require__(203), - Base64: __webpack_require__(1468), - Objects: __webpack_require__(1470), - String: __webpack_require__(1474), + Array: __webpack_require__(205), + Base64: __webpack_require__(1475), + Objects: __webpack_require__(1477), + String: __webpack_require__(1481), NOOP: __webpack_require__(1) }; /***/ }), -/* 1468 */ +/* 1475 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204307,14 +205000,14 @@ module.exports = { module.exports = { - ArrayBufferToBase64: __webpack_require__(1469), - Base64ToArrayBuffer: __webpack_require__(411) + ArrayBufferToBase64: __webpack_require__(1476), + Base64ToArrayBuffer: __webpack_require__(427) }; /***/ }), -/* 1469 */ +/* 1476 */ /***/ (function(module, exports) { /** @@ -204372,7 +205065,7 @@ module.exports = ArrayBufferToBase64; /***/ }), -/* 1470 */ +/* 1477 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204388,26 +205081,26 @@ module.exports = ArrayBufferToBase64; module.exports = { Clone: __webpack_require__(77), - DeepCopy: __webpack_require__(171), - Extend: __webpack_require__(19), + DeepCopy: __webpack_require__(172), + Extend: __webpack_require__(17), GetAdvancedValue: __webpack_require__(13), GetFastValue: __webpack_require__(2), - GetMinMaxValue: __webpack_require__(1471), + GetMinMaxValue: __webpack_require__(1478), GetValue: __webpack_require__(6), - HasAll: __webpack_require__(1472), - HasAny: __webpack_require__(433), + HasAll: __webpack_require__(1479), + HasAny: __webpack_require__(449), HasValue: __webpack_require__(125), IsPlainObject: __webpack_require__(7), - Merge: __webpack_require__(142), - MergeRight: __webpack_require__(1473), - Pick: __webpack_require__(551), - SetValue: __webpack_require__(456) + Merge: __webpack_require__(143), + MergeRight: __webpack_require__(1480), + Pick: __webpack_require__(567), + SetValue: __webpack_require__(472) }; /***/ }), -/* 1471 */ +/* 1478 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204417,7 +205110,7 @@ module.exports = { */ var GetValue = __webpack_require__(6); -var Clamp = __webpack_require__(17); +var Clamp = __webpack_require__(18); /** * Retrieves and clamps a numerical value from an object. @@ -204446,7 +205139,7 @@ module.exports = GetMinMaxValue; /***/ }), -/* 1472 */ +/* 1479 */ /***/ (function(module, exports) { /** @@ -204483,7 +205176,7 @@ module.exports = HasAll; /***/ }), -/* 1473 */ +/* 1480 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204526,7 +205219,7 @@ module.exports = MergeRight; /***/ }), -/* 1474 */ +/* 1481 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204541,18 +205234,18 @@ module.exports = MergeRight; module.exports = { - Format: __webpack_require__(1475), - Pad: __webpack_require__(182), - RemoveAt: __webpack_require__(1476), - Reverse: __webpack_require__(1477), - UppercaseFirst: __webpack_require__(200), - UUID: __webpack_require__(217) + Format: __webpack_require__(1482), + Pad: __webpack_require__(183), + RemoveAt: __webpack_require__(1483), + Reverse: __webpack_require__(1484), + UppercaseFirst: __webpack_require__(202), + UUID: __webpack_require__(219) }; /***/ }), -/* 1475 */ +/* 1482 */ /***/ (function(module, exports) { /** @@ -204587,7 +205280,7 @@ module.exports = Format; /***/ }), -/* 1476 */ +/* 1483 */ /***/ (function(module, exports) { /** @@ -204623,7 +205316,7 @@ module.exports = RemoveAt; /***/ }), -/* 1477 */ +/* 1484 */ /***/ (function(module, exports) { /** @@ -204652,7 +205345,7 @@ module.exports = Reverse; /***/ }), -/* 1478 */ +/* 1485 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -204668,27 +205361,27 @@ module.exports = Reverse; module.exports = { - SoundManagerCreator: __webpack_require__(404), + SoundManagerCreator: __webpack_require__(420), - Events: __webpack_require__(68), + Events: __webpack_require__(69), - BaseSound: __webpack_require__(144), - BaseSoundManager: __webpack_require__(143), + BaseSound: __webpack_require__(145), + BaseSoundManager: __webpack_require__(144), - WebAudioSound: __webpack_require__(412), - WebAudioSoundManager: __webpack_require__(410), + WebAudioSound: __webpack_require__(428), + WebAudioSoundManager: __webpack_require__(426), - HTML5AudioSound: __webpack_require__(407), - HTML5AudioSoundManager: __webpack_require__(405), + HTML5AudioSound: __webpack_require__(423), + HTML5AudioSoundManager: __webpack_require__(421), - NoAudioSound: __webpack_require__(409), - NoAudioSoundManager: __webpack_require__(408) + NoAudioSound: __webpack_require__(425), + NoAudioSoundManager: __webpack_require__(424) }; /***/ }), -/* 1479 */ +/* 1486 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -205094,7 +205787,7 @@ module.exports = BodyBounds; /***/ }), -/* 1480 */ +/* 1487 */ /***/ (function(module, exports) { /** @@ -205764,7 +206457,7 @@ function points_eq(a,b,precision){ /***/ }), -/* 1481 */ +/* 1488 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -205776,16 +206469,16 @@ function points_eq(a,b,precision){ var Bodies = __webpack_require__(126); var Class = __webpack_require__(0); var Composites = __webpack_require__(1388); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Svg = __webpack_require__(1389); -var MatterGameObject = __webpack_require__(1482); -var MatterImage = __webpack_require__(1483); -var MatterSprite = __webpack_require__(1484); +var MatterGameObject = __webpack_require__(1489); +var MatterImage = __webpack_require__(1490); +var MatterSprite = __webpack_require__(1491); var MatterTileBody = __webpack_require__(1390); var PhysicsEditorParser = __webpack_require__(1386); var PhysicsJSONParser = __webpack_require__(1387); -var PointerConstraint = __webpack_require__(1485); -var Vertices = __webpack_require__(93); +var PointerConstraint = __webpack_require__(1492); +var Vertices = __webpack_require__(94); /** * @classdesc @@ -206694,7 +207387,7 @@ module.exports = Factory; /***/ }), -/* 1482 */ +/* 1489 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -206703,7 +207396,7 @@ module.exports = Factory; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Components = __webpack_require__(518); +var Components = __webpack_require__(534); var GetFastValue = __webpack_require__(2); var Vector2 = __webpack_require__(3); @@ -206820,7 +207513,7 @@ module.exports = MatterGameObject; /***/ }), -/* 1483 */ +/* 1490 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -206830,11 +207523,11 @@ module.exports = MatterGameObject; */ var Class = __webpack_require__(0); -var Components = __webpack_require__(518); +var Components = __webpack_require__(534); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); var Image = __webpack_require__(124); -var Pipeline = __webpack_require__(170); +var Pipeline = __webpack_require__(171); var Vector2 = __webpack_require__(3); /** @@ -206966,7 +207659,7 @@ module.exports = MatterImage; /***/ }), -/* 1484 */ +/* 1491 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -206975,12 +207668,12 @@ module.exports = MatterImage; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(161); +var AnimationState = __webpack_require__(162); var Class = __webpack_require__(0); -var Components = __webpack_require__(518); +var Components = __webpack_require__(534); var GameObject = __webpack_require__(15); var GetFastValue = __webpack_require__(2); -var Pipeline = __webpack_require__(170); +var Pipeline = __webpack_require__(171); var Sprite = __webpack_require__(73); var Vector2 = __webpack_require__(3); @@ -207118,7 +207811,7 @@ module.exports = MatterSprite; /***/ }), -/* 1485 */ +/* 1492 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -207127,17 +207820,17 @@ module.exports = MatterSprite; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); var Class = __webpack_require__(0); var Composite = __webpack_require__(163); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Detector = __webpack_require__(587); var Events = __webpack_require__(586); var InputEvents = __webpack_require__(49); -var Merge = __webpack_require__(142); +var Merge = __webpack_require__(143); var Sleeping = __webpack_require__(267); var Vector2 = __webpack_require__(3); -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); /** * @classdesc @@ -207506,7 +208199,7 @@ module.exports = PointerConstraint; /***/ }), -/* 1486 */ +/* 1493 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -207598,7 +208291,7 @@ var Common = __webpack_require__(50); /***/ }), -/* 1487 */ +/* 1494 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -207613,11 +208306,11 @@ var Query = {}; module.exports = Query; -var Vector = __webpack_require__(114); +var Vector = __webpack_require__(116); var SAT = __webpack_require__(588); -var Bounds = __webpack_require__(115); +var Bounds = __webpack_require__(117); var Bodies = __webpack_require__(126); -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); (function() { @@ -207740,7 +208433,7 @@ var Vertices = __webpack_require__(93); /***/ }), -/* 1488 */ +/* 1495 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -207761,13 +208454,13 @@ var World = __webpack_require__(1393); var Sleeping = __webpack_require__(267); var Resolver = __webpack_require__(1396); var Pairs = __webpack_require__(1395); -var Metrics = __webpack_require__(1521); +var Metrics = __webpack_require__(1528); var Grid = __webpack_require__(1394); var Events = __webpack_require__(268); var Composite = __webpack_require__(163); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Common = __webpack_require__(50); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); (function() { @@ -208233,7 +208926,7 @@ var Body = __webpack_require__(70); /***/ }), -/* 1489 */ +/* 1496 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -208243,20 +208936,20 @@ var Body = __webpack_require__(70); */ var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var Class = __webpack_require__(0); var Common = __webpack_require__(50); var Composite = __webpack_require__(163); -var Engine = __webpack_require__(1488); +var Engine = __webpack_require__(1495); var EventEmitter = __webpack_require__(9); var Events = __webpack_require__(586); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); -var MatterBody = __webpack_require__(70); +var MatterBody = __webpack_require__(71); var MatterEvents = __webpack_require__(268); var MatterTileBody = __webpack_require__(1390); var MatterWorld = __webpack_require__(1393); -var Vector = __webpack_require__(114); +var Vector = __webpack_require__(116); /** * @classdesc @@ -210453,7 +211146,7 @@ module.exports = World; /***/ }), -/* 1490 */ +/* 1497 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {/** @@ -210465,7 +211158,7 @@ module.exports = World; __webpack_require__(590); var CONST = __webpack_require__(39); -var Extend = __webpack_require__(19); +var Extend = __webpack_require__(17); /** * @namespace Phaser @@ -210475,7 +211168,7 @@ var Phaser = { Actions: __webpack_require__(269), Animations: __webpack_require__(699), - BlendModes: __webpack_require__(38), + BlendModes: __webpack_require__(33), Cache: __webpack_require__(711), Cameras: __webpack_require__(714), Core: __webpack_require__(803), @@ -210488,23 +211181,23 @@ var Phaser = { Events: __webpack_require__(914), Game: __webpack_require__(916), GameObjects: __webpack_require__(1007), - Geom: __webpack_require__(461), + Geom: __webpack_require__(477), Input: __webpack_require__(1302), Loader: __webpack_require__(1332), - Math: __webpack_require__(189), - Physics: __webpack_require__(1491), + Math: __webpack_require__(190), + Physics: __webpack_require__(1498), Plugins: __webpack_require__(1397), - Renderer: __webpack_require__(1526), - Scale: __webpack_require__(1399), - ScaleModes: __webpack_require__(263), - Scene: __webpack_require__(396), - Scenes: __webpack_require__(1400), - Structs: __webpack_require__(1402), - Textures: __webpack_require__(1403), - Tilemaps: __webpack_require__(1405), - Time: __webpack_require__(1447), - Tweens: __webpack_require__(1449), - Utils: __webpack_require__(1467) + Renderer: __webpack_require__(1399), + Scale: __webpack_require__(1406), + ScaleModes: __webpack_require__(164), + Scene: __webpack_require__(412), + Scenes: __webpack_require__(1407), + Structs: __webpack_require__(1409), + Textures: __webpack_require__(1410), + Tilemaps: __webpack_require__(1412), + Time: __webpack_require__(1454), + Tweens: __webpack_require__(1456), + Utils: __webpack_require__(1474) }; @@ -210512,7 +211205,7 @@ var Phaser = { if (true) { - Phaser.Sound = __webpack_require__(1478); + Phaser.Sound = __webpack_require__(1485); } if (false) @@ -210547,7 +211240,7 @@ global.Phaser = Phaser; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(589))) /***/ }), -/* 1491 */ +/* 1498 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -210567,13 +211260,13 @@ global.Phaser = Phaser; module.exports = { Arcade: __webpack_require__(1360), - Matter: __webpack_require__(1492) + Matter: __webpack_require__(1499) }; /***/ }), -/* 1492 */ +/* 1499 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -210588,27 +211281,27 @@ module.exports = { module.exports = { - BodyBounds: __webpack_require__(1479), - Components: __webpack_require__(518), + BodyBounds: __webpack_require__(1486), + Components: __webpack_require__(534), Events: __webpack_require__(586), - Factory: __webpack_require__(1481), - MatterGameObject: __webpack_require__(1482), - Image: __webpack_require__(1483), + Factory: __webpack_require__(1488), + MatterGameObject: __webpack_require__(1489), + Image: __webpack_require__(1490), Matter: __webpack_require__(1391), - MatterPhysics: __webpack_require__(1522), - PolyDecomp: __webpack_require__(1480), - Sprite: __webpack_require__(1484), + MatterPhysics: __webpack_require__(1529), + PolyDecomp: __webpack_require__(1487), + Sprite: __webpack_require__(1491), TileBody: __webpack_require__(1390), PhysicsEditorParser: __webpack_require__(1386), PhysicsJSONParser: __webpack_require__(1387), - PointerConstraint: __webpack_require__(1485), - World: __webpack_require__(1489) + PointerConstraint: __webpack_require__(1492), + World: __webpack_require__(1496) }; /***/ }), -/* 1493 */ +/* 1500 */ /***/ (function(module, exports) { /** @@ -210648,7 +211341,7 @@ module.exports = Bounce; /***/ }), -/* 1494 */ +/* 1501 */ /***/ (function(module, exports) { /** @@ -210834,7 +211527,7 @@ module.exports = Collision; /***/ }), -/* 1495 */ +/* 1502 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -210843,7 +211536,7 @@ module.exports = Collision; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); /** * A component to apply force to Matter.js bodies. @@ -210990,7 +211683,7 @@ module.exports = Force; /***/ }), -/* 1496 */ +/* 1503 */ /***/ (function(module, exports) { /** @@ -211080,7 +211773,7 @@ module.exports = Friction; /***/ }), -/* 1497 */ +/* 1504 */ /***/ (function(module, exports) { /** @@ -211120,7 +211813,7 @@ module.exports = Gravity; /***/ }), -/* 1498 */ +/* 1505 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -211129,7 +211822,7 @@ module.exports = Gravity; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var Vector2 = __webpack_require__(3); /** @@ -211202,7 +211895,7 @@ module.exports = Mass; /***/ }), -/* 1499 */ +/* 1506 */ /***/ (function(module, exports) { /** @@ -211256,7 +211949,7 @@ module.exports = Sensor; /***/ }), -/* 1500 */ +/* 1507 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -211266,12 +211959,12 @@ module.exports = Sensor; */ var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); -var FuzzyEquals = __webpack_require__(121); +var Body = __webpack_require__(71); +var FuzzyEquals = __webpack_require__(123); var GetFastValue = __webpack_require__(2); var PhysicsEditorParser = __webpack_require__(1386); var PhysicsJSONParser = __webpack_require__(1387); -var Vertices = __webpack_require__(93); +var Vertices = __webpack_require__(94); /** * Enables a Matter-enabled Game Object to set its Body. Should be used as a mixin and not directly. @@ -211546,7 +212239,7 @@ module.exports = SetBody; /***/ }), -/* 1501 */ +/* 1508 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -211700,7 +212393,7 @@ module.exports = Sleep; /***/ }), -/* 1502 */ +/* 1509 */ /***/ (function(module, exports) { /** @@ -211734,7 +212427,7 @@ module.exports = 'afteradd'; /***/ }), -/* 1503 */ +/* 1510 */ /***/ (function(module, exports) { /** @@ -211768,7 +212461,7 @@ module.exports = 'afterremove'; /***/ }), -/* 1504 */ +/* 1511 */ /***/ (function(module, exports) { /** @@ -211801,7 +212494,7 @@ module.exports = 'afterupdate'; /***/ }), -/* 1505 */ +/* 1512 */ /***/ (function(module, exports) { /** @@ -211835,7 +212528,7 @@ module.exports = 'beforeadd'; /***/ }), -/* 1506 */ +/* 1513 */ /***/ (function(module, exports) { /** @@ -211869,7 +212562,7 @@ module.exports = 'beforeremove'; /***/ }), -/* 1507 */ +/* 1514 */ /***/ (function(module, exports) { /** @@ -211902,7 +212595,7 @@ module.exports = 'beforeupdate'; /***/ }), -/* 1508 */ +/* 1515 */ /***/ (function(module, exports) { /** @@ -211939,7 +212632,7 @@ module.exports = 'collisionactive'; /***/ }), -/* 1509 */ +/* 1516 */ /***/ (function(module, exports) { /** @@ -211976,7 +212669,7 @@ module.exports = 'collisionend'; /***/ }), -/* 1510 */ +/* 1517 */ /***/ (function(module, exports) { /** @@ -212013,7 +212706,7 @@ module.exports = 'collisionstart'; /***/ }), -/* 1511 */ +/* 1518 */ /***/ (function(module, exports) { /** @@ -212040,7 +212733,7 @@ module.exports = 'dragend'; /***/ }), -/* 1512 */ +/* 1519 */ /***/ (function(module, exports) { /** @@ -212067,7 +212760,7 @@ module.exports = 'drag'; /***/ }), -/* 1513 */ +/* 1520 */ /***/ (function(module, exports) { /** @@ -212095,7 +212788,7 @@ module.exports = 'dragstart'; /***/ }), -/* 1514 */ +/* 1521 */ /***/ (function(module, exports) { /** @@ -212118,7 +212811,7 @@ module.exports = 'pause'; /***/ }), -/* 1515 */ +/* 1522 */ /***/ (function(module, exports) { /** @@ -212141,7 +212834,7 @@ module.exports = 'resume'; /***/ }), -/* 1516 */ +/* 1523 */ /***/ (function(module, exports) { /** @@ -212174,7 +212867,7 @@ module.exports = 'sleepend'; /***/ }), -/* 1517 */ +/* 1524 */ /***/ (function(module, exports) { /** @@ -212207,7 +212900,7 @@ module.exports = 'sleepstart'; /***/ }), -/* 1518 */ +/* 1525 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -212216,7 +212909,7 @@ module.exports = 'sleepstart'; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); /** * Provides methods used for getting and setting the static state of a physics body. @@ -212262,7 +212955,7 @@ module.exports = Static; /***/ }), -/* 1519 */ +/* 1526 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -212271,10 +212964,10 @@ module.exports = Static; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); var MATH_CONST = __webpack_require__(14); -var WrapAngle = __webpack_require__(264); -var WrapAngleDegrees = __webpack_require__(265); +var WrapAngle = __webpack_require__(265); +var WrapAngleDegrees = __webpack_require__(266); // global bitmask flag for GameObject.renderMask (used by Scale) var _FLAG = 4; // 0100 @@ -212577,7 +213270,7 @@ module.exports = Transform; /***/ }), -/* 1520 */ +/* 1527 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -212586,7 +213279,7 @@ module.exports = Transform; * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(70); +var Body = __webpack_require__(71); /** * Contains methods for changing the velocity of a Matter Body. Should be used as a mixin and not called directly. @@ -212678,7 +213371,7 @@ module.exports = Velocity; /***/ }), -/* 1521 */ +/* 1528 */ /***/ (function(module, exports, __webpack_require__) { // @if DEBUG @@ -212777,7 +213470,7 @@ var Common = __webpack_require__(50); /***/ }), -/* 1522 */ +/* 1529 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -212786,39 +213479,39 @@ var Common = __webpack_require__(50); * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = __webpack_require__(120); +var ALIGN_CONST = __webpack_require__(122); var Axes = __webpack_require__(585); var Bodies = __webpack_require__(126); -var Body = __webpack_require__(70); -var BodyBounds = __webpack_require__(1479); -var Bounds = __webpack_require__(115); +var Body = __webpack_require__(71); +var BodyBounds = __webpack_require__(1486); +var Bounds = __webpack_require__(117); var Class = __webpack_require__(0); var Composite = __webpack_require__(163); var Composites = __webpack_require__(1388); -var Constraint = __webpack_require__(244); +var Constraint = __webpack_require__(246); var Detector = __webpack_require__(587); var DistanceBetween = __webpack_require__(48); -var Factory = __webpack_require__(1481); +var Factory = __webpack_require__(1488); var GetFastValue = __webpack_require__(2); var GetValue = __webpack_require__(6); var Grid = __webpack_require__(1394); -var MatterAttractors = __webpack_require__(1523); -var MatterCollisionEvents = __webpack_require__(1524); -var MatterLib = __webpack_require__(1486); -var MatterWrap = __webpack_require__(1525); -var Merge = __webpack_require__(142); -var Pair = __webpack_require__(519); +var MatterAttractors = __webpack_require__(1530); +var MatterCollisionEvents = __webpack_require__(1531); +var MatterLib = __webpack_require__(1493); +var MatterWrap = __webpack_require__(1532); +var Merge = __webpack_require__(143); +var Pair = __webpack_require__(535); var Pairs = __webpack_require__(1395); var Plugin = __webpack_require__(1392); var PluginCache = __webpack_require__(24); -var Query = __webpack_require__(1487); +var Query = __webpack_require__(1494); var Resolver = __webpack_require__(1396); var SAT = __webpack_require__(588); var SceneEvents = __webpack_require__(21); var Svg = __webpack_require__(1389); -var Vector = __webpack_require__(114); -var Vertices = __webpack_require__(93); -var World = __webpack_require__(1489); +var Vector = __webpack_require__(116); +var Vertices = __webpack_require__(94); +var World = __webpack_require__(1496); /** * @classdesc @@ -214246,7 +214939,7 @@ module.exports = MatterPhysics; /***/ }), -/* 1523 */ +/* 1530 */ /***/ (function(module, exports, __webpack_require__) { var Matter = __webpack_require__(1391); @@ -214405,7 +215098,7 @@ module.exports = MatterAttractors; /***/ }), -/* 1524 */ +/* 1531 */ /***/ (function(module, exports) { /** @@ -214538,7 +215231,7 @@ module.exports = MatterCollisionEvents; /***/ }), -/* 1525 */ +/* 1532 */ /***/ (function(module, exports, __webpack_require__) { var Matter = __webpack_require__(1391); @@ -214719,673 +215412,6 @@ module.exports = MatterWrap; * @memberof Matter.Composite */ -/***/ }), -/* 1526 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Renderer - */ - -/** - * @namespace Phaser.Types.Renderer - */ - -module.exports = { - - Canvas: __webpack_require__(1527), - Events: __webpack_require__(94), - Snapshot: __webpack_require__(1528), - WebGL: __webpack_require__(1529) - -}; - - -/***/ }), -/* 1527 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Renderer.Canvas - */ - -module.exports = { - - CanvasRenderer: __webpack_require__(569), - GetBlendModes: __webpack_require__(571), - SetTransform: __webpack_require__(30) - -}; - - -/***/ }), -/* 1528 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Renderer.Snapshot - */ - -module.exports = { - - Canvas: __webpack_require__(570), - WebGL: __webpack_require__(584) - -}; - - -/***/ }), -/* 1529 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var WEBGL_CONST = __webpack_require__(122); -var Extend = __webpack_require__(19); - -/** - * @namespace Phaser.Renderer.WebGL - */ - -var WebGL = { - - PipelineManager: __webpack_require__(573), - Pipelines: __webpack_require__(1530), - RenderTarget: __webpack_require__(162), - Utils: __webpack_require__(12), - WebGLPipeline: __webpack_require__(66), - WebGLRenderer: __webpack_require__(572), - WebGLShader: __webpack_require__(576) - -}; - -// Merge in the consts - -WebGL = Extend(false, WebGL, WEBGL_CONST); - -// Export it - -module.exports = WebGL; - - -/***/ }), -/* 1530 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = __webpack_require__(72); -var Extend = __webpack_require__(19); - -/** - * @namespace Phaser.Renderer.WebGL.Pipelines - */ - -var Pipelines = { - - BitmapMaskPipeline: __webpack_require__(574), - Events: __webpack_require__(575), - GraphicsPipeline: __webpack_require__(577), - LightPipeline: __webpack_require__(578), - MultiPipeline: __webpack_require__(123), - PointLightPipeline: __webpack_require__(579), - PostFXPipeline: __webpack_require__(1531), - RopePipeline: __webpack_require__(580), - SinglePipeline: __webpack_require__(581), - UtilityPipeline: __webpack_require__(582) - -}; - -// Merge in the consts - -Pipelines = Extend(false, Pipelines, CONST); - -// Export it - -module.exports = Pipelines; - - -/***/ }), -/* 1531 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); -var ColorMatrix = __webpack_require__(266); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(1532); -var ShaderSourceVS = __webpack_require__(583); -var WebGLPipeline = __webpack_require__(66); - -/** - * @classdesc - * The Post FX Pipeline is a special kind of pipeline specifically for handling post - * processing effects. Where-as a standard Pipeline allows you to control the process - * of rendering Game Objects by configuring the shaders and attributes used to draw them, - * a Post FX Pipeline is designed to allow you to apply processing _after_ the Game Object/s - * have been rendered. Typical examples of post processing effects are bloom filters, - * blurs, light effects and color manipulation. - * - * The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad - * in it. Game Objects can have a Post Pipeline set on them. Those objects are then rendered - * using their standard pipeline, but are redirected to the Render Targets owned by the - * post pipeline, which can then apply their own shaders and effects, before passing them - * back to the main renderer. - * - * Please see the Phaser 3 examples for further details on this extensive subject. - * - * The default fragment shader it uses can be found in `shaders/src/PostFX.frag`. - * The default vertex shader it uses can be found in `shaders/src/Quad.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) - * - * The vertices array layout is: - * - * -1, 1 B----C 1, 1 - * 0, 1 | /| 1, 1 - * | / | - * | / | - * |/ | - * -1, -1 A----D 1, -1 - * 0, 0 1, 0 - * - * A = -1, -1 (pos) and 0, 0 (uv) - * B = -1, 1 (pos) and 0, 1 (uv) - * C = 1, 1 (pos) and 1, 1 (uv) - * D = 1, -1 (pos) and 1, 0 (uv) - * - * First tri: A, B, C - * Second tri: A, C, D - * - * Array index: - * - * 0 = Tri 1 - Vert A - x pos - * 1 = Tri 1 - Vert A - y pos - * 2 = Tri 1 - Vert A - uv u - * 3 = Tri 1 - Vert A - uv v - * - * 4 = Tri 1 - Vert B - x pos - * 5 = Tri 1 - Vert B - y pos - * 6 = Tri 1 - Vert B - uv u - * 7 = Tri 1 - Vert B - uv v - * - * 8 = Tri 1 - Vert C - x pos - * 9 = Tri 1 - Vert C - y pos - * 10 = Tri 1 - Vert C - uv u - * 11 = Tri 1 - Vert C - uv v - * - * 12 = Tri 2 - Vert A - x pos - * 13 = Tri 2 - Vert A - y pos - * 14 = Tri 2 - Vert A - uv u - * 15 = Tri 2 - Vert A - uv v - * - * 16 = Tri 2 - Vert C - x pos - * 17 = Tri 2 - Vert C - y pos - * 18 = Tri 2 - Vert C - uv u - * 19 = Tri 2 - Vert C - uv v - * - * 20 = Tri 2 - Vert D - x pos - * 21 = Tri 2 - Vert D - y pos - * 22 = Tri 2 - Vert D - uv u - * 23 = Tri 2 - Vert D - uv v - * - * @class PostFXPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. - */ -var PostFXPipeline = new Class({ - - Extends: WebGLPipeline, - - initialize: - - function PostFXPipeline (config) - { - config.renderTarget = GetFastValue(config, 'renderTarget', 1); - config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS); - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inTexCoord', - size: 2 - } - ]); - config.batchSize = 1; - config.vertices = [ - -1, -1, 0, 0, - -1, 1, 0, 1, - 1, 1, 1, 1, - -1, -1, 0, 0, - 1, 1, 1, 1, - 1, -1, 1, 0 - ]; - - WebGLPipeline.call(this, config); - - this.isPostFX = true; - - /** - * If this post-pipeline belongs to a Game Object or Camera, this contains a reference to it. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.50.0 - */ - this.gameObject; - - /** - * A Color Matrix instance belonging to this pipeline. - * - * Used during calls to the `drawFrame` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#colorMatrix - * @type {Phaser.Display.ColorMatrix} - * @since 3.50.0 - */ - this.colorMatrix = new ColorMatrix(); - - /** - * A reference to the Full Frame 1 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. - * - * This Render Target is the full size of the renderer. - * - * You can use this directly in Post FX Pipelines for multi-target effects. - * However, be aware that these targets are shared between all post fx pipelines. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.fullFrame1; - - /** - * A reference to the Full Frame 2 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. - * - * This Render Target is the full size of the renderer. - * - * You can use this directly in Post FX Pipelines for multi-target effects. - * However, be aware that these targets are shared between all post fx pipelines. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.fullFrame2; - - /** - * A reference to the Half Frame 1 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. - * - * This Render Target is half the size of the renderer. - * - * You can use this directly in Post FX Pipelines for multi-target effects. - * However, be aware that these targets are shared between all post fx pipelines. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.halfFrame1; - - /** - * A reference to the Half Frame 2 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. - * - * This Render Target is half the size of the renderer. - * - * You can use this directly in Post FX Pipelines for multi-target effects. - * However, be aware that these targets are shared between all post fx pipelines. - * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.halfFrame2; - - if (this.renderer.isBooted) - { - this.manager = this.renderer.pipelines; - - this.boot(); - } - }, - - boot: function () - { - WebGLPipeline.prototype.boot.call(this); - - var utility = this.manager.UTILITY_PIPELINE; - - this.fullFrame1 = utility.fullFrame1; - this.fullFrame2 = utility.fullFrame2; - this.halfFrame1 = utility.halfFrame1; - this.halfFrame2 = utility.halfFrame2; - - this.set1i('uMainSampler', 0); - }, - - onDraw: function (renderTarget) - { - this.bindAndDraw(renderTarget); - }, - - /** - * Copy the `source` Render Target to the `target` Render Target. - * - * You can optionally set the brightness factor of the copy. - * - * The difference between this method and `drawFrame` is that this method - * uses a faster copy shader, where only the brightness can be modified. - * If you need color level manipulation, see `drawFrame` instead. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. - * @param {number} [brightness=1] - The brightness value applied to the frame copy. - * @param {boolean} [clear=true] - Clear the target before copying? - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - copyFrame: function (source, target, brightness, clear, clearAlpha) - { - this.manager.copyFrame(source, target, brightness, clear, clearAlpha); - }, - - /** - * Pops the framebuffer from the renderers FBO stack and sets that as the active target, - * then draws the `source` Render Target to it. It then resets the renderer textures. - * - * This should be done when you need to draw the _final_ results of a pipeline to the game - * canvas, or the next framebuffer in line on the FBO stack. You should only call this once - * in the `onDraw` handler and it should be the final thing called. Be careful not to call - * this if you need to actually use the pipeline shader, instead of the copy shader. In - * those cases, use the `bindAndDraw` method. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyToGame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. - */ - copyToGame: function (source) - { - this.manager.copyToGame(source); - }, - - /** - * Copy the `source` Render Target to the `target` Render Target, using the - * given Color Matrix. - * - * The difference between this method and `copyFrame` is that this method - * uses a color matrix shader, where you have full control over the luminance - * values used during the copy. If you don't need this, you can use the faster - * `copyFrame` method instead. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#drawFrame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - drawFrame: function (source, target, clearAlpha) - { - this.manager.drawFrame(source, target, clearAlpha, this.colorMatrix); - }, - - /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using a linear blend effect, which is controlled by the `strength` parameter. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFrames - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. - * @param {number} [strength=1] - The strength of the blend. - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - blendFrames: function (source1, source2, target, strength, clearAlpha) - { - this.manager.blendFrames(source1, source2, target, strength, clearAlpha); - }, - - /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using an additive blend effect, which is controlled by the `strength` parameter. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFramesAdditive - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target. - * @param {number} [strength=1] - The strength of the blend. - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) - { - this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha); - }, - - /** - * Clears the given Render Target. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#clearFrame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear. - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - clearFrame: function (target, clearAlpha) - { - this.manager.clearFrame(target, clearAlpha); - }, - - /** - * Copy the `source` Render Target to the `target` Render Target. - * - * The difference with this copy is that no resizing takes place. If the `source` - * Render Target is larger than the `target` then only a portion the same size as - * the `target` dimensions is copied across. - * - * You can optionally set the brightness factor of the copy. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blitFrame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. - * @param {number} [brightness=1] - The brightness value applied to the frame copy. - * @param {boolean} [clear=true] - Clear the target before copying? - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - * @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode? - */ - blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) - { - this.manager.blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); - }, - - /** - * Binds the `source` Render Target and then copies a section of it to the `target` Render Target. - * - * This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't - * require the use of any shaders. Remember the coordinates are given in standard WebGL format, - * where x and y specify the lower-left corner of the section, not the top-left. Also, the - * copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes - * place. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrameRect - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. - * @param {number} x - The x coordinate of the lower left corner where to start copying. - * @param {number} y - The y coordinate of the lower left corner where to start copying. - * @param {number} width - The width of the texture. - * @param {number} height - The height of the texture. - * @param {boolean} [clear=true] - Clear the target before copying? - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - */ - copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) - { - this.manager.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); - }, - - /** - * Binds this pipeline and draws the `source` Render Target to the `target` Render Target. - * - * If no `target` is specified, it will pop the framebuffer from the Renderers FBO stack - * and use that instead, which should be done when you need to draw the final results of - * this pipeline to the game canvas. - * - * You can optionally set the shader to be used for the draw here, if this is a multi-shader - * pipeline. By default `currentShader` will be used. If you need to set a shader but not - * a target, just pass `null` as the `target` parameter. - * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bindAndDraw - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to draw to. If not set, it will pop the fbo from the stack. - * @param {boolean} [clear=true] - Clear the target before copying? Only used if `target` parameter is set. - * @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target? - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to use during the draw. - */ - bindAndDraw: function (source, target, clear, clearAlpha, currentShader) - { - if (clear === undefined) { clear = true; } - if (clearAlpha === undefined) { clearAlpha = true; } - - var gl = this.gl; - var renderer = this.renderer; - - this.bind(currentShader); - - this.set1i('uMainSampler', 0); - - if (target) - { - gl.viewport(0, 0, target.width, target.height); - gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); - - if (clear) - { - if (clearAlpha) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(0, 0, 0, 1); - } - - gl.clear(gl.COLOR_BUFFER_BIT); - } - } - else - { - renderer.popFramebuffer(false, false, false); - - if (!renderer.currentFramebuffer) - { - gl.viewport(0, 0, renderer.width, renderer.height); - } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); - - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); - - if (!target) - { - renderer.resetTextures(); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - } - } - -}); - -module.exports = PostFXPipeline; - - -/***/ }), -/* 1532 */ -/***/ (function(module, exports) { - -module.exports = [ - '#define SHADER_NAME PHASER_POSTFX_FS', - '', - 'precision mediump float;', - '', - 'uniform sampler2D uMainSampler;', - '', - 'varying vec2 outTexCoord;', - '', - 'void main ()', - '{', - ' gl_FragColor = texture2D(uMainSampler, outTexCoord);', - '}', - '' -].join('\n'); - - /***/ }) /******/ ]); }); \ No newline at end of file diff --git a/dist/phaser.min.js b/dist/phaser.min.js index 404e4ce54..00726aaab 100644 --- a/dist/phaser.min.js +++ b/dist/phaser.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("Phaser",[],e):"object"==typeof exports?exports.Phaser=e():t.Phaser=e()}(window,function(){return n={},s.m=i=[function(t,e){function r(t,e,i,n){for(var s in e)if(e.hasOwnProperty(s)){var r=(l=e,u=s,f=d=void 0,f=(c=i)?l[u]:Object.getOwnPropertyDescriptor(l,u),!c&&f.value&&"object"==typeof f.value&&(f=f.value),!(!f||!((d=f).get&&"function"==typeof d.get||d.set&&"function"==typeof d.set))&&(void 0===f.enumerable&&(f.enumerable=!0),void 0===f.configurable&&(f.configurable=!0),f));if(!1!==r){if(o=(n||t).prototype,a=s,h=void 0,(h=Object.getOwnPropertyDescriptor(o,a))&&(h.value&&"object"==typeof h.value&&(h=h.value),!1===h.configurable)){if(p.ignoreFinals)continue;throw new Error("cannot override final property '"+s+"', set Class.ignoreFinals = true to skip")}Object.defineProperty(t.prototype,s,r)}else t.prototype[s]=e[s]}var o,a,h,l,u,c,d,f}function o(t,e){if(e){Array.isArray(e)||(e=[e]);for(var i=0;i=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=u},function(t,e,i){t.exports={Alpha:i(605),AlphaSingle:i(297),BlendMode:i(298),ComputedSize:i(606),Crop:i(607),Depth:i(299),Flip:i(608),GetBounds:i(609),Mask:i(303),Origin:i(630),PathFollower:i(631),Pipeline:i(170),ScrollFactor:i(306),Size:i(632),Texture:i(633),TextureCrop:i(634),Tint:i(635),ToJSON:i(172),Transform:i(307),TransformMatrix:i(25),Visible:i(308)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var l=[],u=e;uthis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=l},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e){t.exports=function(t,e,i,n){var s=i||e.strokeColor,r=n||e.strokeAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(20),l=i(23),s=i(8),u=i(2),c=i(6),d=i(7),r=new n({Extends:l,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=u(r=e,"key"),i=u(r,"url"),n=u(r,"xhrSettings"),o=u(r,"extension",o),s=u(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};l.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(36),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,l,u,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=l,v[10]=u,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,b=n*h-s*a,E=l*p-u*f,S=l*g-c*f,A=l*v-d*f,_=u*g-c*p,C=u*v-d*p,M=c*v-d*g,P=m*M-y*C+x*_+T*A-w*S+b*E;return P?(P=1/P,this.setValues((o*M-a*C+h*_)*P,(n*C-i*M-s*_)*P,(p*b-g*w+v*T)*P,(c*w-u*b-d*T)*P,(a*A-r*M-h*S)*P,(e*M-n*A+s*S)*P,(g*x-f*b-v*y)*P,(l*b-c*x+d*y)*P,(r*C-o*A+h*E)*P,(i*A-e*C-s*E)*P,(f*w-p*x+v*m)*P,(u*x-l*w-d*m)*P,(o*S-r*_-a*E)*P,(e*_-i*S+n*E)*P,(p*y-f*T-g*m)*P,(l*T-u*y+c*m)*P)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-u*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-u*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+u*(n*h-s*a)),-(r*(c*v-d*g)-l*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-l*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+l*(n*h-s*a),r*(u*v-d*p)-l*(o*v-h*p)+f*(o*d-h*u),-(e*(u*v-d*p)-l*(i*v-s*p)+f*(i*d-s*u)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*u)-r*(i*d-s*u)+l*(i*h-s*o)),-(r*(u*g-c*p)-l*(o*g-a*p)+f*(o*c-a*u)),e*(u*g-c*p)-l*(i*g-n*p)+f*(i*c-n*u),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*u)-r*(i*c-n*u)+l*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(u*v-d*p)+(e*h-s*r)*(u*g-c*p)+(i*a-n*o)*(l*v-d*f)-(i*h-s*o)*(l*g-c*f)+(n*h-s*a)*(l*p-u*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],l=e[7],u=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],b=y[3];return e[0]=x*i+T*o+w*u+b*p,e[1]=x*n+T*a+w*c+b*g,e[2]=x*s+T*h+w*d+b*v,e[3]=x*r+T*l+w*f+b*m,x=y[4],T=y[5],w=y[6],b=y[7],e[4]=x*i+T*o+w*u+b*p,e[5]=x*n+T*a+w*c+b*g,e[6]=x*s+T*h+w*d+b*v,e[7]=x*r+T*l+w*f+b*m,x=y[8],T=y[9],w=y[10],b=y[11],e[8]=x*i+T*o+w*u+b*p,e[9]=x*n+T*a+w*c+b*g,e[10]=x*s+T*h+w*d+b*v,e[11]=x*r+T*l+w*f+b*m,x=y[12],T=y[13],w=y[14],b=y[15],e[12]=x*i+T*o+w*u+b*p,e[13]=x*n+T*a+w*c+b*g,e[14]=x*s+T*h+w*d+b*v,e[15]=x*r+T*l+w*f+b*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],l=i[5],u=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],b=n[8],E=n[12],S=n[1],A=n[5],_=n[9],C=n[13],M=n[2],P=n[6],R=n[10],O=n[14],L=n[3],D=n[7],F=n[11],k=n[15];return this.setValues(s*T+r*S+o*M+a*L,h*T+l*S+u*M+c*L,d*T+f*S+p*M+g*L,v*T+m*S+y*M+x*L,s*w+r*A+o*P+a*D,h*w+l*A+u*P+c*D,d*w+f*A+p*P+g*D,v*w+m*A+y*P+x*D,s*b+r*_+o*R+a*F,h*b+l*_+u*R+c*F,d*b+f*_+p*R+g*F,v*b+m*_+y*R+x*F,s*E+r*C+o*O+a*k,h*E+l*C+u*O+c*k,d*E+f*C+p*O+g*k,v*E+m*C+y*O+x*k)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,l=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,l*o+i,l*a-n*r,0,h*a-n*o,l*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),l=1-h,u=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],b=i[12],E=i[13],S=i[14],A=i[15],_=n*n*l+h,C=s*n*l+r*a,M=r*n*l-s*a,P=n*s*l-r*a,R=s*s*l+h,O=r*s*l+n*a,L=n*r*l+s*a,D=s*r*l-n*a,F=r*r*l+h;return this.setValues(u*_+p*C+y*M,c*_+g*C+x*M,d*_+v*C+T*M,f*_+m*C+w*M,u*P+p*R+y*O,c*P+g*R+x*O,d*P+v*R+T*O,f*P+m*R+w*O,u*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,b,E,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],l=e[9],u=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+l*i,e[6]=o*n+u*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=l*n-r*i,e[10]=u*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],l=e[9],u=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-l*i,e[2]=o*n-u*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+l*n,e[10]=o*i+u*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],l=e[5],u=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+l*i,e[2]=o*n+u*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=l*n-r*i,e[6]=u*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,l=i*o,u=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),u+m,c-v,0,u-m,1-(l+p),f+g,0,c+v,f-g,1-(l+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,l=e*o,u=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),l+v,u-g,0,l-v,1-(h+f),d+p,0,u+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return u.subVectors(t,e),0===u.getLengthSquared()&&(u.z=1),u.normalize(),o.crossVectors(i,u),0===o.getLengthSquared()&&(1===Math.abs(i.z)?u.x+=1e-4:u.z+=1e-4,u.normalize(),o.crossVectors(i,u)),o.normalize(),a.crossVectors(u,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=u.x,n[9]=u.y,n[10]=u.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,l=e.x,u=e.y,c=e.z;if(Math.abs(n-l)<1e-6&&Math.abs(s-u)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-l,f=s-u,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),l.zero();var n=this.val,s=h.val,r=l.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(l),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),l.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(l),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],l=i[5],u=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],b=n[2],E=n[3],S=n[4],A=n[5],_=n[6],C=n[7],M=n[8],P=n[9],R=n[10],O=n[11],L=n[12],D=n[13],F=n[14],k=n[15];return e.setValues(T*s+w*h+b*d+E*v,w*r+w*l+b*f+E*m,b*o+w*u+b*p+E*y,E*a+w*c+b*g+E*x,S*s+A*h+_*d+C*v,S*r+A*l+_*f+C*m,S*o+A*u+_*p+C*y,S*a+A*c+_*g+C*x,M*s+P*h+R*d+O*v,M*r+P*l+R*f+O*m,M*o+P*u+R*p+O*y,M*a+P*c+R*g+O*x,L*s+D*h+F*d+k*v,L*r+D*l+F*f+k*m,L*o+D*u+F*p+k*y,L*a+D*c+F*g+k*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),l=Math.cos(t.y),u=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*l,m=a*l;return i||(u=l*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(l,p,g,0,0,a,o,0,h,v,m,0,u,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,l=new r,o=new s,a=new s,u=new s;t.exports=r},function(t,e,i){var n=i(0),y=i(171),s=i(9),v=i(575),x=i(2),m=i(65),T=i(94),w=i(162),b=i(12),E=i(576),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=u[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=u.length-1;0<=d;d--)u[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=u&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==l;);return i}(t,e))&&(i=E(e,t),v(e,e.next),v(i,i.next))}}(l[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,u=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(l,u,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,l=h.next;else if((t=h)===l){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!u(s,r)&&c(s,n,n.next,r)&&b(s,r)&&b(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(b(t,e)&&b(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||u(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function l(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=u},function(t,e,i){var n=i(29),s=i(0),r=i(11),o=i(480),a=new s({Mixins:[r.Alpha,r.Flip,r.Visible],initialize:function(t,e,i,n,s,r,o,a){this.layer=t,this.index=e,this.x=i,this.y=n,this.width=s,this.height=r,this.right,this.bottom,this.baseWidth=void 0!==o?o:s,this.baseHeight=void 0!==a?a:r,this.pixelX=0,this.pixelY=0,this.updatePixelXY(),this.properties={},this.rotation=0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceLeft=!1,this.faceRight=!1,this.faceTop=!1,this.faceBottom=!1,this.collisionCallback=void 0,(this.collisionCallbackContext=this).tint=16777215,this.physics={}},containsPoint:function(t,e){return!(tthis.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){var h=i(74);t.exports=function(t,e,i,n){if(void 0===n&&(n=t),!Array.isArray(e))return-1!==(o=t.indexOf(e))?(h(t,o),i&&i.call(n,e),e):null;for(var s=e.length-1,r=[];0<=s;){var o,a=e[s];-1!==(o=t.indexOf(a))&&(h(t,o),r.push(a),i&&i.call(n,a)),s--}return r}},function(t,e,i){var n=i(0),s=i(194),r=i(10),o=i(3),a=new n({initialize:function(t){this.type=t,this.defaultDivisions=5,this.arcLengthDivisions=100,this.cacheArcLengths=[],this.needsUpdate=!0,this.active=!0,this._tmpVec2A=new o,this._tmpVec2B=new o},draw:function(t,e){return void 0===e&&(e=32),t.strokePoints(this.getPoints(e))},getBounds:function(t,e){t=t||new r,void 0===e&&(e=16);var i=this.getLength();ih||a.y>l)?(u=Math.max(a.x,e),c=Math.max(a.y,i),b=d=Math.min(a.r,h)-u,E=f=Math.min(a.b,l)-c,T=r?p+(v-(u-a.x)-d):p+(u-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=u,i=c,n=d,s=f):E=b=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+b)/A),t.v1=Math.min(1,(w+E)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=b,t.ch=E,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(203),n=i(0),r=i(1),o=i(79),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),u=i(36),s=new n({Extends:u,initialize:function(t,e,i,n,s,r,o,a,h,l){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l=0),u.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=l,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],l=s*a[1]+r*a[5]+o*a[9]+a[13],u=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-l/c*i,this.vz=n<=0?u/c:-u/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,l=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),l=Math.round(l)),this.tx=h,this.ty=l,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},function(t,e){var i={};(t.exports=i).create=function(t,e){return{x:t||0,y:e||0}},i.clone=function(t){return{x:t.x,y:t.y}},i.magnitude=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},i.rotate=function(t,e,i){var n=Math.cos(e),s=Math.sin(e);i=i||{};var r=t.x*n-t.y*s;return i.y=t.x*s+t.y*n,i.x=r,i},i.rotateAbout=function(t,e,i,n){var s=Math.cos(e),r=Math.sin(e);n=n||{};var o=i.x+((t.x-i.x)*s-(t.y-i.y)*r);return n.y=i.y+((t.x-i.x)*r+(t.y-i.y)*s),n.x=o,n},i.normalise=function(t){var e=i.magnitude(t);return 0===e?{x:0,y:0}:{x:t.x/e,y:t.y/e}},i.dot=function(t,e){return t.x*e.x+t.y*e.y},i.cross=function(t,e){return t.x*e.y-t.y*e.x},i.cross3=function(t,e,i){return(e.x-t.x)*(i.y-t.y)-(e.y-t.y)*(i.x-t.x)},i.add=function(t,e,i){return(i=i||{}).x=t.x+e.x,i.y=t.y+e.y,i},i.sub=function(t,e,i){return(i=i||{}).x=t.x-e.x,i.y=t.y-e.y,i},i.mult=function(t,e){return{x:t.x*e,y:t.y*e}},i.div=function(t,e){return{x:t.x/e,y:t.y/e}},i.perp=function(t,e){return{x:(e=!0===e?-1:1)*-t.y,y:e*t.x}},i.neg=function(t){return{x:-t.x,y:-t.y}},i.angle=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},i._temp=[i.create(),i.create(),i.create(),i.create(),i.create(),i.create()]},function(t,e){var i={};(t.exports=i).create=function(t){var e={min:{x:0,y:0},max:{x:0,y:0}};return t&&i.update(e,t),e},i.update=function(t,e,i){t.min.x=1/0,t.max.x=-1/0,t.min.y=1/0,t.max.y=-1/0;for(var n=0;nt.max.x&&(t.max.x=s.x),s.xt.max.y&&(t.max.y=s.y),s.y=t.min.x&&e.x<=t.max.x&&e.y>=t.min.y&&e.y<=t.max.y},i.overlaps=function(t,e){return t.min.x<=e.max.x&&t.max.x>=e.min.x&&t.max.y>=e.min.y&&t.min.y<=e.max.y},i.translate=function(t,e){t.min.x+=e.x,t.max.x+=e.x,t.min.y+=e.y,t.max.y+=e.y},i.shift=function(t,e){var i=t.max.x-t.min.x,n=t.max.y-t.min.y;t.min.x=e.x,t.max.x=e.x+i,t.min.y=e.y,t.max.y=e.y+n}},function(t,e){t.exports=function(t,e,i){return 0<=t&&t=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},function(t,e,i){var n=i(0),s=i(94),r=new n({initialize:function(t,e,i,n,s,r,o){void 0===n&&(n=1),void 0===s&&(s=0),void 0===r&&(r=!0),void 0===o&&(o=!1),this.renderer=t,this.framebuffer=null,this.texture=null,this.width=0,this.height=0,this.scale=n,this.minFilter=s,this.autoClear=r,this.autoResize=!1,this.resize(e,i),o&&this.setAutoResize(!0)},setAutoResize:function(t){return t&&!this.autoResize?(this.renderer.on(s.RESIZE,this.resize,this),this.autoResize=!0):!t&&this.autoResize&&(this.renderer.off(s.RESIZE,this.resize,this),this.autoResize=!1),this},resize:function(t,e){var i,n=t*this.scale,s=e*this.scale;return n===this.width&&s===this.height||((i=this.renderer).deleteFramebuffer(this.framebuffer),i.deleteTexture(this.texture),t*=this.scale,e*=this.scale,this.texture=i.createTextureFromSource(null,t,e,this.minFilter),this.framebuffer=i.createFramebuffer(t,e,this.texture,!1),this.width=t,this.height=e),this},bind:function(t,e,i){var n;void 0===t&&(t=!1),t&&this.renderer.flush(),e&&i&&this.resize(e,i),this.renderer.pushFramebuffer(this.framebuffer,!1,!1,!1),t&&this.adjustViewport(),this.autoClear&&((n=this.renderer.gl).clearColor(0,0,0,0),n.clear(n.COLOR_BUFFER_BIT))},adjustViewport:function(){var t=this.renderer.gl;t.viewport(0,0,this.width,this.height),t.disable(t.SCISSOR_TEST)},clear:function(){var t=this.renderer,e=t.gl;t.pushFramebuffer(this.framebuffer),e.disable(e.SCISSOR_TEST),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT),t.popFramebuffer(),t.resetScissor()},unbind:function(t){void 0===t&&(t=!1);var e=this.renderer;return t&&e.flush(),e.popFramebuffer()},destroy:function(){var t=this.renderer;t.deleteFramebuffer(this.framebuffer),t.deleteTexture(this.texture),t.off(s.RESIZE,this.resize,this),this.renderer=null,this.framebuffer=null,this.texture=null}});t.exports=r},function(t,e,i){var c={};t.exports=c;var o=i(268),r=i(50),a=i(115),d=i(70);c.create=function(t){return r.extend({id:r.nextId(),type:"composite",parent:null,isModified:!1,bodies:[],constraints:[],composites:[],label:"Composite",plugin:{}},t)},c.setModified=function(t,e,i,n){if(o.trigger(t,"compositeModified",t),t.isModified=e,i&&t.parent&&c.setModified(t.parent,e,i,n),n)for(var s=0;s=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(321),s=i(185),r=i(325),o=i(326);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(100);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(35),s=i(324);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(102),r=i(134),o=i(31),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var l,u,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(l=this.pipeline).manager.set(l),u=y.width,c=y.height,d=h.width/u,f=h.height/c,l.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},function(t,e,i){var w={};t.exports=w;var o=i(93),b=i(114),a=i(267),h=i(115),l=i(585),u=i(50);w._warming=.4,w._torqueDampen=1,w._minLength=1e-6,w.create=function(t){var e=t;e.bodyA&&!e.pointA&&(e.pointA={x:0,y:0}),e.bodyB&&!e.pointB&&(e.pointB={x:0,y:0});var i=e.bodyA?b.add(e.bodyA.position,e.pointA):e.pointA,n=e.bodyB?b.add(e.bodyB.position,e.pointB):e.pointB,s=b.magnitude(b.sub(i,n));e.length=void 0!==e.length?e.length:s,e.id=e.id||u.nextId(),e.label=e.label||"Constraint",e.type="constraint",e.stiffness=e.stiffness||(0t&&(t=s.totalDuration),s.delay=o.sleepThreshold&&u.set(o,!0)):0u._motionWakeThreshold*i&&u.set(a,!1)))}},u.set=function(t,e){var i=t.isSleeping;e?(t.isSleeping=!0,t.sleepCounter=t.sleepThreshold,t.positionImpulse.x=0,t.positionImpulse.y=0,t.positionPrev.x=t.position.x,t.positionPrev.y=t.position.y,t.anglePrev=t.angle,t.speed=0,t.angularSpeed=0,t.motion=0,i||n.trigger(t,"sleepStart")):(t.isSleeping=!1,t.sleepCounter=0,i&&n.trigger(t,"sleepEnd"))}},function(t,e,i){var n={};t.exports=n;var u=i(50);n.on=function(t,e,i){for(var n,s=e.split(" "),r=0;r=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),l=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(181),s=i(0),r=i(99),o=i(9),a=i(130),h=i(22),T=i(2),d=i(6),f=i(182),p=i(316),l=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1l.right&&(u=E(u,u+(d-l.right),this.lerp.x)),fl.bottom&&(c=E(c,c+(f-l.bottom),this.lerp.y))):(u=E(u,d-o,this.lerp.x),c=E(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(u=this.clampX(u),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),u=Math.round(u),c=Math.round(c));var g=(this.scrollX=u)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(b.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=u(i,0,1),n=u(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,l=t.y-r;return this.midPoint.set(h,l),this.scrollX=h-o,this.scrollY=l-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=l},function(t,e,i){var o=i(35);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,l=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(35);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(35);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(737),Flash:i(738),Pan:i(739),Shake:i(772),RotateTo:i(773),Zoom:i(774)}},function(t,e,i){t.exports={In:i(740),Out:i(741),InOut:i(742)}},function(t,e,i){t.exports={In:i(743),Out:i(744),InOut:i(745)}},function(t,e,i){t.exports={In:i(746),Out:i(747),InOut:i(748)}},function(t,e,i){t.exports={In:i(749),Out:i(750),InOut:i(751)}},function(t,e,i){t.exports={In:i(752),Out:i(753),InOut:i(754)}},function(t,e,i){t.exports={In:i(755),Out:i(756),InOut:i(757)}},function(t,e,i){t.exports=i(758)},function(t,e,i){t.exports={In:i(759),Out:i(760),InOut:i(761)}},function(t,e,i){t.exports={In:i(762),Out:i(763),InOut:i(764)}},function(t,e,i){t.exports={In:i(765),Out:i(766),InOut:i(767)}},function(t,e,i){t.exports={In:i(768),Out:i(769),InOut:i(770)}},function(t,e,i){t.exports=i(771)},function(t,e,i){var n=i(0),h=i(39),l=i(341),u=i(2),c=i(6),d=i(7),f=i(189),p=i(1),g=i(193),v=i(183),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",l.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=l.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=u(r,"global",[]),this.installScenePlugins=u(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(102),browser:i(134),features:i(187),input:i(805),audio:i(806),video:i(807),fullscreen:i(808),canvasFeatures:i(342)}},function(t,e,i){var n,s,r,o=i(31),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(361),l=a(31),u=a(39),c=a(187);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===u.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==u.HEADLESS)if(e.renderType===u.CANVAS||e.renderType!==u.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=u.CANVAS}else e.renderType=u.WEBGL;e.antialias||l.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=l.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==u.HEADLESS&&(i=a(569),n=a(572),e.renderType===u.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var l=i(39);t.exports=function(t){var e,i,n,s,r,o,a,h=t.config;h.hideBanner||(e="WebGL",h.renderType===l.CANVAS?e="Canvas":h.renderType===l.HEADLESS&&(e="Headless"),i=h.audio,a=(n=t.device.audio).webAudio&&!i.disableWebAudio?"Web Audio":i.noAudio||!n.webAudio&&!n.audioData?"No Audio":"HTML5 Audio",t.device.browser.ie?window.console&&console.log("Phaser v"+l.VERSION+" / https://phaser.io"):(r=[s=""],Array.isArray(h.bannerBackgroundColor)?(h.bannerBackgroundColor.forEach(function(t){s=s.concat("%c "),r.push("background: "+t),o=t}),r[r.length-1]="color: "+h.bannerTextColor+"; background: "+o):(s=s.concat("%c "),r.push("color: "+h.bannerTextColor+"; background: "+h.bannerBackgroundColor)),r.push("background: #fff"),h.gameTitle&&(s=s.concat(h.gameTitle),h.gameVersion&&(s=s.concat(" v"+h.gameVersion)),h.hidePhaser||(s=s.concat(" / "))),h.hidePhaser||(s=s.concat("Phaser v"+l.VERSION+" ("+e+" | "+a+")")),s=s.concat(" %c "+h.gameURL),r[0]=s,console.log.apply(console,r)))}},function(t,e,i){var n=i(0),s=i(6),r=i(1),o=i(364),a=new n({initialize:function(t,e){this.game=t,this.raf=new o,this.started=!1,this.running=!1,this.minFps=s(e,"min",5),this.targetFps=s(e,"target",60),this._min=1e3/this.minFps,this._target=1e3/this.targetFps,this.actualFps=this.targetFps,this.nextFpsUpdate=0,this.framesThisSecond=0,this.callback=r,this.forceSetTimeOut=s(e,"forceSetTimeOut",!1),this.time=0,this.startTime=0,this.lastTime=0,this.frame=0,this.inFocus=!0,this._pauseTime=0,this._coolDown=0,this.delta=0,this.deltaIndex=0,this.deltaHistory=[],this.deltaSmoothingMax=s(e,"deltaHistory",10),this.panicMax=s(e,"panicMax",120),this.rawDelta=0,this.now=0,this.smoothStep=s(e,"smoothStep",!0)},blur:function(){this.inFocus=!1},focus:function(){this.inFocus=!0,this.resetDelta()},pause:function(){this._pauseTime=window.performance.now()},resume:function(){this.resetDelta(),this.startTime+=this.time-this._pauseTime},resetDelta:function(){var t=window.performance.now();this.time=t,this.lastTime=t,this.nextFpsUpdate=t+1e3;for(var e=this.framesThisSecond=0;ethis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(22);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(367),y=i(31),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),l=x(t,"postRender",null),u=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,u,c),a=o=!1),o&&(i.width=u,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,u,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],l=i[s>i.length-3?i.length-1:s+2];return e.set(u(r,o.x,a.x,h.x,l.x),u(r,o.y,a.y,h.y,l.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===u.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===u.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(17),s=i(0),r=i(76),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,l[a++]=(15&i)<<4|n>>2,l[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(144),s=i(0),r=i(68),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=t.context.createStereoPanner(),this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+l+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],u=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+u+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(135),r=i(80),o=i(2),a=i(64),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=u(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1094),r=i(67),o=i(10),a=i(32),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(u(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&l(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(55),s=i(19)(!1,s={Circle:i(1185),Ellipse:i(1195),Intersects:i(462),Line:i(1215),Mesh:i(1237),Point:i(1240),Polygon:i(1254),Rectangle:i(480),Triangle:i(1287)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(226),CircleToRectangle:i(149),GetCircleToCircle:i(1205),GetCircleToRectangle:i(1206),GetLineToCircle:i(227),GetLineToLine:i(463),GetLineToPoints:i(464),GetLineToPolygon:i(465),GetLineToRectangle:i(229),GetRaysFromPointToPolygon:i(1207),GetRectangleIntersection:i(1208),GetRectangleToRectangle:i(1209),GetRectangleToTriangle:i(1210),GetTriangleToCircle:i(1211),GetTriangleToLine:i(470),GetTriangleToTriangle:i(1212),LineToCircle:i(228),LineToLine:i(91),LineToRectangle:i(466),PointToLine:i(474),PointToLineSegment:i(1213),RectangleToRectangle:i(112),RectangleToTriangle:i(467),RectangleToValues:i(1214),TriangleToCircle:i(469),TriangleToLine:i(471),TriangleToTriangle:i(472)}},function(t,e,i){var g=i(36);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,l=r-n,u=o-s,c=e.x2-a,d=e.y2-h;if(0==l||0==d*l-c*u)return!1;var f=(l*(h-s)+u*(n-a))/(c*u-d*l),p=(a+c*f-n)/l;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(487),h=i(488),n=i(0),l=i(9),u=i(3),s=new n({Extends:l,initialize:function(t,e){l.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xu))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=M(t,e,s,this.OVERLAP_BIAS),p=P(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,u+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,l,u,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,l=t.body,u={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!l(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,l,u,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),l=n,u=s,p=f=d=c=void 0,c=Math.max(l.minX,u.minX),d=Math.max(l.minY,u.minY),f=Math.min(l.maxX,u.maxX),p=Math.min(l.maxY,u.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0n.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=l(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(254),p=i(552),g=i(158);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],l=0;l=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(119),b=i(556),E=i(254);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=l(e,i),o.tilesets=u(e),o}},function(t,e,i){var d=i(117),f=i(83);t.exports=function(t,e){for(var i=[],n=0;ne.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(l.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(31),C=i(35),M=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=M(e,"callback"),s=M(e,"type","image/png"),r=M(e,"encoder",.92),o=M(e,"x",0),a=M(e,"y",0),h=M(e,"getPixel",!1),l=M(e,"isFramebuffer",!1),u=l?M(e,"bufferWidth",1):i.drawingBufferWidth,c=l?M(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=l?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=M(e,"width",u),g=M(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;w>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(320),BaseCamera:i(131),CameraManager:i(775),Effects:i(327),Events:i(34)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(17),s=i(0),l=i(34),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?l.FADE_OUT_START:l.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(u=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:uMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(345);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(14);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(366),Palettes:i(885)}},function(t,e,i){t.exports={ARNE16:i(367),C64:i(886),CGA:i(887),JMP:i(888),MSX:i(889)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(891),MoveTo:i(371),CubicBezier:i(368),Curve:i(89),Ellipse:i(369),Line:i(370),QuadraticBezier:i(372),Spline:i(373)}},function(t,e,i){var n=i(0),u=i(368),l=i(369),s=i(5),r=i(370),o=i(371),a=i(372),h=i(10),c=i(373),d=i(3),f=i(14),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),l=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new u(h,o,a,l))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(35),l=i(377);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=l(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=l(s,n,t),a=l(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(184);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:l(t,n,h),g:l(e,s,h),b:l(i,r,h)}}var l=i(133);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(191),s=i(35);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(376);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(304),GeometryMask:i(305)}},function(t,e,i){var n={AddToDOM:i(139),DOMContentLoaded:i(378),GetInnerHeight:i(379),GetScreenOrientation:i(380),GetTarget:i(385),ParseXML:i(386),RemoveFromDOM:i(197),RequestAnimationFrame:i(364)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(915)}},function(t,e,i){var n=i(0),s=i(9),r=i(24),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(139),s=i(315),r=i(319),o=i(31),a=i(0),h=i(340),l=i(917),u=i(360),c=i(98),d=i(362),f=i(341),p=i(378),g=i(9),v=i(22),m=i(387),y=i(24),x=i(392),T=i(393),w=i(395),b=i(103),E=i(400),S=i(363),A=i(365),_=i(404),C=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new E(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),u(this),l(this),d(this),n(this.canvas,this.config.parent),this.textures.once(b.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=C},function(t,e,i){var n=i(139);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){t.exports={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"}},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var l=i(78);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),l(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var P=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=P(e,"chars","");if(""!==o){var a=P(e,"image",""),h=t.sys.textures.getFrame(a),l=h.cutX,u=h.cutY,c=h.source.width,d=h.source.height,f=P(e,"offset.x",0),p=P(e,"offset.y",0),g=P(e,"spacing.x",0),v=P(e,"spacing.y",0),m=P(e,"lineSpacing",0),y=P(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},b=0,E=0;E=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(186);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(112);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(33);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){l.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){l.revokeObjectURL(s.data),s.onProcessError()},l.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;r=n[2];if("^"===i.operator)return 0=i.number:0=n[2]:r[2]===n[2]}return t===e||"*"===t}},function(t,e,i){var n={};t.exports=n;var s=i(163),r=(i(244),i(50));n.create=function(t){var e=s.create(),i={label:"World",gravity:{x:0,y:1,scale:.001},bounds:{min:{x:-1/0,y:-1/0},max:{x:1/0,y:1/0}}};return r.extend(e,i,t)}},function(t,e,i){var y={};t.exports=y;var a=i(519),n=i(587),r=i(50);y.create=function(t){var e={controller:y,detector:n.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return r.extend(e,t)},y.update=function(t,e,i,n){for(var s,r,o,a=i.world,h=t.buckets,l=!1,u=i.metrics,c=u.broadphaseTests=0;ca.bounds.max.x||d.bounds.max.ya.bounds.max.y)){var f=y._getRegion(t,d);if(!d.region||f.id!==d.region.id||n){u.broadphaseTests+=1,d.region&&!n||(d.region=f);for(var p=y._regionUnion(f,d.region),g=p.startCol;g<=p.endCol;g++)for(s=p.startRow;s<=p.endRow;s++){r=h[o=y._getBucketId(g,s)];var v=g>=f.startCol&&g<=f.endCol&&s>=f.startRow&&s<=f.endRow,m=g>=d.region.startCol&&g<=d.region.endCol&&s>=d.region.startRow&&s<=d.region.endRow;!v&&m&&m&&r&&y._bucketRemoveBody(t,r,d),(d.region===f||v&&!m||n)&&(r=r||y._createBucket(h,o),y._bucketAddBody(t,r,d))}d.region=f,l=!0}}}l&&(t.pairsList=y._createActivePairsList(t))},y.clear=function(t){t.buckets={},t.pairs={},t.pairsList=[]},y._regionUnion=function(t,e){var i=Math.min(t.startCol,e.startCol),n=Math.max(t.endCol,e.endCol),s=Math.min(t.startRow,e.startRow),r=Math.max(t.endRow,e.endRow);return y._createRegion(i,n,s,r)},y._getRegion=function(t,e){var i=e.bounds,n=Math.floor(i.min.x/t.bucketWidth),s=Math.floor(i.max.x/t.bucketWidth),r=Math.floor(i.min.y/t.bucketHeight),o=Math.floor(i.max.y/t.bucketHeight);return y._createRegion(n,s,r,o)},y._createRegion=function(t,e,i,n){return{id:t+","+e+","+i+","+n,startCol:t,endCol:e,startRow:i,endRow:n}},y._getBucketId=function(t,e){return"C"+t+"R"+e},y._createBucket=function(t,e){return t[e]=[]},y._bucketAddBody=function(t,e,i){for(var n=0;nl._pairMaxIdleLife&&a.push(h);for(h=0;hu.friction*u.frictionStatic*O*i&&(D=M,L=X.clamp(u.friction*P*i,-D,D));var F,k,I=U.cross(w,p),B=U.cross(b,p),N=m/(d.inverseMass+f.inverseMass+d.inverseInertia*I*I+f.inverseInertia*B*B);R*=N,L*=N,_<0&&_*_>Y._restingThresh*i?x.normalImpulse=0:(F=x.normalImpulse,x.normalImpulse=Math.min(x.normalImpulse+R,0),R=x.normalImpulse-F),C*C>Y._restingThreshTangent*i?x.tangentImpulse=0:(k=x.tangentImpulse,x.tangentImpulse=X.clamp(x.tangentImpulse+L,-D,D),L=x.tangentImpulse-k),n.x=p.x*R+g.x*L,n.y=p.y*R+g.y*L,d.isStatic||d.isSleeping||(d.positionPrev.x+=n.x*d.inverseMass,d.positionPrev.y+=n.y*d.inverseMass,d.anglePrev+=U.cross(w,n)*d.inverseInertia),f.isStatic||f.isSleeping||(f.positionPrev.x-=n.x*f.inverseMass,f.positionPrev.y-=n.y*f.inverseMass,f.anglePrev-=U.cross(b,n)*f.inverseInertia)}}}}},function(t,e,i){t.exports={BasePlugin:i(520),DefaultPlugins:i(193),PluginCache:i(24),PluginManager:i(392),ScenePlugin:i(1398)}},function(t,e,i){var n=i(520),s=i(0),r=i(21),o=new s({Extends:n,initialize:function(t,e){n.call(this,e),this.scene=t,this.systems=t.sys,t.sys.events.once(r.BOOT,this.boot,this)},boot:function(){},destroy:function(){this.pluginManager=null,this.game=null,this.scene=null,this.systems=null}});t.exports=o},function(t,e,i){var n=i(19),s=i(196),r=n(!1,r={Center:i(381),Events:i(101),Orientation:i(382),ScaleManager:i(393),ScaleModes:i(383),Zoom:i(384)},s.CENTER);r=n(!1,r,s.ORIENTATION),r=n(!1,r,s.SCALE_MODE),r=n(!1,r,s.ZOOM),t.exports=r},function(t,e,i){var n=i(141),s=i(19)(!1,s={Events:i(21),GetPhysicsPlugins:i(397),GetScenePlugins:i(398),SceneManager:i(395),ScenePlugin:i(1401),Settings:i(399),Systems:i(199)},n);t.exports=s},function(t,e,i){var n=i(17),s=i(0),a=i(21),h=i(2),r=i(24),o=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.settings=t.sys.settings,this.key=t.sys.settings.key,this.manager=t.sys.game.scene,this.transitionProgress=0,this._elapsed=0,this._target=null,this._duration=0,this._onUpdate,this._onUpdateScope,this._willSleep=!1,this._willRemove=!1,t.sys.events.once(a.BOOT,this.boot,this),t.sys.events.on(a.START,this.pluginStart,this)},boot:function(){this.systems.events.once(a.DESTROY,this.destroy,this)},pluginStart:function(){this._target=null,this.systems.events.once(a.SHUTDOWN,this.shutdown,this)},start:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",this.key),this.manager.queueOp("start",t,e),this},restart:function(t){var e=this.key;return this.manager.queueOp("stop",e),this.manager.queueOp("start",e,t),this},transition:function(t){void 0===t&&(t={});var e=h(t,"target",!1),i=this.manager.getScene(e);if(!e||!this.checkValidTransition(i))return!1;var n=h(t,"duration",1e3);this._elapsed=0,this._target=i,this._duration=n,this._willSleep=h(t,"sleep",!1),this._willRemove=h(t,"remove",!1);var s=h(t,"onUpdate",null);s&&(this._onUpdate=s,this._onUpdateScope=h(t,"onUpdateScope",this.scene));var r=h(t,"allowInput",!1);this.settings.transitionAllowInput=r;var o=i.sys.settings;return o.isTransition=!0,o.transitionFrom=this.scene,o.transitionDuration=n,o.transitionAllowInput=r,h(t,"moveAbove",!1)?this.manager.moveAbove(this.key,e):h(t,"moveBelow",!1)&&this.manager.moveBelow(this.key,e),i.sys.isSleeping()?i.sys.wake(h(t,"data")):this.manager.start(e,h(t,"data")),this.systems.events.emit(a.TRANSITION_OUT,i,n),this.systems.events.on(a.UPDATE,this.step,this),!0},checkValidTransition:function(t){return!(!t||t.sys.isActive()||t.sys.isTransitioning()||t===this.scene||this.systems.isTransitioning())},step:function(t,e){this._elapsed+=e,this.transitionProgress=n(this._elapsed/this._duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.transitionProgress),this._elapsed>=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(416),List:i(105),Map:i(99),ProcessQueue:i(206),RTree:i(509),Set:i(147),Size:i(394)}},function(t,e,i){var n=i(19),s=i(1404),r=n(!1,r={CanvasTexture:i(401),Events:i(103),FilterMode:s,Frame:i(104),Parsers:i(403),Texture:i(201),TextureManager:i(400),TextureSource:i(402)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(19),s=i(1406),r=n(!1,r={Components:i(245),Parsers:i(1439),Formats:i(37),ImageCollection:i(556),ParseToTilemap:i(256),Tile:i(83),Tilemap:i(560),TilemapCreator:i(1445),TilemapFactory:i(1446),Tileset:i(119),TilemapLayer:i(561),Orientation:i(29),LayerData:i(117),MapData:i(118),ObjectLayer:i(552)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(29)};t.exports=n},function(t,e,i){var p=i(26),g=i(60);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),l=s-t,u=r-e,c=0;c=t&&l.index<=e&&u(l,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(71),h=i(60),l=i(157);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(77),DeepCopy:i(171),Extend:i(19),GetAdvancedValue:i(13),GetFastValue:i(2),GetMinMaxValue:i(1471),GetValue:i(6),HasAll:i(1472),HasAny:i(433),HasValue:i(125),IsPlainObject:i(7),Merge:i(142),MergeRight:i(1473),Pick:i(551),SetValue:i(456)}},function(t,e,i){var o=i(6),a=i(17);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;ii[e][0])&&(e=n);return!S(P(t,e-1),P(t,e),P(t,e+1))&&(function(t){for(var e=[],i=t.length,n=0;n!==i;n++)e.push(t.pop());for(n=0;n!==i;n++)t[n]=e[n]}(t),!0)}};var u=[],c=[];function M(t,e){var i=e[0]-t[0],n=e[1]-t[1];return i*i+n*n}function P(t,e){var i=t.length;return t[e<0?e%i+i:e%i]}function R(t,e,i,n){for(var s=i;sn.deltaMax?n.deltaMax:e)/n.delta,n.delta=e),0!==n.timeScalePrev&&(r*=s.timeScale/n.timeScalePrev),0===s.timeScale&&(r=0),n.timeScalePrev=s.timeScale,n.correction=r,n.frameCounter+=1,1e3<=t-n.counterTimestamp&&(n.fps=n.frameCounter*((t-n.counterTimestamp)/1e3),n.counterTimestamp=t,n.frameCounter=0),T.update(i,e,r))},step:function(t,e){T.update(this.engine,t,e)},update60Hz:function(){return 1e3/60},update30Hz:function(){return 1e3/30},has:function(t){var e=t.hasOwnProperty("body")?t.body:t;return null!==u.get(this.localWorld,e.id,e.type)},getAllBodies:function(){return u.allBodies(this.localWorld)},getAllConstraints:function(){return u.allConstraints(this.localWorld)},getAllComposites:function(){return u.allComposites(this.localWorld)},postUpdate:function(){var t,e,i,n;this.drawDebug&&(t=this.debugConfig,e=this.engine,i=this.debugGraphic,n=u.allBodies(this.localWorld),this.debugGraphic.clear(),t.showBroadphase&&e.broadphase.controller&&this.renderGrid(e.broadphase,i,t.broadphaseColor,.5),t.showBounds&&this.renderBodyBounds(n,i,t.boundsColor,.5),(t.showBody||t.showStaticBody)&&this.renderBodies(n),t.showJoint&&this.renderJoints(),(t.showAxes||t.showAngleIndicator)&&this.renderBodyAxes(n,i,t.showAxes,t.angleColor,.5),t.showVelocity&&this.renderBodyVelocity(n,i,t.velocityColor,1,2),t.showSeparations&&this.renderSeparations(e.pairs.list,i,t.separationColor),t.showCollisions&&this.renderCollisions(e.pairs.list,i,t.collisionColor))},renderGrid:function(t,e,i,n){e.lineStyle(1,i,n);for(var s=y.keys(t.buckets),r=0;re.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?n=e.min.y-t.max.y:t.max.y=this.right?this.width=0:this.width=this.right-t,this.x=t}},right:{get:function(){return this.x+this.width},set:function(t){t<=this.x?this.width=0:this.width=t-this.x}},top:{get:function(){return this.y},set:function(t){t>=this.bottom?this.height=0:this.height=this.bottom-t,this.y=t}},bottom:{get:function(){return this.y+this.height},set:function(t){t<=this.y?this.height=0:this.height=t-this.y}},centerX:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},centerY:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=u},function(t,e,i){t.exports={Alpha:i(605),AlphaSingle:i(297),BlendMode:i(298),ComputedSize:i(606),Crop:i(607),Depth:i(299),Flip:i(608),GetBounds:i(609),Mask:i(303),Origin:i(630),PathFollower:i(631),Pipeline:i(171),ScrollFactor:i(306),Size:i(632),Texture:i(633),TextureCrop:i(634),Tint:i(635),ToJSON:i(173),Transform:i(307),TransformMatrix:i(25),Visible:i(308)}},function(t,e){t.exports={getTintFromFloats:function(t,e,i,n){return((255&(255*n|0))<<24|(255&(255*t|0))<<16|(255&(255*e|0))<<8|255&(255*i|0))>>>0},getTintAppendFloatAlpha:function(t,e){return((255&(255*e|0))<<24|t)>>>0},getTintAppendFloatAlphaAndSwap:function(t,e){return((255&(255*e|0))<<24|(255&(0|t))<<16|(255&(t>>8|0))<<8|255&(t>>16|0))>>>0},getFloatsFromUintRGB:function(t){return[(255&(t>>16|0))/255,(255&(t>>8|0))/255,(255&(0|t))/255]},checkShaderMax:function(t,e){e&&-1!==e||(e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));for(var i=t.createShader(t.FRAGMENT_SHADER),n=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n");;){var s=n.replace(/%forloop%/gi,function(t){for(var e="",i=0;ir.width&&(i=Math.max(r.width-t,0)),e+n>r.height&&(n=Math.max(r.height-e,0));for(var l=[],u=e;uthis.x2?this.x1=t:this.x2=t}},top:{get:function(){return Math.min(this.y1,this.y2)},set:function(t){this.y1<=this.y2?this.y1=t:this.y2=t}},bottom:{get:function(){return Math.max(this.y1,this.y2)},set:function(t){this.y1>this.y2?this.y1=t:this.y2=t}}});t.exports=l},function(t,e){t.exports=function(t,e,i,n){var s=i||e.fillColor,r=n||e.fillAlpha,o=(16711680&s)>>>16,a=(65280&s)>>>8,h=255&s;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n){var s=[];n.forEach(function(t){t&&s.push(t)}),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=s,this.complete=!1,this.pending=s.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var r=0;r=e&&t.y<=i&&t.y+t.height>=i)}},function(t,e,i){var n=i(0),y=i(172),s=i(9),v=i(368),x=i(2),m=i(67),T=i(88),w=i(139),b=i(12),E=i(369),r=new n({Extends:s,initialize:function(t){s.call(this);var e=t.game,i=e.renderer,n=i.gl;this.name=x(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=n,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.topology=x(t,"topology",n.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.currentUnit=0,this.forceZero=x(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t},boot:function(){var t=this.gl,e=this.config,i=this.renderer;this.isPostFX||(this.projectionMatrix=(new m).identity());var n=this.renderTargets,s=x(e,"renderTarget",!1);"boolean"==typeof s&&s&&(s=1);var r=i.width,o=i.height;if("number"==typeof s)for(d=0;dc&&(c=u[d].vertexSize);var f=x(e,"batchSize",i.config.batchSize);this.vertexCapacity=6*f;var p=new ArrayBuffer(this.vertexCapacity*c);this.vertexData=p,this.bytes=new Uint8Array(p),this.vertexViewF32=new Float32Array(p),this.vertexViewU32=new Uint32Array(p);var g=x(e,"vertices",null);for(g?(this.vertexViewF32.set(g),this.vertexBuffer=i.createVertexBuffer(p,t.STATIC_DRAW)):this.vertexBuffer=i.createVertexBuffer(p.byteLength,t.DYNAMIC_DRAW),this.setVertexBuffer(),d=u.length-1;0<=d;d--)u[d].rebind();this.hasBooted=!0,i.on(T.RESIZE,this.resize,this),i.on(T.PRE_RENDER,this.onPreRender,this),i.on(T.RENDER,this.onRender,this),i.on(T.POST_RENDER,this.onPostRender,this),this.emit(v.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e){var i=this.renderer;return t===this.currentShader&&i.currentProgram===this.currentShader.program||(this.flush(),i.resetTextures(),this.setVertexBuffer()&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t),this},getShaderByName:function(t){for(var e=this.shaders,i=0;ithis.vertexCapacity},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,n=0;n>>16,a=(65280&s)>>>8,h=255&s;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},function(t,e,i){var n=i(0),h=i(20),l=i(23),s=i(8),u=i(2),c=i(6),d=i(7),r=new n({Extends:l,initialize:function(t,e,i,n,s){var r,o="json";d(e)&&(e=u(r=e,"key"),i=u(r,"url"),n=u(r,"xhrSettings"),o=u(r,"extension",o),s=u(r,"dataKey",s));var a={type:"json",cache:t.cacheManager.json,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:s};l.call(this,t,a),d(i)&&(this.data=s?c(i,s):i,this.state=h.FILE_POPULATED)},onProcess:function(){var t,e;this.state!==h.FILE_POPULATED&&(this.state=h.FILE_PROCESSING,t=JSON.parse(this.xhrLoader.responseText),e=this.config,this.data="string"==typeof e?c(t,e,t):t),this.onProcessComplete()}});s.register("json",function(t,e,i,n){if(Array.isArray(t))for(var s=0;s=t.left&&e<=t.right&&i>=t.top&&i<=t.bottom&&(t.x-e)*(t.x-e)+(t.y-i)*(t.y-i)<=t.radius*t.radius}},function(t,e){t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},function(t,e){t.exports={BITMAPMASK_PIPELINE:"BitmapMaskPipeline",LIGHT_PIPELINE:"Light2D",POINTLIGHT_PIPELINE:"PointLightPipeline",SINGLE_PIPELINE:"SinglePipeline",MULTI_PIPELINE:"MultiPipeline",ROPE_PIPELINE:"RopePipeline",GRAPHICS_PIPELINE:"GraphicsPipeline",POSTFX_PIPELINE:"PostFXPipeline",UTILITY_PIPELINE:"UtilityPipeline"}},function(t,e){t.exports=function(t,e,i){var n=i-e;return e+((t-e)%n+n)%n}},function(t,e,i){var n=i(0),s=i(37),r=new n({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new r(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,n,s,r,o,a,h,l,u,c,d,f,p,g){var v=this.val;return v[0]=t,v[1]=e,v[2]=i,v[3]=n,v[4]=s,v[5]=r,v[6]=o,v[7]=a,v[8]=h,v[9]=l,v[10]=u,v[11]=c,v[12]=d,v[13]=f,v[14]=p,v[15]=g,this},copy:function(t){var e=t.val;return this.setValues(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},fromArray:function(t){return this.setValues(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},zero:function(){return this.setValues(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)},transform:function(t,e,i){var n=h.fromQuat(i).val,s=e.x,r=e.y,o=e.z;return this.setValues(n[0]*s,n[1]*s,n[2]*s,0,n[4]*r,n[5]*r,n[6]*r,0,n[8]*o,n[9]*o,n[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var n=this.val;return n[12]=t,n[13]=e,n[14]=i,this},scaling:function(t,e,i){this.zero();var n=this.val;return n[0]=t,n[5]=e,n[10]=i,n[15]=1,this},identity:function(){return this.setValues(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},transpose:function(){var t=this.val,e=t[1],i=t[2],n=t[3],s=t[6],r=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=e,t[6]=t[9],t[7]=t[13],t[8]=i,t[9]=s,t[11]=t[14],t[12]=n,t[13]=r,t[14]=o,this},getInverse:function(t){return this.copy(t),this.invert()},invert:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15],m=e*o-i*r,y=e*a-n*r,x=e*h-s*r,T=i*a-n*o,w=i*h-s*o,b=n*h-s*a,E=l*p-u*f,S=l*g-c*f,A=l*v-d*f,_=u*g-c*p,C=u*v-d*p,M=c*v-d*g,P=m*M-y*C+x*_+T*A-w*S+b*E;return P?(P=1/P,this.setValues((o*M-a*C+h*_)*P,(n*C-i*M-s*_)*P,(p*b-g*w+v*T)*P,(c*w-u*b-d*T)*P,(a*A-r*M-h*S)*P,(e*M-n*A+s*S)*P,(g*x-f*b-v*y)*P,(l*b-c*x+d*y)*P,(r*C-o*A+h*E)*P,(i*A-e*C-s*E)*P,(f*w-p*x+v*m)*P,(u*x-l*w-d*m)*P,(o*S-r*_-a*E)*P,(e*_-i*S+n*E)*P,(p*y-f*T-g*m)*P,(l*T-u*y+c*m)*P)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return this.setValues(o*(c*v-d*g)-u*(a*v-h*g)+p*(a*d-h*c),-(i*(c*v-d*g)-u*(n*v-s*g)+p*(n*d-s*c)),i*(a*v-h*g)-o*(n*v-s*g)+p*(n*h-s*a),-(i*(a*d-h*c)-o*(n*d-s*c)+u*(n*h-s*a)),-(r*(c*v-d*g)-l*(a*v-h*g)+f*(a*d-h*c)),e*(c*v-d*g)-l*(n*v-s*g)+f*(n*d-s*c),-(e*(a*v-h*g)-r*(n*v-s*g)+f*(n*h-s*a)),e*(a*d-h*c)-r*(n*d-s*c)+l*(n*h-s*a),r*(u*v-d*p)-l*(o*v-h*p)+f*(o*d-h*u),-(e*(u*v-d*p)-l*(i*v-s*p)+f*(i*d-s*u)),e*(o*v-h*p)-r*(i*v-s*p)+f*(i*h-s*o),-(e*(o*d-h*u)-r*(i*d-s*u)+l*(i*h-s*o)),-(r*(u*g-c*p)-l*(o*g-a*p)+f*(o*c-a*u)),e*(u*g-c*p)-l*(i*g-n*p)+f*(i*c-n*u),-(e*(o*g-a*p)-r*(i*g-n*p)+f*(i*a-n*o)),e*(o*c-a*u)-r*(i*c-n*u)+l*(i*a-n*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],n=t[2],s=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=t[9],c=t[10],d=t[11],f=t[12],p=t[13],g=t[14],v=t[15];return(e*o-i*r)*(c*v-d*g)-(e*a-n*r)*(u*v-d*p)+(e*h-s*r)*(u*g-c*p)+(i*a-n*o)*(l*v-d*f)-(i*h-s*o)*(l*g-c*f)+(n*h-s*a)*(l*p-u*f)},multiply:function(t){var e=this.val,i=e[0],n=e[1],s=e[2],r=e[3],o=e[4],a=e[5],h=e[6],l=e[7],u=e[8],c=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15],y=t.val,x=y[0],T=y[1],w=y[2],b=y[3];return e[0]=x*i+T*o+w*u+b*p,e[1]=x*n+T*a+w*c+b*g,e[2]=x*s+T*h+w*d+b*v,e[3]=x*r+T*l+w*f+b*m,x=y[4],T=y[5],w=y[6],b=y[7],e[4]=x*i+T*o+w*u+b*p,e[5]=x*n+T*a+w*c+b*g,e[6]=x*s+T*h+w*d+b*v,e[7]=x*r+T*l+w*f+b*m,x=y[8],T=y[9],w=y[10],b=y[11],e[8]=x*i+T*o+w*u+b*p,e[9]=x*n+T*a+w*c+b*g,e[10]=x*s+T*h+w*d+b*v,e[11]=x*r+T*l+w*f+b*m,x=y[12],T=y[13],w=y[14],b=y[15],e[12]=x*i+T*o+w*u+b*p,e[13]=x*n+T*a+w*c+b*g,e[14]=x*s+T*h+w*d+b*v,e[15]=x*r+T*l+w*f+b*m,this},multiplyLocal:function(t){var e=this.val,i=t.val;return this.setValues(e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15])},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.val,n=e.val,s=i[0],r=i[4],o=i[8],a=i[12],h=i[1],l=i[5],u=i[9],c=i[13],d=i[2],f=i[6],p=i[10],g=i[14],v=i[3],m=i[7],y=i[11],x=i[15],T=n[0],w=n[4],b=n[8],E=n[12],S=n[1],A=n[5],_=n[9],C=n[13],M=n[2],P=n[6],R=n[10],O=n[14],L=n[3],D=n[7],F=n[11],k=n[15];return this.setValues(s*T+r*S+o*M+a*L,h*T+l*S+u*M+c*L,d*T+f*S+p*M+g*L,v*T+m*S+y*M+x*L,s*w+r*A+o*P+a*D,h*w+l*A+u*P+c*D,d*w+f*A+p*P+g*D,v*w+m*A+y*P+x*D,s*b+r*_+o*R+a*F,h*b+l*_+u*R+c*F,d*b+f*_+p*R+g*F,v*b+m*_+y*R+x*F,s*E+r*C+o*O+a*k,h*E+l*C+u*O+c*k,d*E+f*C+p*O+g*k,v*E+m*C+y*O+x*k)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var n=this.val;return n[12]=n[0]*t+n[4]*e+n[8]*i+n[12],n[13]=n[1]*t+n[5]*e+n[9]*i+n[13],n[14]=n[2]*t+n[6]*e+n[10]*i+n[14],n[15]=n[3]*t+n[7]*e+n[11]*i+n[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var n=this.val;return n[0]=n[0]*t,n[1]=n[1]*t,n[2]=n[2]*t,n[3]=n[3]*t,n[4]=n[4]*e,n[5]=n[5]*e,n[6]=n[6]*e,n[7]=n[7]*e,n[8]=n[8]*i,n[9]=n[9]*i,n[10]=n[10]*i,n[11]=n[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),n=Math.sin(e),s=1-i,r=t.x,o=t.y,a=t.z,h=s*r,l=s*o;return this.setValues(h*r+i,h*o-n*a,h*a+n*o,0,h*o+n*a,l*o+i,l*a-n*r,0,h*a-n*o,l*a+n*r,s*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,n=e.x,s=e.y,r=e.z,o=Math.sqrt(n*n+s*s+r*r);if(Math.abs(o)<1e-6)return this;n*=o=1/o,s*=o,r*=o;var a=Math.sin(t),h=Math.cos(t),l=1-h,u=i[0],c=i[1],d=i[2],f=i[3],p=i[4],g=i[5],v=i[6],m=i[7],y=i[8],x=i[9],T=i[10],w=i[11],b=i[12],E=i[13],S=i[14],A=i[15],_=n*n*l+h,C=s*n*l+r*a,M=r*n*l-s*a,P=n*s*l-r*a,R=s*s*l+h,O=r*s*l+n*a,L=n*r*l+s*a,D=s*r*l-n*a,F=r*r*l+h;return this.setValues(u*_+p*C+y*M,c*_+g*C+x*M,d*_+v*C+T*M,f*_+m*C+w*M,u*P+p*R+y*O,c*P+g*R+x*O,d*P+v*R+T*O,f*P+m*R+w*O,u*L+p*D+y*F,c*L+g*D+x*F,d*L+v*D+T*F,f*L+m*D+w*F,b,E,S,A)},rotateX:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[4],r=e[5],o=e[6],a=e[7],h=e[8],l=e[9],u=e[10],c=e[11];return e[4]=s*n+h*i,e[5]=r*n+l*i,e[6]=o*n+u*i,e[7]=a*n+c*i,e[8]=h*n-s*i,e[9]=l*n-r*i,e[10]=u*n-o*i,e[11]=c*n-a*i,this},rotateY:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[8],l=e[9],u=e[10],c=e[11];return e[0]=s*n-h*i,e[1]=r*n-l*i,e[2]=o*n-u*i,e[3]=a*n-c*i,e[8]=s*i+h*n,e[9]=r*i+l*n,e[10]=o*i+u*n,e[11]=a*i+c*n,this},rotateZ:function(t){var e=this.val,i=Math.sin(t),n=Math.cos(t),s=e[0],r=e[1],o=e[2],a=e[3],h=e[4],l=e[5],u=e[6],c=e[7];return e[0]=s*n+h*i,e[1]=r*n+l*i,e[2]=o*n+u*i,e[3]=a*n+c*i,e[4]=h*n-s*i,e[5]=l*n-r*i,e[6]=u*n-o*i,e[7]=c*n-a*i,this},fromRotationTranslation:function(t,e){var i=t.x,n=t.y,s=t.z,r=t.w,o=i+i,a=n+n,h=s+s,l=i*o,u=i*a,c=i*h,d=n*a,f=n*h,p=s*h,g=r*o,v=r*a,m=r*h;return this.setValues(1-(d+p),u+m,c-v,0,u-m,1-(l+p),f+g,0,c+v,f-g,1-(l+d),0,e.x,e.y,e.z,1)},fromQuat:function(t){var e=t.x,i=t.y,n=t.z,s=t.w,r=e+e,o=i+i,a=n+n,h=e*r,l=e*o,u=e*a,c=i*o,d=i*a,f=n*a,p=s*r,g=s*o,v=s*a;return this.setValues(1-(c+f),l+v,u-g,0,l-v,1-(h+f),d+p,0,u+g,d-p,1-(h+c),0,0,0,0,1)},frustum:function(t,e,i,n,s,r){var o=1/(e-t),a=1/(n-i),h=1/(s-r);return this.setValues(2*s*o,0,0,0,0,2*s*a,0,0,(e+t)*o,(n+i)*a,(r+s)*h,-1,0,0,r*s*2*h,0)},perspective:function(t,e,i,n){var s=1/Math.tan(t/2),r=1/(i-n);return this.setValues(s/e,0,0,0,0,s,0,0,0,0,(n+i)*r,-1,0,0,2*n*i*r,0)},perspectiveLH:function(t,e,i,n){return this.setValues(2*i/t,0,0,0,0,2*i/e,0,0,0,0,-n/(i-n),1,0,0,i*n/(i-n),0)},ortho:function(t,e,i,n,s,r){var o=0===(o=t-e)?o:1/o,a=0===(a=i-n)?a:1/a,h=0===(h=s-r)?h:1/h;return this.setValues(-2*o,0,0,0,0,-2*a,0,0,0,0,2*h,0,(t+e)*o,(n+i)*a,(r+s)*h,1)},lookAtRH:function(t,e,i){var n=this.val;return u.subVectors(t,e),0===u.getLengthSquared()&&(u.z=1),u.normalize(),o.crossVectors(i,u),0===o.getLengthSquared()&&(1===Math.abs(i.z)?u.x+=1e-4:u.z+=1e-4,u.normalize(),o.crossVectors(i,u)),o.normalize(),a.crossVectors(u,o),n[0]=o.x,n[1]=o.y,n[2]=o.z,n[4]=a.x,n[5]=a.y,n[6]=a.z,n[8]=u.x,n[9]=u.y,n[10]=u.z,this},lookAt:function(t,e,i){var n=t.x,s=t.y,r=t.z,o=i.x,a=i.y,h=i.z,l=e.x,u=e.y,c=e.z;if(Math.abs(n-l)<1e-6&&Math.abs(s-u)<1e-6&&Math.abs(r-c)<1e-6)return this.identity();var d=n-l,f=s-u,p=r-c,g=1/Math.sqrt(d*d+f*f+p*p),v=a*(p*=g)-h*(f*=g),m=h*(d*=g)-o*p,y=o*f-a*d;(g=Math.sqrt(v*v+m*m+y*y))?(v*=g=1/g,m*=g,y*=g):y=m=v=0;var x=f*y-p*m,T=p*v-d*y,w=d*m-f*v;return(g=Math.sqrt(x*x+T*T+w*w))?(x*=g=1/g,T*=g,w*=g):w=T=x=0,this.setValues(v,x,d,0,m,T,f,0,y,w,p,0,-(v*n+m*s+y*r),-(x*n+T*s+w*r),-(d*n+f*s+p*r),1)},yawPitchRoll:function(t,e,i){this.zero(),h.zero(),l.zero();var n=this.val,s=h.val,r=l.val,o=Math.sin(i),a=Math.cos(i);return n[10]=1,n[15]=1,n[0]=a,n[1]=o,n[4]=-o,n[5]=a,o=Math.sin(e),a=Math.cos(e),s[0]=1,s[15]=1,s[5]=a,s[10]=a,s[9]=-o,s[6]=o,o=Math.sin(t),a=Math.cos(t),r[5]=1,r[15]=1,r[0]=a,r[2]=-o,r[8]=o,r[10]=a,this.multiplyLocal(h),this.multiplyLocal(l),this},setWorldMatrix:function(t,e,i,n,s){return this.yawPitchRoll(t.y,t.x,t.z),h.scaling(i.x,i.y,i.z),l.xyz(e.x,e.y,e.z),this.multiplyLocal(h),this.multiplyLocal(l),n&&this.multiplyLocal(n),s&&this.multiplyLocal(s),this},multiplyToMat4:function(t,e){var i=this.val,n=t.val,s=i[0],r=i[1],o=i[2],a=i[3],h=i[4],l=i[5],u=i[6],c=i[7],d=i[8],f=i[9],p=i[10],g=i[11],v=i[12],m=i[13],y=i[14],x=i[15],T=n[0],w=n[1],b=n[2],E=n[3],S=n[4],A=n[5],_=n[6],C=n[7],M=n[8],P=n[9],R=n[10],O=n[11],L=n[12],D=n[13],F=n[14],k=n[15];return e.setValues(T*s+w*h+b*d+E*v,w*r+w*l+b*f+E*m,b*o+w*u+b*p+E*y,E*a+w*c+b*g+E*x,S*s+A*h+_*d+C*v,S*r+A*l+_*f+C*m,S*o+A*u+_*p+C*y,S*a+A*c+_*g+C*x,M*s+P*h+R*d+O*v,M*r+P*l+R*f+O*m,M*o+P*u+R*p+O*y,M*a+P*c+R*g+O*x,L*s+D*h+F*d+k*v,L*r+D*l+F*f+k*m,L*o+D*u+F*p+k*y,L*a+D*c+F*g+k*x)},fromRotationXYTranslation:function(t,e,i){var n=e.x,s=e.y,r=e.z,o=Math.sin(t.x),a=Math.cos(t.x),h=Math.sin(t.y),l=Math.cos(t.y),u=n,c=s,d=r,f=-o,p=0-f*h,g=0-a*h,v=f*l,m=a*l;return i||(u=l*n+h*r,c=p*n+a*s+v*r,d=g*n+o*s+m*r),this.setValues(l,p,g,0,0,a,o,0,h,v,m,0,u,c,d,1)},getMaxScaleOnAxis:function(){var t=this.val,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],n=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,n))}}),h=new r,l=new r,o=new s,a=new s,u=new s;t.exports=r},function(t,e,i){"use strict";function n(t,e,i){i=i||2;var n,s,r,o,a,h,l,u=e&&e.length,c=u?e[0]*i:t.length,d=g(t,0,c,i,!0),f=[];if(!d||d.next===d.prev)return f;if(u&&(d=function(t,e,i,n){var s,r,o,a,h,l=[];for(s=0,r=e.length;s=n.next.y&&n.next.y!==n.y){var a=n.x+(r-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=s&&o=n.x&&n.x>=u&&s!==n.x&&T(ri.x||n.x===i.x&&function(t,e){return w(t.prev,t,e.prev)<0&&w(e.next,t,t.next)<0}(i,n)))&&(i=n,d=h)),n=n.next,n!==l;);return i}(t,e))&&(i=E(e,t),v(e,e.next),v(i,i.next))}}(l[s],i),i=v(i,i.next);return i}(t,e,d,i)),t.length>80*i){n=r=t[0],s=o=t[1];for(var p=i;pr.x?s.x>o.x?s.x:o.x:r.x>o.x?r.x:o.x,u=s.y>r.y?s.y>o.y?s.y:o.y:r.y>o.y?r.y:o.y,c=x(a,h,e,i,n),d=x(l,u,e,i,n),f=t.prevZ,p=t.nextZ;for(;f&&f.z>=c&&p&&p.z<=d;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;if(f=f.prevZ,p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}for(;f&&f.z>=c;){if(f!==t.prev&&f!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,f.x,f.y)&&0<=w(f.prev,f,f.next))return!1;f=f.prevZ}for(;p&&p.z<=d;){if(p!==t.prev&&p!==t.next&&T(s.x,s.y,r.x,r.y,o.x,o.y,p.x,p.y)&&0<=w(p.prev,p,p.next))return!1;p=p.nextZ}return!0}(t,n,s,r):function(t){var e=t.prev,i=t,n=t.next;if(0<=w(e,i,n))return!1;var s=t.next.next;for(;s!==t.prev;){if(T(e.x,e.y,i.x,i.y,n.x,n.y,s.x,s.y)&&0<=w(s.prev,s,s.next))return!1;s=s.next}return!0}(t))e.push(a.i/i),e.push(t.i/i),e.push(h.i/i),d(t),t=h.next,l=h.next;else if((t=h)===l){o?1===o?m(t=function(t,e,i){var n=t;do{var s=n.prev,r=n.next.next;!u(s,r)&&c(s,n,n.next,r)&&b(s,r)&&b(r,s)&&(e.push(s.i/i),e.push(n.i/i),e.push(r.i/i),d(n),d(n.next),n=t=r),n=n.next}while(n!==t);return v(n)}(v(t),e,i),e,i,n,s,r,2):2===o&&function(t,e,i,n,s,r){var o=t;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&function(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&c(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(b(t,e)&&b(e,t)&&function(t,e){var i=t,n=!1,s=(t.x+e.x)/2,r=(t.y+e.y)/2;for(;i.y>r!=i.next.y>r&&i.next.y!==i.y&&s<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(n=!n),i=i.next,i!==t;);return n}(t,e)&&(w(t.prev,t,e.prev)||w(t,e.prev,e))||u(t,e)&&0=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function l(t){return 0=t.length)){for(var i=t.length-1,n=t[e],s=e;s=this.x2&&this.x1>=this.x3?this.x1-t:this.x2>=this.x1&&this.x2>=this.x3?this.x2-t:this.x3-t;this.x1-=e,this.x2-=e,this.x3-=e}},top:{get:function(){return Math.min(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1<=this.y2&&this.y1<=this.y3?this.y1-t:this.y2<=this.y1&&this.y2<=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}},bottom:{get:function(){return Math.max(this.y1,this.y2,this.y3)},set:function(t){var e=0,e=this.y1>=this.y2&&this.y1>=this.y3?this.y1-t:this.y2>=this.y1&&this.y2>=this.y3?this.y2-t:this.y3-t;this.y1-=e,this.y2-=e,this.y3-=e}}});t.exports=u},function(t,e,i){var n=i(29),s=i(0),r=i(11),o=i(496),a=new s({Mixins:[r.Alpha,r.Flip,r.Visible],initialize:function(t,e,i,n,s,r,o,a){this.layer=t,this.index=e,this.x=i,this.y=n,this.width=s,this.height=r,this.right,this.bottom,this.baseWidth=void 0!==o?o:s,this.baseHeight=void 0!==a?a:r,this.pixelX=0,this.pixelY=0,this.updatePixelXY(),this.properties={},this.rotation=0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceLeft=!1,this.faceRight=!1,this.faceTop=!1,this.faceBottom=!1,this.collisionCallback=void 0,(this.collisionCallbackContext=this).tint=16777215,this.physics={}},containsPoint:function(t,e){return!(tthis.right||e>this.bottom)},copy:function(t){return this.index=t.index,this.alpha=t.alpha,this.properties=t.properties,this.visible=t.visible,this.setFlip(t.flipX,t.flipY),this.tint=t.tint,this.rotation=t.rotation,this.collideUp=t.collideUp,this.collideDown=t.collideDown,this.collideLeft=t.collideLeft,this.collideRight=t.collideRight,this.collisionCallback=t.collisionCallback,this.collisionCallbackContext=t.collisionCallbackContext,this},getCollisionGroup:function(){return this.tileset?this.tileset.getTileCollisionGroup(this.index):null},getTileData:function(){return this.tileset?this.tileset.getTileData(this.index):null},getLeft:function(t){var e=this.tilemapLayer;return e?e.tileToWorldX(this.x,t):this.x*this.baseWidth},getRight:function(t){var e=this.tilemapLayer;return e?this.getLeft(t)+this.width*e.scaleX:this.getLeft(t)+this.width},getTop:function(t){var e=this.tilemapLayer;return e?e.tileToWorldY(this.y,t)-(this.height-this.baseHeight)*e.scaleY:this.y*this.baseHeight-(this.height-this.baseHeight)},getBottom:function(t){var e=this.tilemapLayer;return e?this.getTop(t)+this.height*e.scaleY:this.getTop(t)+this.height},getBounds:function(t,e){return void 0===e&&(e=new o),e.x=this.getLeft(),e.y=this.getTop(),e.width=this.getRight()-e.x,e.height=this.getBottom()-e.y,e},getCenterX:function(t){return(this.getLeft(t)+this.getRight(t))/2},getCenterY:function(t){return(this.getTop(t)+this.getBottom(t))/2},intersects:function(t,e,i,n){return!(i<=this.pixelX||n<=this.pixelY||t>=this.right||e>=this.bottom)},isInteresting:function(t,e){return t&&e?this.canCollide||this.hasInterestingFace:t?this.collides:!!e&&this.hasInterestingFace},resetCollision:function(t){return void 0===t&&(t=!0),this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,t&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,n,s){return void 0===e&&(e=t),void 0===i&&(i=t),void 0===n&&(n=t),void 0===s&&(s=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=n,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=n,s&&this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y),this},setCollisionCallback:function(t,e){return null===t?(this.collisionCallback=void 0,this.collisionCallbackContext=void 0):(this.collisionCallback=t,this.collisionCallbackContext=e),this},setSize:function(t,e,i,n){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==n&&(this.baseHeight=n),this.updatePixelXY(),this},updatePixelXY:function(){var t,e,i=this.layer.orientation;return i===n.ORTHOGONAL?(this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight):i===n.ISOMETRIC?(this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5):i===n.STAGGERED?(this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2)):i===n.HEXAGONAL&&(t=this.layer.hexSideLength,e=(this.baseHeight-t)/2+t,this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*e),this.right=this.pixelX+this.baseWidth,this.bottom=this.pixelY+this.baseHeight,this},destroy:function(){this.collisionCallback=void 0,this.collisionCallbackContext=void 0,this.properties=void 0},canCollide:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown||void 0!==this.collisionCallback}},collides:{get:function(){return this.collideLeft||this.collideRight||this.collideUp||this.collideDown}},hasInterestingFace:{get:function(){return this.faceTop||this.faceBottom||this.faceLeft||this.faceRight}},tileset:{get:function(){var t=this.layer.tilemapLayer;if(t){var e=t.gidMap[this.index];if(e)return e}return null}},tilemapLayer:{get:function(){return this.layer.tilemapLayer}},tilemap:{get:function(){var t=this.tilemapLayer;return t?t.tilemap:null}}});t.exports=a},function(t,e){t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},function(t,e){t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},function(t,e){t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},function(t,e){t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},function(t,e,i){t.exports={POST_RENDER:i(626),PRE_RENDER:i(627),RENDER:i(628),RESIZE:i(629)}},function(t,e,i){var h=i(74);t.exports=function(t,e,i,n){if(void 0===n&&(n=t),!Array.isArray(e))return-1!==(o=t.indexOf(e))?(h(t,o),i&&i.call(n,e),e):null;for(var s=e.length-1,r=[];0<=s;){var o,a=e[s];-1!==(o=t.indexOf(a))&&(h(t,o),r.push(a),i&&i.call(n,a)),s--}return r}},function(t,e,i){var n=i(0),s=i(196),r=i(10),o=i(3),a=new n({initialize:function(t){this.type=t,this.defaultDivisions=5,this.arcLengthDivisions=100,this.cacheArcLengths=[],this.needsUpdate=!0,this.active=!0,this._tmpVec2A=new o,this._tmpVec2B=new o},draw:function(t,e){return void 0===e&&(e=32),t.strokePoints(this.getPoints(e))},getBounds:function(t,e){t=t||new r,void 0===e&&(e=16);var i=this.getLength();ih||a.y>l)?(u=Math.max(a.x,e),c=Math.max(a.y,i),b=d=Math.min(a.r,h)-u,E=f=Math.min(a.b,l)-c,T=r?p+(v-(u-a.x)-d):p+(u-a.x),w=o?g+(m-(c-a.y)-f):g+(c-a.y),e=u,i=c,n=d,s=f):E=b=w=T=0):(r&&(T=p+(v-e-n)),o&&(w=g+(m-i-s)));var A=this.source.width,_=this.source.height;return t.u0=Math.max(0,T/A),t.v0=Math.max(0,w/_),t.u1=Math.min(1,(T+b)/A),t.v1=Math.min(1,(w+E)/_),t.x=e,t.y=i,t.cx=T,t.cy=w,t.cw=b,t.ch=E,t.width=n,t.height=s,t.flipX=r,t.flipY=o,t},updateCropUVs:function(t,e,i){return this.setCropUVs(t,t.x,t.y,t.width,t.height,e,i)},setUVs:function(t,e,i,n,s,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=n,this.u1=s,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,n=this.cutHeight,s=this.data.drawImage;s.width=i,s.height=n;var r=this.source.width,o=this.source.height;return this.u0=t/r,this.v0=e/o,this.u1=(t+i)/r,this.v1=(e+n)/o,this},updateUVsInverted:function(){var t=this.source.width,e=this.source.height;return this.u0=(this.cutX+this.cutHeight)/t,this.v0=this.cutY/e,this.u1=this.cutX/t,this.v1=(this.cutY+this.cutWidth)/e,this},clone:function(){var t=new r(this.texture,this.name,this.sourceIndex);return t.cutX=this.cutX,t.cutY=this.cutY,t.cutWidth=this.cutWidth,t.cutHeight=this.cutHeight,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t.halfWidth=this.halfWidth,t.halfHeight=this.halfHeight,t.centerX=this.centerX,t.centerY=this.centerY,t.rotated=this.rotated,t.data=s(!0,t.data,this.data),t.updateUVs(),t},destroy:function(){this.source=null,this.texture=null,this.glTexture=null,this.customData=null,this.data=null},realWidth:{get:function(){return this.data.sourceSize.w}},realHeight:{get:function(){return this.data.sourceSize.h}},radius:{get:function(){return this.data.radius}},trimmed:{get:function(){return this.data.trim}},canvasData:{get:function(){return this.data.drawImage}}});t.exports=r},function(t,e,i){var s=i(205),n=i(0),r=i(1),o=i(79),a=new n({initialize:function(t){this.parent=t,this.list=[],this.position=0,this.addCallback=r,this.removeCallback=r,this._sortKey=""},add:function(t,e){return e?s.Add(this.list,t):s.Add(this.list,t,0,this.addCallback,this)},addAt:function(t,e,i){return i?s.AddAt(this.list,t,e):s.AddAt(this.list,t,e,0,this.addCallback,this)},getAt:function(t){return this.list[t]},getIndex:function(t){return this.list.indexOf(t)},sort:function(i,t){return i&&(void 0===t&&(t=function(t,e){return t[i]-e[i]}),o(this.list,t)),this},getByName:function(t){return s.GetFirst(this.list,"name",t)},getRandom:function(t,e){return s.GetRandom(this.list,t,e)},getFirst:function(t,e,i,n){return s.GetFirst(this.list,t,e,i,n)},getAll:function(t,e,i,n){return s.GetAll(this.list,t,e,i,n)},count:function(t,e){return s.CountAllMatching(this.list,t,e)},swap:function(t,e){s.Swap(this.list,t,e)},moveTo:function(t,e){return s.MoveTo(this.list,t,e)},remove:function(t,e){return e?s.Remove(this.list,t):s.Remove(this.list,t,this.removeCallback,this)},removeAt:function(t,e){return e?s.RemoveAt(this.list,t):s.RemoveAt(this.list,t,this.removeCallback,this)},removeBetween:function(t,e,i){return i?s.RemoveBetween(this.list,t,e):s.RemoveBetween(this.list,t,e,this.removeCallback,this)},removeAll:function(t){for(var e=this.list.length;e--;)this.remove(this.list[e],t);return this},bringToTop:function(t){return s.BringToTop(this.list,t)},sendToBack:function(t){return s.SendToBack(this.list,t)},moveUp:function(t){return s.MoveUp(this.list,t),t},moveDown:function(t){return s.MoveDown(this.list,t),t},reverse:function(){return this.list.reverse(),this},shuffle:function(){return s.Shuffle(this.list),this},replace:function(t,e){return s.Replace(this.list,t,e)},exists:function(t){return-1=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;ie.right||t.y>e.bottom)}},function(t,e,i){var n=i(0),r=i(12),u=i(37),s=new n({Extends:u,initialize:function(t,e,i,n,s,r,o,a,h,l){void 0===r&&(r=16777215),void 0===o&&(o=1),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l=0),u.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=a,this.ny=h,this.nz=l,this.u=n,this.v=s,this.color=r,this.alpha=o,this.tx=0,this.ty=0,this.ta=0},setUVs:function(t,e){return this.u=t,this.v=e,this},transformCoordinatesLocal:function(t,e,i,n){var s=this.x,r=this.y,o=this.z,a=t.val,h=s*a[0]+r*a[4]+o*a[8]+a[12],l=s*a[1]+r*a[5]+o*a[9]+a[13],u=s*a[2]+r*a[6]+o*a[10]+a[14],c=s*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-l/c*i,this.vz=n<=0?u/c:-u/c},update:function(t,e,i,n,s,r,o,a){var h=this.vx*t+this.vy*i+s,l=this.vx*e+this.vy*n+r;return o&&(h=Math.round(h),l=Math.round(l)),this.tx=h,this.ty=l,this.ta=this.alpha*a,this},load:function(t,e,i,n,s){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.u,t[++i]=this.v,t[++i]=n,t[++i]=s,e[++i]=r.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=s},function(t,e){var i={};(t.exports=i).create=function(t,e){return{x:t||0,y:e||0}},i.clone=function(t){return{x:t.x,y:t.y}},i.magnitude=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},i.rotate=function(t,e,i){var n=Math.cos(e),s=Math.sin(e);i=i||{};var r=t.x*n-t.y*s;return i.y=t.x*s+t.y*n,i.x=r,i},i.rotateAbout=function(t,e,i,n){var s=Math.cos(e),r=Math.sin(e);n=n||{};var o=i.x+((t.x-i.x)*s-(t.y-i.y)*r);return n.y=i.y+((t.x-i.x)*r+(t.y-i.y)*s),n.x=o,n},i.normalise=function(t){var e=i.magnitude(t);return 0===e?{x:0,y:0}:{x:t.x/e,y:t.y/e}},i.dot=function(t,e){return t.x*e.x+t.y*e.y},i.cross=function(t,e){return t.x*e.y-t.y*e.x},i.cross3=function(t,e,i){return(e.x-t.x)*(i.y-t.y)-(e.y-t.y)*(i.x-t.x)},i.add=function(t,e,i){return(i=i||{}).x=t.x+e.x,i.y=t.y+e.y,i},i.sub=function(t,e,i){return(i=i||{}).x=t.x-e.x,i.y=t.y-e.y,i},i.mult=function(t,e){return{x:t.x*e,y:t.y*e}},i.div=function(t,e){return{x:t.x/e,y:t.y/e}},i.perp=function(t,e){return{x:(e=!0===e?-1:1)*-t.y,y:e*t.x}},i.neg=function(t){return{x:-t.x,y:-t.y}},i.angle=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},i._temp=[i.create(),i.create(),i.create(),i.create(),i.create(),i.create()]},function(t,e){var i={};(t.exports=i).create=function(t){var e={min:{x:0,y:0},max:{x:0,y:0}};return t&&i.update(e,t),e},i.update=function(t,e,i){t.min.x=1/0,t.max.x=-1/0,t.min.y=1/0,t.max.y=-1/0;for(var n=0;nt.max.x&&(t.max.x=s.x),s.xt.max.y&&(t.max.y=s.y),s.y=t.min.x&&e.x<=t.max.x&&e.y>=t.min.y&&e.y<=t.max.y},i.overlaps=function(t,e){return t.min.x<=e.max.x&&t.max.x>=e.min.x&&t.max.y>=e.min.y&&t.min.y<=e.max.y},i.translate=function(t,e){t.min.x+=e.x,t.max.x+=e.x,t.min.y+=e.y,t.max.y+=e.y},i.shift=function(t,e){var i=t.max.x-t.min.x,n=t.max.y-t.min.y;t.min.x=e.x,t.max.x=e.x+i,t.min.y=e.y,t.max.y=e.y+n}},function(t,e){t.exports=function(t,e,i){return 0<=t&&t=this.firstgid&&th.getTotalFrames()&&(s=0),r=h.frames[s],0!==s||this.forward||(r=h.getLastFrame()),this.currentFrame=r):console.warn("Missing animation: "+a),this.parent},pause:function(t){return this._paused||(this._paused=!0,this._wasPlaying=this.isPlaying,this.isPlaying=!1),void 0!==t&&this.setCurrentFrame(t),this.parent},resume:function(t){return this._paused&&(this._paused=!1,this.isPlaying=this._wasPlaying),void 0!==t&&this.setCurrentFrame(t),this.parent},playAfterDelay:function(t,e){var i,n;return this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e):(this.delayCounter=e,this.play(t,!0)),this.parent},playAfterRepeat:function(t,e){var i,n;return void 0===e&&(e=1),this.isPlaying?(i=this.nextAnim,n=this.nextAnimsQueue,i&&n.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e):this.play(t),this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,n=this.parent,s="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===s)return n;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(0this.repeatCounter&&(t=this.repeatCounter),this._pendingStop=2,this._pendingStopValue=t,this.parent},stopOnFrame:function(t){return this._pendingStop=3,this._pendingStopValue=t,this.parent},getTotalFrames:function(){return this.currentAnim?this.currentAnim.getTotalFrames():0},update:function(t,e){var i=this.currentAnim;if(this.isPlaying&&i&&!i.paused){if(this.accumulator+=e*this.timeScale,1===this._pendingStop&&(this._pendingStopValue-=e,this._pendingStopValue<=0))return this.stop();if(this.hasStarted){if(this.accumulator>=this.nextTick&&(this.forward?i.nextFrame(this):i.previousFrame(this),this.isPlaying&&0===this._pendingStop&&this.skipMissedFrames&&this.accumulator>this.nextTick))for(var n=0;this.forward?i.nextFrame(this):i.previousFrame(this),n++,this.accumulator>this.nextTick&&n<60;);}else this.accumulator>=this.delayCounter&&(this.accumulator-=this.delayCounter,this.handleStart())}},setCurrentFrame:function(t){var e=this.parent;return this.currentFrame=t,e.texture=t.frame.texture,e.frame=t.frame,e.isCropped&&e.frame.updateCropUVs(e._crop,e.flipX,e.flipY),t.setAlpha&&(e.alpha=t.alpha),e.setSizeToFrame(),e._originComponent&&(t.frame.customPivot?e.setOrigin(t.frame.pivotX,t.frame.pivotY):e.updateDisplayOrigin()),this.isPlaying&&this.hasStarted&&(this.emitEvents(r.ANIMATION_UPDATE),3===this._pendingStop&&this._pendingStopValue===t&&this.stop()),e},nextFrame:function(){return this.currentAnim&&this.currentAnim.nextFrame(this),this.parent},previousFrame:function(){return this.currentAnim&&this.currentAnim.previousFrame(this),this.parent},get:function(t){return this.anims?this.anims.get(t):null},exists:function(t){return!!this.anims&&this.anims.has(t)},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))||(i=new o(this,e,t),this.anims||(this.anims=new s),this.anims.set(e,i))),i},generateFrameNames:function(t,e){return this.animationManager.generateFrameNames(t,e)},generateFrameNumbers:function(t,e){return this.animationManager.generateFrameNumbers(t,e)},remove:function(t){var e=this.get(t);return e&&(this.currentAnim===e&&this.stop(),this.anims.delete(t)),e},destroy:function(){this.animationManager.off(r.REMOVE_ANIMATION,this.globalRemove,this),this.anims&&this.anims.clear(),this.animationManager=null,this.parent=null,this.nextAnim=null,this.nextAnimsQueue.length=0,this.currentAnim=null,this.currentFrame=null},isPaused:{get:function(){return this._paused}}});t.exports=a},function(t,e,i){var c={};t.exports=c;var o=i(268),r=i(50),a=i(117),d=i(71);c.create=function(t){return r.extend({id:r.nextId(),type:"composite",parent:null,isModified:!1,bodies:[],constraints:[],composites:[],label:"Composite",plugin:{}},t)},c.setModified=function(t,e,i,n){if(o.trigger(t,"compositeModified",t),t.isModified=e,i&&t.parent&&c.setModified(t.parent,e,i,n),n)for(var s=0;s=(t=t.toString()).length)switch(n){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((s=e-t.length)/2);t=new Array(1+(s-r)).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},function(t,e,i){var n=i(321),s=i(186),r=i(325),o=i(326);t.exports=function(t){switch(typeof t){case"string":return("rgb"===t.substr(0,3).toLowerCase()?o:n)(t);case"number":return s(t);case"object":return r(t)}}},function(t,e,i){var a=i(100);function h(t,e,i,n){var s=(t+6*e)%6,r=Math.min(s,4-s,1);return Math.round(255*(n-n*i*Math.max(0,r)))}t.exports=function(t,e,i,n){void 0===e&&(e=1),void 0===i&&(i=1);var s=h(5,t,e,i),r=h(3,t,e,i),o=h(1,t,e,i);return n?n.setTo?n.setTo(s,r,o,n.alpha,!1):(n.r=s,n.g=r,n.b=o,n.color=a(s,r,o),n):{r:s,g:r,b:o,color:a(s,r,o)}}},function(t,e,i){var n=i(36),s=i(324);t.exports=function(t){var e=s(t);return new n(e.r,e.g,e.b,e.a)}},function(t,e){t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},function(t,e,i){var n=i(102),r=i(134),o=i(31),a={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){a.canvas=!!window.CanvasRenderingContext2D;try{a.localStorage=!!localStorage.getItem}catch(t){a.localStorage=!1}a.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),a.fileSystem=!!window.requestFileSystem;var t,e,i,s=!1;return a.webGL=function(){if(window.WebGLRenderingContext)try{var t=o.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=o.create2D(this),n=i.getContext("2d").createImageData(1,1);return s=n.data instanceof Uint8ClampedArray,o.remove(t),o.remove(i),!!e}catch(t){return!1}return!1}(),a.worker=!!window.Worker,a.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia||navigator.oGetUserMedia,window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL,a.getUserMedia=a.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,r.firefox&&r.firefoxVersion<21&&(a.getUserMedia=!1),!n.iOS&&(r.ie||r.firefox||r.chrome)&&(a.canvasBitBltShift=!0),(r.safari||r.mobileSafari)&&(a.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(a.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(a.littleEndian=(t=new ArrayBuffer(4),e=new Uint8Array(t),i=new Uint32Array(t),e[0]=161,e[1]=178,e[2]=195,e[3]=212,3569595041===i[0]||2712847316!==i[0]&&null)),a.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==a.littleEndian&&s,a}()},function(t,e){var i="";function n(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;in.width&&(t=n.width-s.cutX),s.cutY+e>n.height&&(e=n.height-s.cutY),s.setSize(t,e,s.cutX,s.cutY)),this.updateDisplayOrigin();var r=this.input;return r&&!r.customHitArea&&(r.hitArea.width=t,r.hitArea.height=e),this},setGlobalTint:function(t){return this.globalTint=t,this},setGlobalAlpha:function(t){return this.globalAlpha=t,this},saveTexture:function(t){return this.textureManager.renameTexture(this.texture.key,t),this._saved=!0,this.texture},fill:function(t,e,i,n,s,r){var o=this.frame,a=this.camera,h=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=o.cutWidth),void 0===r&&(r=o.cutHeight);var l,u,c,d,f,p,g=(t>>16&255)/255,v=(t>>8&255)/255,m=(255&t)/255,y=this.renderTarget;return a.preRender(),y?(y.bind(!0),(l=this.pipeline).manager.set(l),u=y.width,c=y.height,d=h.width/u,f=h.height/c,l.drawFillRect(i*d,n*f,s*d,r*f,x.getTintFromFloats(m,v,g,1),e),y.unbind(!0)):(p=this.context,h.setContext(p),p.fillStyle="rgba("+g+","+v+","+m+","+e+")",p.fillRect(i+o.cutX,n+o.cutY,s,r),h.setContext()),this.dirty=!0,this},clear:function(){var t,e;return this.dirty&&((t=this.renderTarget)?t.clear():((e=this.context).save(),e.setTransform(1,0,0,1,0,0),e.clearRect(this.frame.cutX,this.frame.cutY,this.frame.cutWidth,this.frame.cutHeight),e.restore()),this.dirty=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i,1,16777215),this._eraseMode=!1,this},draw:function(t,e,i,n,s){return this.beginDraw(),this.batchDraw(t,e,i,n,s),this.endDraw(),this},drawFrame:function(t,e,i,n,s,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,n,s,r),this.endDraw(),this},beginDraw:function(){var t=this.camera,e=this.renderer,i=this.renderTarget;return t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this},batchDraw:function(t,e,i,n,s){return void 0===n&&(n=this.globalAlpha),s=void 0===s?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(s>>16)+(65280&s)+((255&s)<<16),Array.isArray(t)||(t=[t]),this.batchList(t,e,i,n,s),this},batchDrawFrame:function(t,e,i,n,s,r){void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=this.globalAlpha),r=void 0===r?(this.globalTint>>16)+(65280&this.globalTint)+((255&this.globalTint)<<16):(r>>16)+(65280&r)+((255&r)<<16);var o=this.textureManager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,n,r,s,this.camera.matrix,null):this.batchTextureFrame(o,i+this.frame.cutX,n+this.frame.cutY,s,r)),this},endDraw:function(){var t,e=this.renderer,i=this.renderTarget;return i?(t=e.endCapture(),e.pipelines.setUtility().blitFrame(t,i,1,!1,!1,this._eraseMode),e.resetScissor(),e.resetViewport()):e.setContext(),this.dirty=!0,this},batchList:function(t,e,i,n,s){for(var r=0;rs&&(r=t[s]),n[s]=r,t.length>s+1&&(r=t[s+1]),n[s+1]=r;return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(r=0;rn&&(s=t[n]),i[n]=s,t.length>n+1&&(s=t[n+1]),i[n+1]=s;return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var n,s,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,s=this.frame.width/(o-1),n=0;n=this._markerOut&&(e.loop?(e.currentTime=this._markerIn,this.updateTexture(),this._lastUpdate=t,this.emit(o.VIDEO_LOOP,this)):(this.emit(o.VIDEO_COMPLETE,this),this.stop())))},checkVideoProgress:function(){2<=this.video.readyState?this.updateTexture():(this.retry--,0e._dx?r<(s=t.right-e.x)&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?s=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxe._dy?r<(s=t.bottom-e.y)&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?s=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==o.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==o.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dy=t.right||e.position.y>=t.bottom)}},function(t,e,i){var w={};t.exports=w;var o=i(94),b=i(116),a=i(267),h=i(117),l=i(585),u=i(50);w._warming=.4,w._torqueDampen=1,w._minLength=1e-6,w.create=function(t){var e=t;e.bodyA&&!e.pointA&&(e.pointA={x:0,y:0}),e.bodyB&&!e.pointB&&(e.pointB={x:0,y:0});var i=e.bodyA?b.add(e.bodyA.position,e.pointA):e.pointA,n=e.bodyB?b.add(e.bodyB.position,e.pointB):e.pointB,s=b.magnitude(b.sub(i,n));e.length=void 0!==e.length?e.length:s,e.id=e.id||u.nextId(),e.label=e.label||"Constraint",e.type="constraint",e.stiffness=e.stiffness||(0t&&(t=s.totalDuration),s.delay=o.sleepThreshold&&u.set(o,!0)):0u._motionWakeThreshold*i&&u.set(a,!1)))}},u.set=function(t,e){var i=t.isSleeping;e?(t.isSleeping=!0,t.sleepCounter=t.sleepThreshold,t.positionImpulse.x=0,t.positionImpulse.y=0,t.positionPrev.x=t.position.x,t.positionPrev.y=t.position.y,t.anglePrev=t.angle,t.speed=0,t.angularSpeed=0,t.motion=0,i||n.trigger(t,"sleepStart")):(t.isSleeping=!1,t.sleepCounter=0,i&&n.trigger(t,"sleepEnd"))}},function(t,e,i){var n={};t.exports=n;var u=i(50);n.on=function(t,e,i){for(var n,s=e.split(" "),r=0;r=t.right&&(o=1,r+=s-t.right,s=t.right);break;case 1:(r+=e)>=t.bottom&&(o=2,s-=r-t.bottom,r=t.bottom);break;case 2:(s-=e)<=t.left&&(o=3,r-=t.left-s,s=t.left);break;case 3:(r-=e)<=t.top&&(o=0,r=t.top)}return n}},function(t,e){t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var n=Math.round(t.x1),s=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-n),h=Math.abs(o-s),l=ne.length&&(r=e.length),i?(n=e[r-1][i],(s=e[r][i])-t<=t-n?e[r]:e[r-1]):(n=e[r-1],(s=e[r])-t<=t-n?s:n)}},function(t,e,i){var n=new(i(0))({initialize:function(t,e,i,n,s){void 0===s&&(s=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=n,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=s},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=n},function(t,e){t.exports=function(t){var i=/\D/g;return t.sort(function(t,e){return parseInt(t.replace(i,""),10)-parseInt(e.replace(i,""),10)}),t}},function(t,e,i){var n=i(182),s=i(0),r=i(99),o=i(9),a=i(130),h=i(22),T=i(2),d=i(6),f=i(183),p=i(316),l=new s({Extends:o,initialize:function(t){o.call(this),this.game=t,this.textureManager=null,this.globalTimeScale=1,this.anims=new r,this.mixes=new r,this.paused=!1,this.name="AnimationManager",t.events.once(h.BOOT,this.boot,this)},boot:function(){this.textureManager=this.game.textures,this.game.events.once(h.DESTROY,this.destroy,this)},addMix:function(t,e,i){var n,s=this.anims,r=this.mixes,o="string"==typeof t?t:t.key,a="string"==typeof e?e:e.key;return s.has(o)&&s.has(a)&&((n=(n=r.get(o))||{})[a]=i,r.set(o,n)),this},removeMix:function(t,e){var i,n=this.mixes,s="string"==typeof t?t:t.key,r=n.get(s);return r&&(e?(i="string"==typeof e?e:e.key,r.hasOwnProperty(i)&&delete r[i]):e||n.delete(s)),this},getMix:function(t,e){var i=this.mixes,n="string"==typeof t?t:t.key,s="string"==typeof e?e:e.key,r=i.get(n);return r&&r.hasOwnProperty(s)?r[s]:0},add:function(t,e){return this.anims.has(t)?console.warn("Animation key exists: "+t):(e.key=t,this.anims.set(t,e),this.emit(a.ADD_ANIMATION,t,e)),this},exists:function(t){return this.anims.has(t)},createFromAseprite:function(g,v){var m=[],t=this.game.cache.json.get(g);if(!t)return m;var y=this,e=d(t,"meta",null),x=d(t,"frames",null);return e&&x&&d(e,"frameTags",[]).forEach(function(t){var e=[],i=T(t,"name",null),n=T(t,"from",0),s=T(t,"to",0),r=T(t,"direction","forward");if(i&&(!v||v&&-1l.right&&(u=E(u,u+(d-l.right),this.lerp.x)),fl.bottom&&(c=E(c,c+(f-l.bottom),this.lerp.y))):(u=E(u,d-o,this.lerp.x),c=E(c,f-a,this.lerp.y)),p=!0),this.useBounds&&(u=this.clampX(u),c=this.clampY(c)),this.roundPixels&&(o=Math.round(o),a=Math.round(a),u=Math.round(u),c=Math.round(c));var g=(this.scrollX=u)+i,v=(this.scrollY=c)+n;this.midPoint.set(g,v);var m=t/s,y=e/s,x=g-m/2,T=v-y/2;this.roundPixels&&(x=Math.round(x),T=Math.round(T)),this.worldView.setTo(x,T,m,y),r.applyITRS(this.x+o,this.y+a,this.rotation,s,s),r.translate(-o,-a),this.shakeEffect.preRender(),p&&this.emit(b.FOLLOW_UPDATE,this,h)},setLerp:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.lerp.set(t,e),this},setFollowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=0),this.followOffset.set(t,e),this},startFollow:function(t,e,i,n,s,r){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===n&&(n=i),void 0===s&&(s=0),void 0===r&&(r=s),this._follow=t,this.roundPixels=e,i=u(i,0,1),n=u(n,0,1),this.lerp.set(i,n),this.followOffset.set(s,r);var o=this.width/2,a=this.height/2,h=t.x-s,l=t.y-r;return this.midPoint.set(h,l),this.scrollX=h-o,this.scrollY=l-a,this.useBounds&&(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},stopFollow:function(){return this._follow=null,this},resetFX:function(){return this.rotateToEffect.reset(),this.panEffect.reset(),this.shakeEffect.reset(),this.flashEffect.reset(),this.fadeEffect.reset(),this},update:function(t,e){this.visible&&(this.rotateToEffect.update(t,e),this.panEffect.update(t,e),this.zoomEffect.update(t,e),this.shakeEffect.update(t,e),this.flashEffect.update(t,e),this.fadeEffect.update(t,e))},destroy:function(){this.resetFX(),s.prototype.destroy.call(this),this._follow=null,this.deadzone=null}});t.exports=l},function(t,e,i){var o=i(36);t.exports=function(t){var e=new o;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,function(t,e,i,n){return e+e+i+i+n+n});var i,n,s,r=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r&&(i=parseInt(r[1],16),n=parseInt(r[2],16),s=parseInt(r[3],16),e.setTo(i,n,s)),e}},function(t,e){t.exports=function(t,e,i,n){return n<<24|t<<16|e<<8|i}},function(t,e){t.exports=function(t,e,i,n){void 0===n&&(n={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var s=Math.min(t,e,i),r=Math.max(t,e,i),o=r-s,a=0,h=0===r?0:o/r,l=r;return r!==s&&(r===t?a=(e-i)/o+(e>>24,r:t>>16&255,g:t>>8&255,b:255&t}:{a:255,r:t>>16&255,g:t>>8&255,b:255&t}}},function(t,e,i){var n=i(36);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(36);t.exports=function(t){var e,i,n,s,r=new a,o=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());return o&&(e=parseInt(o[1],10),i=parseInt(o[2],10),n=parseInt(o[3],10),s=void 0!==o[4]?parseFloat(o[4]):1,r.setTo(e,i,n,255*s)),r}},function(t,e,i){t.exports={Fade:i(737),Flash:i(738),Pan:i(739),Shake:i(772),RotateTo:i(773),Zoom:i(774)}},function(t,e,i){t.exports={In:i(740),Out:i(741),InOut:i(742)}},function(t,e,i){t.exports={In:i(743),Out:i(744),InOut:i(745)}},function(t,e,i){t.exports={In:i(746),Out:i(747),InOut:i(748)}},function(t,e,i){t.exports={In:i(749),Out:i(750),InOut:i(751)}},function(t,e,i){t.exports={In:i(752),Out:i(753),InOut:i(754)}},function(t,e,i){t.exports={In:i(755),Out:i(756),InOut:i(757)}},function(t,e,i){t.exports=i(758)},function(t,e,i){t.exports={In:i(759),Out:i(760),InOut:i(761)}},function(t,e,i){t.exports={In:i(762),Out:i(763),InOut:i(764)}},function(t,e,i){t.exports={In:i(765),Out:i(766),InOut:i(767)}},function(t,e,i){t.exports={In:i(768),Out:i(769),InOut:i(770)}},function(t,e,i){t.exports=i(771)},function(t,e,i){var n=i(0),h=i(39),l=i(341),u=i(2),c=i(6),d=i(7),f=i(190),p=i(1),g=i(194),v=i(184),s=new n({initialize:function(t){void 0===t&&(t={});this.width=c(t,"width",1024),this.height=c(t,"height",768),this.zoom=c(t,"zoom",1),this.parent=c(t,"parent",void 0),this.scaleMode=c(t,"scaleMode",0),this.expandParent=c(t,"expandParent",!0),this.autoRound=c(t,"autoRound",!1),this.autoCenter=c(t,"autoCenter",0),this.resizeInterval=c(t,"resizeInterval",500),this.fullscreenTarget=c(t,"fullscreenTarget",null),this.minWidth=c(t,"minWidth",0),this.maxWidth=c(t,"maxWidth",0),this.minHeight=c(t,"minHeight",0),this.maxHeight=c(t,"maxHeight",0);var e=c(t,"scale",null);e&&(this.width=c(e,"width",this.width),this.height=c(e,"height",this.height),this.zoom=c(e,"zoom",this.zoom),this.parent=c(e,"parent",this.parent),this.scaleMode=c(e,"mode",this.scaleMode),this.expandParent=c(e,"expandParent",this.expandParent),this.autoRound=c(e,"autoRound",this.autoRound),this.autoCenter=c(e,"autoCenter",this.autoCenter),this.resizeInterval=c(e,"resizeInterval",this.resizeInterval),this.fullscreenTarget=c(e,"fullscreenTarget",this.fullscreenTarget),this.minWidth=c(e,"min.width",this.minWidth),this.maxWidth=c(e,"max.width",this.maxWidth),this.minHeight=c(e,"min.height",this.minHeight),this.maxHeight=c(e,"max.height",this.maxHeight)),this.renderType=c(t,"type",h.AUTO),this.canvas=c(t,"canvas",null),this.context=c(t,"context",null),this.canvasStyle=c(t,"canvasStyle",null),this.customEnvironment=c(t,"customEnvironment",!1),this.sceneConfig=c(t,"scene",null),this.seed=c(t,"seed",[(Date.now()*Math.random()).toString()]),f.RND=new f.RandomDataGenerator(this.seed),this.gameTitle=c(t,"title",""),this.gameURL=c(t,"url","https://phaser.io"),this.gameVersion=c(t,"version",""),this.autoFocus=c(t,"autoFocus",!0),this.domCreateContainer=c(t,"dom.createContainer",!1),this.domBehindCanvas=c(t,"dom.behindCanvas",!1),this.inputKeyboard=c(t,"input.keyboard",!0),this.inputKeyboardEventTarget=c(t,"input.keyboard.target",window),this.inputKeyboardCapture=c(t,"input.keyboard.capture",[]),this.inputMouse=c(t,"input.mouse",!0),this.inputMouseEventTarget=c(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=c(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=c(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=c(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=c(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=c(t,"input.touch",l.input.touch),this.inputTouchEventTarget=c(t,"input.touch.target",null),this.inputTouchCapture=c(t,"input.touch.capture",!0),this.inputActivePointers=c(t,"input.activePointers",1),this.inputSmoothFactor=c(t,"input.smoothFactor",0),this.inputWindowEvents=c(t,"input.windowEvents",!0),this.inputGamepad=c(t,"input.gamepad",!1),this.inputGamepadEventTarget=c(t,"input.gamepad.target",window),this.disableContextMenu=c(t,"disableContextMenu",!1),this.audio=c(t,"audio",{}),this.hideBanner=!1===c(t,"banner",null),this.hidePhaser=c(t,"banner.hidePhaser",!1),this.bannerTextColor=c(t,"banner.text","#ffffff"),this.bannerBackgroundColor=c(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=c(t,"fps",null);var i=c(t,"render",t);this.pipeline=c(i,"pipeline",null),this.antialias=c(i,"antialias",!0),this.antialiasGL=c(i,"antialiasGL",!0),this.mipmapFilter=c(i,"mipmapFilter","LINEAR"),this.desynchronized=c(i,"desynchronized",!1),this.roundPixels=c(i,"roundPixels",!1),this.pixelArt=c(i,"pixelArt",1!==this.zoom),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=c(i,"transparent",!1),this.clearBeforeRender=c(i,"clearBeforeRender",!0),this.premultipliedAlpha=c(i,"premultipliedAlpha",!0),this.failIfMajorPerformanceCaveat=c(i,"failIfMajorPerformanceCaveat",!1),this.powerPreference=c(i,"powerPreference","default"),this.batchSize=c(i,"batchSize",4096),this.maxTextures=c(i,"maxTextures",-1),this.maxLights=c(i,"maxLights",10);var n=c(t,"backgroundColor",0);this.backgroundColor=v(n),this.transparent&&(this.backgroundColor=v(0),this.backgroundColor.alpha=0),this.preBoot=c(t,"callbacks.preBoot",p),this.postBoot=c(t,"callbacks.postBoot",p),this.physics=c(t,"physics",{}),this.defaultPhysicsSystem=c(this.physics,"default",!1),this.loaderBaseURL=c(t,"loader.baseURL",""),this.loaderPath=c(t,"loader.path","");var s=l.os.android?6:32;this.loaderMaxParallelDownloads=c(t,"loader.maxParallelDownloads",s),this.loaderCrossOrigin=c(t,"loader.crossOrigin",void 0),this.loaderResponseType=c(t,"loader.responseType",""),this.loaderAsync=c(t,"loader.async",!0),this.loaderUser=c(t,"loader.user",""),this.loaderPassword=c(t,"loader.password",""),this.loaderTimeout=c(t,"loader.timeout",0),this.loaderWithCredentials=c(t,"loader.withCredentials",!1),this.installGlobalPlugins=[],this.installScenePlugins=[];var r=c(t,"plugins",null),o=g.DefaultScene;r&&(Array.isArray(r)?this.defaultPlugins=r:d(r)&&(this.installGlobalPlugins=u(r,"global",[]),this.installScenePlugins=u(r,"scene",[]),Array.isArray(r.default)?o=r.default:Array.isArray(r.defaultMerge)&&(o=o.concat(r.defaultMerge)))),this.defaultPlugins=o;var a="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=c(t,"images.default",a+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=c(t,"images.missing",a+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=c(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=h.WEBGL:window.FORCE_CANVAS&&(this.renderType=h.CANVAS))}});t.exports=s},function(t,e,i){t.exports={os:i(102),browser:i(134),features:i(188),input:i(805),audio:i(806),video:i(807),fullscreen:i(808),canvasFeatures:i(342)}},function(t,e,i){var n,s,r,o=i(31),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=(void 0!==document&&(a.supportNewBlendModes=(n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",s="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var i=new Image;i.onload=function(){var t=o.create(i,6,1).getContext("2d");if(t.globalCompositeOperation="multiply",t.drawImage(r,0,0),t.drawImage(i,2,0),!t.getImageData(2,0,1,1))return!1;var e=t.getImageData(2,0,1,1).data;o.remove(i),a.supportNewBlendModes=255===e[0]&&0===e[1]&&0===e[2]},i.src=n+"/wCKxvRF"+s},r.src=n+"AP804Oa6"+s,!1),a.supportInverseAlpha=function(){var t=o.create(this,2,1).getContext("2d");t.fillStyle="rgba(10, 20, 30, 0.5)",t.fillRect(0,0,1,1);var e=t.getImageData(0,0,1,1);if(null===e)return!1;t.putImageData(e,1,0);var i=t.getImageData(1,0,1,1);return i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3]}()),a)},function(t,e){t.exports=function(t,e,i,n){return Math.atan2(n-e,i-t)}},function(t,e){t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},function(t,e){t.exports=function(t){return 0<=(t%=2*Math.PI)?t:t+2*Math.PI}},function(t,e){t.exports=function(t,e){var i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}},function(t,e){t.exports=function(t,e,i,n){var s=t-i,r=e-n;return s*s+r*r}},function(t,e){t.exports=function(t,e,i){return void 0===i&&(i=1e-4),e-ir[0]&&(e=1),r[8]>r[3*e+e]&&(e=2),i=a[e],n=a[i],s=Math.sqrt(r[3*e+e]-r[3*i+i]-r[3*n+n]+1),h[e]=.5*s,s=.5/s,h[i]=(r[3*i+e]+r[3*e+i])*s,h[n]=(r[3*n+e]+r[3*e+n])*s,this._x=h[0],this._y=h[1],this._z=h[2],this._w=(r[3*n+i]-r[3*i+n])*s),this.onChangeCallback(this),this}});t.exports=f},function(t,e,a){var h=a(361),l=a(31),u=a(39),c=a(188);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===u.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==u.HEADLESS)if(e.renderType===u.CANVAS||e.renderType!==u.CANVAS&&!c.webGL){if(!c.canvas)throw new Error("Cannot create Canvas or WebGL context, aborting.");e.renderType=u.CANVAS}else e.renderType=u.WEBGL;e.antialias||l.disableSmoothing();var i,n,s=t.scale.baseSize,r=s.width,o=s.height;e.canvas?(t.canvas=e.canvas,t.canvas.width=r,t.canvas.height=o):t.canvas=l.create(t,r,o,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||h.setCrisp(t.canvas),e.renderType!==u.HEADLESS&&(i=a(362),n=a(365),e.renderType===u.WEBGL?t.renderer=new n(t):(t.renderer=new i(t),t.context=t.renderer.gameContext))}},function(t,e){t.exports={setCrisp:function(e){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach(function(t){e.style["image-rendering"]=t}),e.style.msInterpolationMode="nearest-neighbor",e},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},function(t,e,i){var d=i(35),u=i(363),n=i(0),s=i(39),r=i(9),f=i(88),o=i(364),a=i(101),h=i(103),l=i(25),c=new n({Extends:r,initialize:function(t){r.call(this);var e=t.config;this.config={clearBeforeRender:e.clearBeforeRender,backgroundColor:e.backgroundColor,antialias:e.antialias,roundPixels:e.roundPixels},this.game=t,this.type=s.CANVAS,this.drawCount=0,this.width=0,this.height=0,this.gameCanvas=t.canvas;var i={alpha:t.config.transparent,desynchronized:t.config.desynchronized};this.gameContext=e.context?e.context:this.gameCanvas.getContext("2d",i),this.currentContext=this.gameContext,this.antialias=t.config.antialias,this.blendModes=o(),this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92},this._tempMatrix1=new l,this._tempMatrix2=new l,this._tempMatrix3=new l,this.isBooted=!1,this.init()},init:function(){this.game.textures.once(h.READY,this.boot,this)},boot:function(){var t=this.game,e=t.scale.baseSize;this.width=e.width,this.height=e.height,this.isBooted=!0,t.scale.on(a.RESIZE,this.onResize,this),this.resize(e.width,e.height)},onResize:function(t,e){e.width===this.width&&e.height===this.height||this.resize(e.width,e.height)},resize:function(t,e){this.width=t,this.height=e,this.emit(f.RESIZE,t,e)},resetTransform:function(){this.currentContext.setTransform(1,0,0,1,0,0)},setBlendMode:function(t){return this.currentContext.globalCompositeOperation=t,this},setContext:function(t){return this.currentContext=t||this.gameContext,this},setAlpha:function(t){return this.currentContext.globalAlpha=t,this},preRender:function(){var t=this.gameContext,e=this.config,i=this.width,n=this.height;t.globalAlpha=1,t.globalCompositeOperation="source-over",t.setTransform(1,0,0,1,0,0),e.clearBeforeRender&&t.clearRect(0,0,i,n),e.transparent||(t.fillStyle=e.backgroundColor.rgba,t.fillRect(0,0,i,n)),t.save(),this.drawCount=0,this.emit(f.PRE_RENDER)},render:function(t,e,i){var n=e.length;this.emit(f.RENDER,t,i);var s=i.x,r=i.y,o=i.width,a=i.height,h=i.renderToTexture?i.context:t.sys.context;h.save(),this.game.scene.customViewports&&(h.beginPath(),h.rect(s,r,o,a),h.clip()),this.currentContext=h;var l=i.mask;l&&l.preRenderCanvas(this,null,i._maskCamera),i.transparent||(h.fillStyle=i.backgroundColor.rgba,h.fillRect(s,r,o,a)),h.globalAlpha=i.alpha,h.globalCompositeOperation="source-over",this.drawCount+=n,i.renderToTexture&&i.emit(d.PRE_RENDER,i),i.matrix.copyToContext(h);for(var u=0;ue.height?(h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e)):(o=e.height-t.height,h.viewport(0,o,t.width,t.height)),h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),n&&(s?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),r&&(a=this.renderer.currentBlendMode,this.renderer.setBlendMode(l.ERASE)),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(a),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),void 0===a&&(a=!0);var h=this.gl;h.bindFramebuffer(h.FRAMEBUFFER,t.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,t.texture,0),o&&(a?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,e.texture),h.copyTexSubImage2D(h.TEXTURE_2D,0,0,0,i,n,s,r),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null)},copyToGame:function(t){var e=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",1),this.renderer.popFramebuffer(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,t.texture),e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.STATIC_DRAW),e.drawArrays(e.TRIANGLES,0,6),this.renderer.resetTextures()},drawFrame:function(t,e,i,n){void 0===i&&(i=!0),void 0===n&&(n=this.colorMatrix);var s=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",n.getData()),this.set1f("uAlpha",n.alpha),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture),e?(s.viewport(0,0,e.width,e.height),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0)):s.viewport(0,0,t.width,t.height),i?s.clearColor(0,0,0,0):s.clearColor(0,0,0,1),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),s.bindFramebuffer(s.FRAMEBUFFER,null),s.bindTexture(s.TEXTURE_2D,null)},blendFrames:function(t,e,i,n,s,r){void 0===n&&(n=1),void 0===s&&(s=!0),void 0===r&&(r=this.linearShader);var o=this.gl;this.setShader(r),this.set1i("uMainSampler1",0),this.set1i("uMainSampler2",1),this.set1f("uStrength",n),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,t.texture),o.activeTexture(o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,e.texture),i?(o.bindFramebuffer(o.FRAMEBUFFER,i.framebuffer),o.framebufferTexture2D(o.FRAMEBUFFER,o.COLOR_ATTACHMENT0,o.TEXTURE_2D,i.texture,0),o.viewport(0,0,i.width,i.height)):o.viewport(0,0,t.width,t.height),s?o.clearColor(0,0,0,0):o.clearColor(0,0,0,1),o.clear(o.COLOR_BUFFER_BIT),o.bufferData(o.ARRAY_BUFFER,this.vertexData,o.STATIC_DRAW),o.drawArrays(o.TRIANGLES,0,6),o.bindFramebuffer(o.FRAMEBUFFER,null),o.bindTexture(o.TEXTURE_2D,null)},blendFramesAdditive:function(t,e,i,n,s){this.blendFrames(t,e,i,n,s,this.addShader)},clearFrame:function(t,e){void 0===e&&(e=!0);var i=this.gl;i.viewport(0,0,t.width,t.height),i.bindFramebuffer(i.FRAMEBUFFER,t.framebuffer),e?i.clearColor(0,0,0,0):i.clearColor(0,0,0,1),i.clear(i.COLOR_BUFFER_BIT);var n=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,n)},setUVs:function(t,e,i,n,s,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=n,h[10]=s,h[11]=r,h[14]=t,h[15]=e,h[18]=s,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=.5<(i=e.height/t.height)?.5-(i-.5):.5-i+.5;this.setUVs(0,i,0,1+i,1,1+i,1,i)},flipX:function(){this.setUVs(1,0,1,1,0,1,0,0)},flipY:function(){this.setUVs(0,1,0,0,1,0,1,1)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)}});t.exports=f},function(t,e){t.exports=["#define SHADER_NAME PHASER_QUAD_VS","","precision mediump float;","","attribute vec2 inPosition;","attribute vec2 inTexCoord;","","varying vec2 outFragCoord;","varying vec2 outTexCoord;","","void main ()","{"," outFragCoord = inPosition.xy * 0.5 + 0.5;"," outTexCoord = inTexCoord;",""," gl_Position = vec4(inPosition, 0, 1);","}",""].join("\n")},function(t,e,i){var _=i(31),C=i(36),M=i(2);t.exports=function(t,e){var i=t.getContext("experimental-webgl"),n=M(e,"callback"),s=M(e,"type","image/png"),r=M(e,"encoder",.92),o=M(e,"x",0),a=M(e,"y",0),h=M(e,"getPixel",!1),l=M(e,"isFramebuffer",!1),u=l?M(e,"bufferWidth",1):i.drawingBufferWidth,c=l?M(e,"bufferHeight",1):i.drawingBufferHeight;if(h){var d=new Uint8Array(4),f=l?a:c-a;i.readPixels(o,f,1,1,i.RGBA,i.UNSIGNED_BYTE,d),n.call(null,new C(d[0],d[1],d[2],d[3]/255))}else{var p=M(e,"width",u),g=M(e,"height",c),v=new Uint8Array(p*g*4);i.readPixels(o,c-a-g,p,g,i.RGBA,i.UNSIGNED_BYTE,v);for(var m=_.createWebGL(this,p,g),y=m.getContext("2d"),x=y.getImageData(0,0,p,g),T=x.data,w=0;wthis._min&&(r=n[i],r=Math.min(r,this._min)),n[i]=r,this.deltaIndex++,this.deltaIndex>s&&(this.deltaIndex=0);for(var a=o=0;athis.nextFpsUpdate&&(this.actualFps=.25*this.framesThisSecond+.75*this.actualFps,this.nextFpsUpdate=t+1e3,this.framesThisSecond=0),this.framesThisSecond++;var h=o/this._target;this.callback(t,o,h),this.lastTime=t,this.frame++},tick:function(){this.step()},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){this.running||(t&&(this.startTime+=-this.lastTime+(this.lastTime+window.performance.now())),this.raf.start(this.step.bind(this),this.useRAF),this.running=!0,this.step())},getDuration:function(){return Math.round(this.lastTime-this.startTime)/1e3},getDurationMS:function(){return Math.round(this.lastTime-this.startTime)},stop:function(){return this.running=!1,this.started=!1,this.raf.stop(),this},destroy:function(){this.stop(),this.callback=r,this.raf=null,this.game=null}});t.exports=a},function(t,e,i){var n=i(0),s=i(1),r=new n({initialize:function(){this.isRunning=!1,this.callback=s,this.tick=0,this.isSetTimeOut=!1,this.timeOutID=null,this.lastTime=0,this.target=0;var n=this;this.step=function t(){var e=window.performance.now();n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.requestAnimationFrame(t)},this.stepTimeout=function t(){var e=Date.now(),i=Math.min(Math.max(2*n.target+n.tick-e,0),n.target);n.lastTime=n.tick,n.tick=e,n.callback(e),n.timeOutID=window.setTimeout(t,i)}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.target=i,this.isRunning=!0,this.timeOutID=e?window.setTimeout(this.stepTimeout,0):window.requestAnimationFrame(this.step))},stop:function(){this.isRunning=!1,this.isSetTimeOut?clearTimeout(this.timeOutID):window.cancelAnimationFrame(this.timeOutID)},destroy:function(){this.stop(),this.callback=s}});t.exports=r},function(t,e,i){var n=i(22);t.exports=function(t){var e,i=t.events;void 0!==document.hidden?e="visibilitychange":["webkit","moz","ms"].forEach(function(t){void 0!==document[t+"Hidden"]&&(document.hidden=function(){return document[t+"Hidden"]},e=t+"visibilitychange")});e&&document.addEventListener(e,function(t){document.hidden||"pause"===t.type?i.emit(n.HIDDEN):i.emit(n.VISIBLE)},!1),window.onblur=function(){i.emit(n.BLUR)},window.onfocus=function(){i.emit(n.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},function(t,e,i){var m=i(383),y=i(31),x=i(6);t.exports=function(t){var e=x(t,"data",[]),i=x(t,"canvas",null),n=x(t,"palette",m),s=x(t,"pixelWidth",1),r=x(t,"pixelHeight",s),o=x(t,"resizeCanvas",!0),a=x(t,"clearCanvas",!0),h=x(t,"preRender",null),l=x(t,"postRender",null),u=Math.floor(Math.abs(e[0].length*s)),c=Math.floor(Math.abs(e.length*r));i||(i=y.create2D(this,u,c),a=o=!1),o&&(i.width=u,i.height=c);var d=i.getContext("2d");a&&d.clearRect(0,0,u,c),h&&h(i,d);for(var f=0;fi.length-2?i.length-1:s+1],l=i[s>i.length-3?i.length-1:s+2];return e.set(u(r,o.x,a.x,h.x,l.x),u(r,o.y,a.y,h.y,l.y))},toJSON:function(){for(var t=[],e=0;ethis.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var e=this.listeners;window.removeEventListener("orientationchange",e.orientationChange,!1),window.removeEventListener("resize",e.windowResize,!1);["webkit","moz",""].forEach(function(t){document.removeEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.removeEventListener(t+"fullscreenerror",e.fullScreenError,!1)}),document.removeEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",e.fullScreenError,!1)},destroy:function(){this.removeAllListeners(),this.stopListeners(),this.game=null,this.canvas=null,this.canvasBounds=null,this.parent=null,this.fullscreenTarget=null,this.parentSize.destroy(),this.gameSize.destroy(),this.baseSize.destroy(),this.displaySize.destroy()},isFullscreen:{get:function(){return this.fullscreen.active}},width:{get:function(){return this.gameSize.width}},height:{get:function(){return this.gameSize.height}},isPortrait:{get:function(){return this.orientation===u.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===u.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=v},function(t,e,i){var n=i(18),s=i(0),r=i(76),o=i(3),a=new s({initialize:function(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===n&&(n=null),this._width=t,this._height=e,this._parent=n,this.aspectMode=i,this.aspectRatio=0===e?1:t/e,this.minWidth=0,this.minHeight=0,this.maxWidth=Number.MAX_VALUE,this.maxHeight=Number.MAX_VALUE,this.snapTo=new o},setAspectMode:function(t){return void 0===t&&(t=0),this.aspectMode=t,this.setSize(this._width,this._height)},setSnap:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.snapTo.set(t,e),this.setSize(this._width,this._height)},setParent:function(t){return this._parent=t,this.setSize(this._width,this._height)},setMin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.minWidth=n(t,0,this.maxWidth),this.minHeight=n(e,0,this.maxHeight),this.setSize(this._width,this._height)},setMax:function(t,e){return void 0===t&&(t=Number.MAX_VALUE),void 0===e&&(e=t),this.maxWidth=n(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=n(e,this.minHeight,Number.MAX_VALUE),this.setSize(this._width,this._height)},setSize:function(t,e){switch(void 0===t&&(t=0),void 0===e&&(e=t),this.aspectMode){case a.NONE:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height;break;case a.WIDTH_CONTROLS_HEIGHT:this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(this._width*(1/this.aspectRatio),!1);break;case a.HEIGHT_CONTROLS_WIDTH:this._height=this.getNewHeight(r(e,this.snapTo.y)),this._width=this.getNewWidth(this._height*this.aspectRatio,!1);break;case a.FIT:this.constrain(t,e,!0);break;case a.ENVELOP:this.constrain(t,e,!1)}return this},setAspectRatio:function(t){return this.aspectRatio=t,this.setSize(this._width,this._height)},resize:function(t,e){return this._width=this.getNewWidth(r(t,this.snapTo.x)),this._height=this.getNewHeight(r(e,this.snapTo.y)),this.aspectRatio=0===this._height?1:this._width/this._height,this},getNewWidth:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minWidth,this.maxWidth),e&&this._parent&&t>this._parent.width&&(t=Math.max(this.minWidth,this._parent.width)),t},getNewHeight:function(t,e){return void 0===e&&(e=!0),t=n(t,this.minHeight,this.maxHeight),e&&this._parent&&t>this._parent.height&&(t=Math.max(this.minHeight,this._parent.height)),t},constrain:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=!0),t=this.getNewWidth(t),e=this.getNewHeight(e);var n=this.snapTo,s=0===e?1:t/e;return i&&this.aspectRatio>s||!i&&this.aspectRatios)&&(t=(e=r(e,n.y))*this.aspectRatio,0r.START&&n.settings.status<=r.RUNNING&&n.step(t,e)}},render:function(t){for(var e=0;e=r.LOADING&&i.settings.status=r.x&&t=r.y&&e=r.x&&t=r.y&&e=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,n-i),n=this.audio.currentTime):n>4,l[a++]=(15&i)<<4|n>>2,l[a++]=(3&n)<<6|63&s;return h}},function(t,e,i){var n=i(145),s=i(0),r=i(69),o=new s({Extends:n,initialize:function(t,e,i){if(void 0===i&&(i={}),this.audioBuffer=t.game.cache.audio.get(e),!this.audioBuffer)throw new Error('Audio key "'+e+'" missing from cache');this.source=null,this.loopSource=null,this.muteNode=t.context.createGain(),this.volumeNode=t.context.createGain(),this.pannerNode=null,this.playTime=0,this.startTime=0,this.loopTime=0,this.rateUpdates=[],this.hasEnded=!1,this.hasLooped=!1,this.muteNode.connect(this.volumeNode),t.context.createStereoPanner?(this.pannerNode=t.context.createStereoPanner(),this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination)):this.volumeNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,n.call(this,t,e,i)},play:function(t,e){return!!n.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime>>16,g=(65280&c)>>>8,v=255&c,h.strokeStyle="rgba("+p+","+g+","+v+","+l+")",h.lineWidth=f,m+=3;break;case y.FILL_STYLE:d=o[m+1],u=o[m+2],p=(16711680&d)>>>16,g=(65280&d)>>>8,v=255&d,h.fillStyle="rgba("+p+","+g+","+v+","+u+")",m+=2;break;case y.BEGIN_PATH:h.beginPath();break;case y.CLOSE_PATH:h.closePath();break;case y.FILL_PATH:r||h.fill();break;case y.STROKE_PATH:r||h.stroke();break;case y.FILL_RECT:r?h.rect(o[m+1],o[m+2],o[m+3],o[m+4]):h.fillRect(o[m+1],o[m+2],o[m+3],o[m+4]),m+=4;break;case y.FILL_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.fill(),m+=6;break;case y.STROKE_TRIANGLE:h.beginPath(),h.moveTo(o[m+1],o[m+2]),h.lineTo(o[m+3],o[m+4]),h.lineTo(o[m+5],o[m+6]),h.closePath(),r||h.stroke(),m+=6;break;case y.LINE_TO:h.lineTo(o[m+1],o[m+2]),m+=2;break;case y.MOVE_TO:h.moveTo(o[m+1],o[m+2]),m+=2;break;case y.LINE_FX_TO:h.lineTo(o[m+1],o[m+2]),m+=5;break;case y.MOVE_FX_TO:h.moveTo(o[m+1],o[m+2]),m+=5;break;case y.SAVE:h.save();break;case y.RESTORE:h.restore();break;case y.TRANSLATE:h.translate(o[m+1],o[m+2]),m+=2;break;case y.SCALE:h.scale(o[m+1],o[m+2]),m+=2;break;case y.ROTATE:h.rotate(o[m+1]),m+=1;break;case y.GRADIENT_FILL_STYLE:m+=5;break;case y.GRADIENT_LINE_STYLE:m+=6}}h.restore()}}},function(t,e,i){var n=i(0),s=i(135),r=i(80),o=i(2),a=i(66),h=new n({initialize:function(t,e,i,n){void 0===n&&(n=!1),this.propertyKey=e,this.propertyValue=i,this.defaultValue=i,this.steps=0,this.counter=0,this.start=0,this.end=0,this.ease,this.emitOnly=n,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.loadConfig(t)},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=o(t,this.propertyKey,this.defaultValue),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return this.propertyValue},onChange:function(t){return this.propertyValue=t,this.setMethods()},setMethods:function(){var t,e,i,n=this.propertyValue,s=typeof n;return this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,"number"==s?(this.onEmit=this.staticValueEmit,this.onUpdate=this.staticValueUpdate):Array.isArray(n)?this.onEmit=this.randomStaticValueEmit:"function"==s?this.emitOnly?this.onEmit=n:this.onUpdate=n:"object"==s&&this.hasBoth(n,"start","end")?(this.start=n.start,this.end=n.end,(t=this.has(n,"random"))&&(this.onEmit=this.randomRangedValueEmit),this.has(n,"steps")?(this.steps=n.steps,this.counter=this.start,this.onEmit=this.steppedEmit):(e=this.has(n,"ease")?n.ease:"Linear",this.ease=r(e,n.easeParams),t||(this.onEmit=this.easedValueEmit),this.onUpdate=this.easeValueUpdate)):"object"==s&&this.hasBoth(n,"min","max")?(this.start=n.min,this.end=n.max,this.onEmit=this.randomRangedValueEmit):"object"==s&&this.has(n,"random")?(i=n.random,Array.isArray(i)&&(this.start=i[0],this.end=i[1]),this.onEmit=this.randomRangedValueEmit):"object"==s&&this.hasEither(n,"onEmit","onUpdate")&&(this.has(n,"onEmit")&&(this.onEmit=n.onEmit),this.has(n,"onUpdate")&&(this.onUpdate=n.onUpdate)),this},has:function(t,e){return t.hasOwnProperty(e)},hasBoth:function(t,e,i){return t.hasOwnProperty(e)&&t.hasOwnProperty(i)},hasEither:function(t,e,i){return t.hasOwnProperty(e)||t.hasOwnProperty(i)},defaultEmit:function(t,e,i){return i},defaultUpdate:function(t,e,i,n){return n},staticValueEmit:function(){return this.propertyValue},staticValueUpdate:function(){return this.propertyValue},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.propertyValue[t]},randomRangedValueEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i),i},steppedEmit:function(){var t=this.counter,e=this.counter+(this.end-this.start)/this.steps;return this.counter=a(e,this.start,this.end),t},easedValueEmit:function(t,e){var i;return t&&t.data[e]&&((i=t.data[e]).min=this.start,i.max=this.end),this.start},easeValueUpdate:function(t,e,i){var n=t.data[e];return(n.max-n.min)*this.ease(i)+n.min}});t.exports=h},function(t,e,i){var n=i(0),o=i(2),s=new n({initialize:function(t,e,i,n,s){var r;"object"==typeof t?(t=o(r=t,"x",0),e=o(r,"y",0),i=o(r,"power",0),n=o(r,"epsilon",100),s=o(r,"gravity",50)):(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=100),void 0===s&&(s=50)),this.x=t,this.y=e,this.active=!0,this._gravity=s,this._power=0,this._epsilon=0,this.power=i,this.epsilon=n},update:function(t,e){var i,n,s=this.x-t.x,r=this.y-t.y,o=s*s+r*r;0!==o&&(i=Math.sqrt(o),oe.right&&t.collideRight&&(this.x=e.right,this.velocityX*=i),this.ye.bottom&&t.collideBottom&&(this.y=e.bottom,this.velocityY*=i)},update:function(t,e,i){if(0this._length&&(this.counter=this._length-1),this},changeSource:function(t){return this.source=t,this.updateSource()},getPoint:function(t){0===this._direction?(this.counter++,this.counter>=this._length&&(this.yoyo?(this._direction=1,this.counter=this._length-1):this.counter=0)):(this.counter--,-1===this.counter&&(this.yoyo?(this._direction=0,this.counter=0):this.counter=this._length-1));var e=this.points[this.counter];e&&(t.x=e.x,t.y=e.y)}});t.exports=n},function(t,e){t.exports=function(t,e){for(var i=0;id.PI2?s=d.PI2:s<0&&(s=d.PI2+s%d.PI2);for(var a,h=[r+Math.cos(n)*i,o+Math.sin(n)*i];e<1;)a=s*e+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),e+=t;return a=s+n,h.push(r+Math.cos(a)*i,o+Math.sin(a)*i),h.push(r+Math.cos(n)*i,o+Math.sin(n)*i),this.pathIndexes=u(h),this.pathData=h,this}});t.exports=r},function(t,e,i){var n=i(0),s=i(1094),r=i(68),o=i(10),a=i(32),h=new n({Extends:a,Mixins:[s],initialize:function(t,e,i,n,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",n),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==s&&this.setFillStyle(s,r),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){var t=this._curveBounds,e=this._smoothness;this.geom.getBounds(t,e),this.setSize(t.width,t.height),this.updateDisplayOrigin();for(var i=[],n=this.geom.getPoints(e),s=0;sthis.maxLights&&(u(n,this.sortByDistance),n=n.slice(0,this.maxLights)),this.visibleLights=n.length,n},sortByDistance:function(t,e){return t.distance>=e.distance},setAmbientColor:function(t){var e=c.getFloatsFromUintRGB(t);return this.ambientColor.set(e[0],e[1],e[2]),this},getMaxVisibleLights:function(){return this.maxLights},getLightCount:function(){return this.lights.length},addLight:function(t,e,i,n,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===n&&(n=16777215),void 0===s&&(s=1);var r=c.getFloatsFromUintRGB(n),o=new h(t,e,i,r[0],r[1],r[2],s);return this.lights.push(o),o},removeLight:function(t){var e=this.lights.indexOf(t);return 0<=e&&l(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(55),s=i(17)(!1,s={Circle:i(1185),Ellipse:i(1195),Intersects:i(478),Line:i(1215),Mesh:i(1237),Point:i(1240),Polygon:i(1254),Rectangle:i(496),Triangle:i(1287)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(228),CircleToRectangle:i(150),GetCircleToCircle:i(1205),GetCircleToRectangle:i(1206),GetLineToCircle:i(229),GetLineToLine:i(479),GetLineToPoints:i(480),GetLineToPolygon:i(481),GetLineToRectangle:i(231),GetRaysFromPointToPolygon:i(1207),GetRectangleIntersection:i(1208),GetRectangleToRectangle:i(1209),GetRectangleToTriangle:i(1210),GetTriangleToCircle:i(1211),GetTriangleToLine:i(486),GetTriangleToTriangle:i(1212),LineToCircle:i(230),LineToLine:i(92),LineToRectangle:i(482),PointToLine:i(490),PointToLineSegment:i(1213),RectangleToRectangle:i(114),RectangleToTriangle:i(483),RectangleToValues:i(1214),TriangleToCircle:i(485),TriangleToLine:i(487),TriangleToTriangle:i(488)}},function(t,e,i){var g=i(37);t.exports=function(t,e,i){var n=t.x1,s=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,l=r-n,u=o-s,c=e.x2-a,d=e.y2-h;if(0==l||0==d*l-c*u)return!1;var f=(l*(h-s)+u*(n-a))/(c*u-d*l),p=(a+c*f-n)/l;return p<0||f<0||1t.right||e.rightt.bottom||e.bottome.right||t.righte.bottom||t.bottome.right||t.righte.bottom||t.bottomt.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(s.BUTTON_DOWN,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(s.BUTTON_UP,e,this,t),this.pad.emit(s.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},function(t,e,i){var a=i(503),h=i(504),n=i(0),l=i(9),u=i(3),s=new n({Extends:l,initialize:function(t,e){l.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],n=0;n=s;for(this.fixedStep||(n=.001*e,o=!0,this._elapsed=0),h=0;h=s;)this._elapsed-=s,this.step(n)}},step:function(t){for(var e,i=this.bodies.entries,n=i.length,s=0;sc)&&(d.xu))return this.separateCircle(t,e,s)}var f=!1,p=!1;s?(f=M(t,e,s,this.OVERLAP_BIAS),p=P(t,e,s,this.OVERLAP_BIAS)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)=e.right||t.position.y>=e.bottom))},circleBodyIntersects:function(t,e){var i=p(t.center.x,e.left,e.right),n=p(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-n)*(t.center.y-n)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!0)},collide:function(t,e,i,n,s){return void 0===i&&(i=null),void 0===n&&(n=null),void 0===s&&(s=i),this.collideObjects(t,e,i,n,s,!1)},collideObjects:function(t,e,i,n,s,r){var o;t.isParent&&void 0===t.physicsType&&(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var a=Array.isArray(t),h=Array.isArray(e);if(this._total=0,a||h)if(!a&&h)for(o=0;od.baseTileWidth&&(h-=a=(d.tileWidth-d.baseTileWidth)*e.scaleX,u+=a),d.tileHeight>d.baseTileHeight&&(c+=(d.tileHeight-d.baseTileHeight)*e.scaleY);var f=S(h,l,u,c,null,e.scene.cameras.main,e.layer);return 0!==f.length&&this.collideSpriteVsTilesHandler(t,f,i,n,s,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,n,s,r,o){for(var a,h,l=t.body,u={left:0,right:0,top:0,bottom:0},c=!1,d=0;de.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=n,r=this.blocked.right=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=s,r=this.blocked.down=!0),r&&(this.blocked.none=!1,this.updateCenter()),r},setOffset:function(t,e){return void 0===e&&(e=t),this.offset.set(t,e),this},setSize:function(t,e,i){void 0===i&&(i=!0);var n,s,r=this.gameObject;return!t&&r.frame&&(t=r.frame.realWidth),!e&&r.frame&&(e=r.frame.realHeight),this.sourceWidth=t,this.sourceHeight=e,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter(),i&&r.getCenter&&(n=(r.width-t)/2,s=(r.height-e)/2,this.offset.set(n,s)),this.isCircle=!1,this.radius=0,this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),0=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom&&(this.center.x-t)*(this.center.x-t)+(this.center.y-e)*(this.center.y-e)<=this.radius*this.radius:h(this,t,e)},onFloor:function(){return this.blocked.down},onCeiling:function(){return this.blocked.up},onWall:function(){return this.blocked.left||this.blocked.right},deltaAbsX:function(){return 0=t.minX&&e.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(t,e,i,n,s){for(var r,o=[e,i];o.length;)(i=o.pop())-(e=o.pop())<=n||(r=e+Math.ceil((i-e)/n/2)*n,a(t,r,e,i,s),o.push(e,r,r,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],n=this.toBBox;if(!l(t,e))return i;for(var s,r,o,a,h=[];e;){for(s=0,r=e.children.length;sthis._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(s,r,e)},_split:function(t,e){var i=t[e],n=i.children.length,s=this._minEntries;this._chooseSplitAxis(i,s,n);var r=this._chooseSplitIndex(i,s,n),o=p(i.children.splice(r,i.children.length-r));o.height=i.height,o.leaf=i.leaf,f(i,this.toBBox),f(o,this.toBBox),e?t[e-1].children.push(o):this._splitRoot(i,o)},_splitRoot:function(t,e){this.data=p([t,e]),this.data.height=t.height+1,this.data.leaf=!1,f(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){for(var n,s,r,o,a,h,l,u,c,d,f,p,g=a=1/0,v=e;v<=i-e;v++)n=m(t,0,v,this.toBBox),s=m(t,v,i,this.toBBox),l=n,u=s,p=f=d=c=void 0,c=Math.max(l.minX,u.minX),d=Math.max(l.minY,u.minY),f=Math.min(l.maxX,u.maxX),p=Math.min(l.maxY,u.maxY),r=Math.max(0,f-c)*Math.max(0,p-d),o=y(n)+y(s),re.deltaAbsY()?g=-1:e.deltaAbsX()i&&s<(o=t.right-i)&&(o=0),0!==o&&(t.customSeparateX?t.overlapX=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):0i&&s<(o=t.bottom-i)&&(o=0),0!==o&&(t.customSeparateY?t.overlapY=o:c(t,o)),o}},function(t,e){t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):0n.worldView.x+s.scaleX*i.tileWidth*(-r-.5)&&a.xn.worldView.y+s.scaleY*i.tileHeight*(-o-1)&&a.y=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r,o,a=n.layers[n.i];n.i++,"imagelayer"===a.type?(s=h(a,"offsetx",0)+h(a,"startx",0),r=h(a,"offsety",0)+h(a,"starty",0),e.push({name:n.name+a.name,image:a.image,x:n.x+s+a.x,y:n.y+r+a.y,alpha:n.opacity*a.opacity,visible:n.visible&&a.visible,properties:h(a,"properties",{})})):"group"===a.type&&(o=l(t,a,n),i.push(n),n=o)}return e}},function(t,e,i){var d=i(2),f=i(256),p=i(568),g=i(159);t.exports=function(t){for(var e=[],i=[],n=g(t);n.i=n.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}n=i.pop()}else{var s,r=n.layers[n.i];if(n.i++,r.opacity*=n.opacity,r.visible=n.visible&&r.visible,"objectgroup"===r.type){r.name=n.name+r.name;for(var o=n.x+d(r,"startx",0)+d(r,"offsetx",0),a=n.y+d(r,"starty",0)+d(r,"offsety",0),h=[],l=0;l=r.layers.length){if(s.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=s.pop()}else{var o,a=r.layers[r.i];if(r.i++,"tilelayer"===a.type)if(a.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+a.name+"'");else{if(a.encoding&&"base64"===a.encoding){if(a.chunks)for(var h=0;h>>0;return n}},function(t,e,i){var w=i(121),b=i(572),E=i(256);t.exports=function(t){for(var e,i=[],n=[],s=null,r=0;r=this.firstgid&&tn&&(n=e.layer[r].width),e.layer[r].height>s&&(s=e.layer[r].height);var o=new h({width:n,height:s,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:a.WELTMEISTER});return o.layers=l(e,i),o.tilesets=u(e),o}},function(t,e,i){var d=i(119),f=i(83);t.exports=function(t,e){for(var i=[],n=0;n>>0;if("function"!=typeof t)throw new TypeError;for(var n=2<=arguments.length?arguments[1]:void 0,s=0;sthis.maxSpeedY&&(this._speedY=this.maxSpeedY)):this.down&&this.down.isDown&&(this._speedY-=this.accelY,this._speedY<-this.maxSpeedY&&(this._speedY=-this.maxSpeedY)),this.left&&this.left.isDown?(this._speedX+=this.accelX,this._speedX>this.maxSpeedX&&(this._speedX=this.maxSpeedX)):this.right&&this.right.isDown&&(this._speedX-=this.accelX,this._speedX<-this.maxSpeedX&&(this._speedX=-this.maxSpeedX)),this.zoomIn&&this.zoomIn.isDown?this._zoom=-this.zoomSpeed:this.zoomOut&&this.zoomOut.isDown?this._zoom=this.zoomSpeed:this._zoom=0,0!==this._speedX&&(e.scrollX-=this._speedX*t|0),0!==this._speedY&&(e.scrollY-=this._speedY*t|0),0!==this._zoom&&(e.zoom+=this._zoom,e.zoom<.001&&(e.zoom=.001)))},destroy:function(){this.camera=null,this.left=null,this.right=null,this.up=null,this.down=null,this.zoomIn=null,this.zoomOut=null}});t.exports=r},function(t,e,i){t.exports={Camera:i(320),BaseCamera:i(131),CameraManager:i(775),Effects:i(327),Events:i(35)}},function(t,e){t.exports="cameradestroy"},function(t,e){t.exports="camerafadeincomplete"},function(t,e){t.exports="camerafadeinstart"},function(t,e){t.exports="camerafadeoutcomplete"},function(t,e){t.exports="camerafadeoutstart"},function(t,e){t.exports="cameraflashcomplete"},function(t,e){t.exports="cameraflashstart"},function(t,e){t.exports="followupdate"},function(t,e){t.exports="camerapancomplete"},function(t,e){t.exports="camerapanstart"},function(t,e){t.exports="postrender"},function(t,e){t.exports="prerender"},function(t,e){t.exports="camerarotatecomplete"},function(t,e){t.exports="camerarotatestart"},function(t,e){t.exports="camerashakecomplete"},function(t,e){t.exports="camerashakestart"},function(t,e){t.exports="camerazoomcomplete"},function(t,e){t.exports="camerazoomstart"},function(t,e,i){var n=i(18),s=i(0),l=i(35),r=new s({initialize:function(t){this.camera=t,this.isRunning=!1,this.isComplete=!1,this.direction=!0,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,n,s,r,o,a){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===n&&(n=0),void 0===s&&(s=0),void 0===r&&(r=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!r&&this.isRunning)return this.camera;this.isRunning=!0,this.isComplete=!1,this.duration=e,this.direction=t,this.progress=0,this.red=i,this.green=n,this.blue=s,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a;var h=t?l.FADE_OUT_START:l.FADE_IN_START;return this.camera.emit(h,this.camera,this,e,i,n,s),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=n(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsedthis.source?Math.abs(this.destination-this.source):Math.abs(this.destination+h)-this.source)<(u=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+h)-this.destination)?this.clockwise=!0:uMath.PI&&(t-=n.PI2),Math.abs(((t+n.TAU)%n.PI2-n.PI2)%n.PI2)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(135);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(345);t.exports=function(t){return n(t+Math.PI)}},function(t,e,i){var n=i(14);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=n.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(e>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return 2.3283064365386963e-10*((this.n=i)>>>0)},init:function(t){"string"==typeof t?this.state(t):this.sow(t)},sow:function(t){if(this.n=4022871197,this.s0=this.hash(" "),this.s1=this.hash(" "),this.s2=this.hash(" "),this.c=1,t)for(var e=0;e 0.0)"," {"," c.rgb /= c.a;"," }",""," vec4 result;",""," result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];"," result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];"," result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];"," result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",""," vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",""," rgb *= result.a;",""," gl_FragColor = vec4(rgb, result.a);","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_COPY_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","uniform float uBrightness;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;","}",""].join("\n")},function(t,e){t.exports=["#define SHADER_NAME PHASER_LINEAR_BLEND_FS","","precision mediump float;","","uniform sampler2D uMainSampler1;","uniform sampler2D uMainSampler2;","uniform float uStrength;","","varying vec2 outTexCoord;","","void main ()","{"," vec4 frame1 = texture2D(uMainSampler1, outTexCoord);"," vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",""," gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);","}",""].join("\n")},function(t,e,i){t.exports={GenerateTexture:i(382),Palettes:i(885)}},function(t,e,i){t.exports={ARNE16:i(383),C64:i(886),CGA:i(887),JMP:i(888),MSX:i(889)}},function(t,e){t.exports={0:"#000",1:"#fff",2:"#8b4131",3:"#7bbdc5",4:"#8b41ac",5:"#6aac41",6:"#3931a4",7:"#d5de73",8:"#945a20",9:"#5a4100",A:"#bd736a",B:"#525252",C:"#838383",D:"#acee8b",E:"#7b73de",F:"#acacac"}},function(t,e){t.exports={0:"#000",1:"#2234d1",2:"#0c7e45",3:"#44aacc",4:"#8a3622",5:"#5c2e78",6:"#aa5c3d",7:"#b5b5b5",8:"#5e606e",9:"#4c81fb",A:"#6cd947",B:"#7be2f9",C:"#eb8a60",D:"#e23d69",E:"#ffd93f",F:"#fff"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#f5f4eb"}},function(t,e){t.exports={0:"#000",1:"#191028",2:"#46af45",3:"#a1d685",4:"#453e78",5:"#7664fe",6:"#833129",7:"#9ec2e8",8:"#dc534b",9:"#e18d79",A:"#d6b97b",B:"#e9d8a1",C:"#216c4b",D:"#d365c8",E:"#afaab9",F:"#fff"}},function(t,e,i){t.exports={Path:i(891),MoveTo:i(387),CubicBezier:i(384),Curve:i(90),Ellipse:i(385),Line:i(386),QuadraticBezier:i(388),Spline:i(389)}},function(t,e,i){var n=i(0),u=i(384),l=i(385),s=i(5),r=i(386),o=i(387),a=i(388),h=i(10),c=i(389),d=i(3),f=i(14),p=new n({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.name="",this.curves=[],this.cacheLengths=[],this.autoClose=!1,this.startPoint=new d,this._tmpVec2A=new d,this._tmpVec2B=new d,"object"==typeof t?this.fromJSON(t):this.startPoint.set(t,e)},add:function(t){return this.curves.push(t),this},circleTo:function(t,e,i){return void 0===e&&(e=!1),this.ellipseTo(t,t,0,360,e,i)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);return t.equals(e)||this.curves.push(new r(e,t)),this},cubicBezierTo:function(t,e,i,n,s,r){var o,a,h=this.getEndPoint(),l=t instanceof d?(o=t,a=e,i):(o=new d(i,n),a=new d(s,r),new d(t,e));return this.add(new u(h,o,a,l))},quadraticBezierTo:function(t,e,i,n){var s,r=this.getEndPoint(),o=t instanceof d?(s=t,e):(s=new d(i,n),new d(t,e));return this.add(new a(r,s,o))},draw:function(t,e){for(var i=0;i=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}s++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],n=0;n=i){var r=n[s]-i,o=this.curves[s],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}s++}return null},lineTo:function(t,e){t instanceof d?this._tmpVec2B.copy(t):this._tmpVec2B.set(t,e);var i=this.getEndPoint(this._tmpVec2A);return this.add(new r([i.x,i.y,this._tmpVec2B.x,this._tmpVec2B.y]))},splineTo:function(t){return t.unshift(this.getEndPoint()),this.add(new c(t))},moveTo:function(t,e){return t instanceof d?this.add(new o(t.x,t.y)):this.add(new o(t,e))},toJSON:function(){for(var t=[],e=0;e>16&255,g:t>>8&255,b:255&t,a:255};return 16777215>>24),e}},function(t,e,i){var h=i(36),l=i(393);t.exports=function(t,e,i){var n,s,r=i,o=i,a=i;return 0!==e&&(r=l(s=2*i-(n=i<.5?i*(1+e):i+e-i*e),n,t+1/3),o=l(s,n,t),a=l(s,n,t-1/3)),(new h).setGLTo(r,o,a,1)}},function(t,e,i){var s=i(185);t.exports=function(t,e){void 0===t&&(t=1),void 0===e&&(e=1);for(var i=[],n=0;n<=359;n++)i.push(s(n/359,t,e));return i}},function(t,e,i){function o(t,e,i,n,s,r,o,a){void 0===o&&(o=100),void 0===a&&(a=0);var h=a/o;return{r:l(t,n,h),g:l(e,s,h),b:l(i,r,h)}}var l=i(133);t.exports={RGBWithRGB:o,ColorWithRGB:function(t,e,i,n,s,r){return void 0===s&&(s=100),void 0===r&&(r=0),o(t.r,t.g,t.b,e,i,n,s,r)},ColorWithColor:function(t,e,i,n){return void 0===i&&(i=100),void 0===n&&(n=0),o(t.r,t.g,t.b,e.r,e.g,e.b,i,n)}}},function(t,e,i){var n=i(192),s=i(36);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new s(n(t,e),n(t,e),n(t,e))}},function(t,e,i){var r=i(392);t.exports=function(t,e,i,n,s){return void 0===n&&(n=255),void 0===s&&(s="#"),"#"===s?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(304),GeometryMask:i(305)}},function(t,e,i){var n={AddToDOM:i(140),DOMContentLoaded:i(394),GetInnerHeight:i(395),GetScreenOrientation:i(396),GetTarget:i(401),ParseXML:i(402),RemoveFromDOM:i(199),RequestAnimationFrame:i(380)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(915)}},function(t,e,i){var n=i(0),s=i(9),r=i(24),o=new n({Extends:s,initialize:function(){s.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},function(t,e,i){var n=i(140),s=i(315),r=i(319),o=i(31),a=i(0),h=i(340),l=i(917),u=i(360),c=i(98),d=i(378),f=i(341),p=i(394),g=i(9),v=i(22),m=i(403),y=i(24),x=i(408),T=i(409),w=i(411),b=i(103),E=i(416),S=i(379),A=i(381),_=i(420),C=new a({initialize:function(t){this.config=new h(t),this.renderer=null,this.domContainer=null,this.canvas=null,this.context=null,this.isBooted=!1,this.isRunning=!1,this.events=new g,this.anims=new s(this),this.textures=new E(this),this.cache=new r(this),this.registry=new c(this),this.input=new m(this,this.config),this.scene=new w(this,this.config.sceneConfig),this.device=f,this.scale=new T(this,this.config),this.sound=null,this.sound=_.create(this),this.loop=new S(this,this.config.fps),this.plugins=new x(this,this.config),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,p(this.boot.bind(this))},boot:function(){y.hasCore("EventEmitter")?(this.isBooted=!0,this.config.preBoot(this),this.scale.preBoot(),u(this),l(this),d(this),n(this.canvas,this.config.parent),this.textures.once(b.READY,this.texturesReady,this),this.events.emit(v.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(v.READY),this.start()},start:function(){this.isRunning=!0,this.config.postBoot(this),this.renderer?this.loop.start(this.step.bind(this)):this.loop.start(this.headlessStep.bind(this)),A(this);var t=this.events;t.on(v.HIDDEN,this.onHidden,this),t.on(v.VISIBLE,this.onVisible,this),t.on(v.BLUR,this.onBlur,this),t.on(v.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e);var n=this.renderer;n.preRender(),i.emit(v.PRE_RENDER,n,t,e),this.scene.render(n),n.postRender(),i.emit(v.POST_RENDER,n,t,e)},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();var i=this.events;i.emit(v.PRE_STEP,t,e),i.emit(v.STEP,t,e),this.scene.update(t,e),i.emit(v.POST_STEP,t,e),i.emit(v.PRE_RENDER),i.emit(v.POST_RENDER)},onHidden:function(){this.loop.pause(),this.events.emit(v.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(v.RESUME)},onBlur:function(){this.hasFocus=!1,this.loop.blur()},onFocus:function(){this.hasFocus=!0,this.loop.focus()},getFrame:function(){return this.loop.frame},getTime:function(){return this.loop.now},destroy:function(t,e){void 0===e&&(e=!1),this.pendingDestroy=!0,this.removeCanvas=t,this.noReturn=e},runDestroy:function(){this.scene.destroy(),this.events.emit(v.DESTROY),this.events.removeAllListeners(),this.renderer&&this.renderer.destroy(),this.removeCanvas&&this.canvas&&(o.remove(this.canvas),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)),this.domContainer&&this.domContainer.parentNode.removeChild(this.domContainer),this.loop.destroy(),this.pendingDestroy=!1}});t.exports=C},function(t,e,i){var n=i(140);t.exports=function(t){var e,i=t.config;i.parent&&i.domCreateContainer&&((e=document.createElement("div")).style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: none;","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=e,n(e,i.parent))}},function(t,e){t.exports="boot"},function(t,e){t.exports="destroy"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameout"},function(t,e){t.exports="gameover"},function(t,e){t.exports="gameobjectdown"},function(t,e){t.exports="dragend"},function(t,e){t.exports="dragenter"},function(t,e){t.exports="drag"},function(t,e){t.exports="dragleave"},function(t,e){t.exports="dragover"},function(t,e){t.exports="dragstart"},function(t,e){t.exports="drop"},function(t,e){t.exports="gameobjectmove"},function(t,e){t.exports="gameobjectout"},function(t,e){t.exports="gameobjectover"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="wheel"},function(t,e){t.exports="gameobjectup"},function(t,e){t.exports="gameobjectwheel"},function(t,e){t.exports="boot"},function(t,e){t.exports="process"},function(t,e){t.exports="update"},function(t,e){t.exports="pointerdown"},function(t,e){t.exports="pointerdownoutside"},function(t,e){t.exports="pointermove"},function(t,e){t.exports="pointerout"},function(t,e){t.exports="pointerover"},function(t,e){t.exports="pointerup"},function(t,e){t.exports="pointerupoutside"},function(t,e){t.exports="wheel"},function(t,e){t.exports="pointerlockchange"},function(t,e){t.exports="preupdate"},function(t,e){t.exports="shutdown"},function(t,e){t.exports="start"},function(t,e){t.exports="update"},function(t,e){t.exports="addfile"},function(t,e){t.exports="complete"},function(t,e){t.exports="filecomplete"},function(t,e){t.exports="filecomplete-"},function(t,e){t.exports="loaderror"},function(t,e){t.exports="load"},function(t,e){t.exports="fileprogress"},function(t,e){t.exports="postprocess"},function(t,e){t.exports="progress"},function(t,e){t.exports="start"},function(t,e,i){t.exports={game:"game",renderer:"renderer",anims:"anims",cache:"cache",plugins:"plugins",registry:"registry",scale:"scale",sound:"sound",textures:"textures",events:"events",cameras:"cameras",add:"add",make:"make",scenePlugin:"scene",displayList:"children",lights:"lights",data:"data",input:"input",load:"load",time:"time",tweens:"tweens",arcadePhysics:"physics",impactPhysics:"impact",matterPhysics:"matter"}},function(t,e){t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var s=i.getElementsByTagName("SubTexture"),r=0;r=t.length)throw new Error("Supplied index out of bounds");return n!==i&&(t.splice(n,1),t.splice(i,0,e)),e}},function(t,e){t.exports=function(t,e){var i,n,s=t.indexOf(e);return-1!==s&&st.length-1)throw new Error("Index out of bounds");var s=r(t,e);return i&&i.call(n,s),s}},function(t,e,i){var l=i(78);t.exports=function(t,e,i,n,s){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===s&&(s=t),l(t,e,i)){var r=i-e,o=t.splice(e,r);if(n)for(var a=0;a?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",TEXT_SET2:" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET3:"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",TEXT_SET4:"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",TEXT_SET5:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",TEXT_SET6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789\"(),-.' ",TEXT_SET7:"AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW\")28FLRX-'39",TEXT_SET8:"0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET9:"ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'\"?!",TEXT_SET10:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",TEXT_SET11:"ABCDEFGHIJKLMNOPQRSTUVWXYZ.,\"-+!?()':;0123456789"}},function(t,e,i){var P=i(6);t.exports=function(t,e){var i=e.width,n=e.height,s=Math.floor(i/2),r=Math.floor(n/2),o=P(e,"chars","");if(""!==o){var a=P(e,"image",""),h=t.sys.textures.getFrame(a),l=h.cutX,u=h.cutY,c=h.source.width,d=h.source.height,f=P(e,"offset.x",0),p=P(e,"offset.y",0),g=P(e,"spacing.x",0),v=P(e,"spacing.y",0),m=P(e,"lineSpacing",0),y=P(e,"charsPerRow",null);null===y&&(y=c/i)>o.length&&(y=o.length);for(var x=f,T=p,w={retroFont:!0,font:a,size:i,lineHeight:n+m,chars:{}},b=0,E=0;E=i&&t.x<=n&&t.y>=s&&t.y<=r}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||s=n&&(p.push(v),f=v)}var m=o[o.length-1];return y(f,m)i&&(i=a.x),a.xs&&(s=a.y),a.yn(e)?t.setSize(e.height*i,e.height):t.setSize(e.width,e.width/i),t.setPosition(e.centerX-t.width/2,e.centerY-t.height/2)}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},function(t,e){t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t.width=Math.floor(t.width),t.height=Math.floor(t.height),t}},function(t,e,i){var r=i(10);t.exports=function(t,e,i,n,s){return void 0===s&&(s=new r),s.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.centerX,e.y=t.centerY,e}},function(t,e,i){var n=i(4);t.exports=function(t,e){return void 0===e&&(e=new n),e.x=t.width,e.y=t.height,e}},function(t,e,i){var r=i(187);t.exports=function(t,e,i){var n=t.centerX,s=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),r(t,n,s)}},function(t,e,i){var n=i(10),s=i(114);t.exports=function(t,e,i){return void 0===i&&(i=new n),s(t,e)?(i.x=Math.max(t.x,e.x),i.y=Math.max(t.y,e.y),i.width=Math.min(t.right,e.right)-i.x,i.height=Math.min(t.bottom,e.bottom)-i.y):i.setEmpty(),i}},function(t,e){t.exports=function(t,e){for(var i=t.x,n=t.right,s=t.y,r=t.bottom,o=0;oe.x&&t.ye.y}},function(t,e,i){var a=i(4),h=i(34);t.exports=function(t,e,i){void 0===i&&(i=new a),e=h(e);var n=Math.sin(e),s=Math.cos(e),r=0=s||0=t.downTime+n)&&(i=!0),i)return this.setDragState(t,3),this.processDragStartList(t)},processDragStartList:function(t){if(3!==this.getDragState(t))return 0;for(var e=this._drag[t.id],i=0;it._tick)return t._tick=i,!0}return!1},update:function(){var t=this.manager.queue,e=t.length;if(this.isActive()&&0!==e)for(var i=this.keys,n=0;n'),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var n=[i.join("\n")],s=this;try{var r=new window.Blob(n,{type:"image/svg+xml;charset=utf-8"})}catch(t){return s.state=o.FILE_ERRORED,void s.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){l.revokeObjectURL(s.data),s.onProcessComplete()},this.data.onerror=function(){l.revokeObjectURL(s.data),s.onProcessError()},l.createObjectURL(this.data,r,"image/svg+xml")},addToCache:function(){var t=this.cache.addImage(this.key,this.data);this.pendingDestroy(t)}});s.register("htmlTexture",function(t,e,i,n,s){if(Array.isArray(t))for(var r=0;r=n[2];if("^"===i.operator)return 0=i.number:0=n[2]:r[2]===n[2]}return t===e||"*"===t}},function(t,e,i){var n={};t.exports=n;var s=i(163),r=(i(246),i(50));n.create=function(t){var e=s.create(),i={label:"World",gravity:{x:0,y:1,scale:.001},bounds:{min:{x:-1/0,y:-1/0},max:{x:1/0,y:1/0}}};return r.extend(e,i,t)}},function(t,e,i){var y={};t.exports=y;var a=i(535),n=i(587),r=i(50);y.create=function(t){var e={controller:y,detector:n.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return r.extend(e,t)},y.update=function(t,e,i,n){for(var s,r,o,a=i.world,h=t.buckets,l=!1,u=i.metrics,c=u.broadphaseTests=0;ca.bounds.max.x||d.bounds.max.ya.bounds.max.y)){var f=y._getRegion(t,d);if(!d.region||f.id!==d.region.id||n){u.broadphaseTests+=1,d.region&&!n||(d.region=f);for(var p=y._regionUnion(f,d.region),g=p.startCol;g<=p.endCol;g++)for(s=p.startRow;s<=p.endRow;s++){r=h[o=y._getBucketId(g,s)];var v=g>=f.startCol&&g<=f.endCol&&s>=f.startRow&&s<=f.endRow,m=g>=d.region.startCol&&g<=d.region.endCol&&s>=d.region.startRow&&s<=d.region.endRow;!v&&m&&m&&r&&y._bucketRemoveBody(t,r,d),(d.region===f||v&&!m||n)&&(r=r||y._createBucket(h,o),y._bucketAddBody(t,r,d))}d.region=f,l=!0}}}l&&(t.pairsList=y._createActivePairsList(t))},y.clear=function(t){t.buckets={},t.pairs={},t.pairsList=[]},y._regionUnion=function(t,e){var i=Math.min(t.startCol,e.startCol),n=Math.max(t.endCol,e.endCol),s=Math.min(t.startRow,e.startRow),r=Math.max(t.endRow,e.endRow);return y._createRegion(i,n,s,r)},y._getRegion=function(t,e){var i=e.bounds,n=Math.floor(i.min.x/t.bucketWidth),s=Math.floor(i.max.x/t.bucketWidth),r=Math.floor(i.min.y/t.bucketHeight),o=Math.floor(i.max.y/t.bucketHeight);return y._createRegion(n,s,r,o)},y._createRegion=function(t,e,i,n){return{id:t+","+e+","+i+","+n,startCol:t,endCol:e,startRow:i,endRow:n}},y._getBucketId=function(t,e){return"C"+t+"R"+e},y._createBucket=function(t,e){return t[e]=[]},y._bucketAddBody=function(t,e,i){for(var n=0;nl._pairMaxIdleLife&&a.push(h);for(h=0;hu.friction*u.frictionStatic*O*i&&(D=M,L=X.clamp(u.friction*P*i,-D,D));var F,k,I=U.cross(w,p),B=U.cross(b,p),N=m/(d.inverseMass+f.inverseMass+d.inverseInertia*I*I+f.inverseInertia*B*B);R*=N,L*=N,_<0&&_*_>Y._restingThresh*i?x.normalImpulse=0:(F=x.normalImpulse,x.normalImpulse=Math.min(x.normalImpulse+R,0),R=x.normalImpulse-F),C*C>Y._restingThreshTangent*i?x.tangentImpulse=0:(k=x.tangentImpulse,x.tangentImpulse=X.clamp(x.tangentImpulse+L,-D,D),L=x.tangentImpulse-k),n.x=p.x*R+g.x*L,n.y=p.y*R+g.y*L,d.isStatic||d.isSleeping||(d.positionPrev.x+=n.x*d.inverseMass,d.positionPrev.y+=n.y*d.inverseMass,d.anglePrev+=U.cross(w,n)*d.inverseInertia),f.isStatic||f.isSleeping||(f.positionPrev.x-=n.x*f.inverseMass,f.positionPrev.y-=n.y*f.inverseMass,f.anglePrev-=U.cross(b,n)*f.inverseInertia)}}}}},function(t,e,i){t.exports={BasePlugin:i(536),DefaultPlugins:i(194),PluginCache:i(24),PluginManager:i(408),ScenePlugin:i(1398)}},function(t,e,i){var n=i(536),s=i(0),r=i(21),o=new s({Extends:n,initialize:function(t,e){n.call(this,e),this.scene=t,this.systems=t.sys,t.sys.events.once(r.BOOT,this.boot,this)},boot:function(){},destroy:function(){this.pluginManager=null,this.game=null,this.scene=null,this.systems=null}});t.exports=o},function(t,e,i){t.exports={Canvas:i(1400),Events:i(88),Snapshot:i(1401),WebGL:i(1402)}},function(t,e,i){t.exports={CanvasRenderer:i(362),GetBlendModes:i(364),SetTransform:i(30)}},function(t,e,i){t.exports={Canvas:i(363),WebGL:i(377)}},function(t,e,i){var n=i(104),s=i(17)(!1,s={PipelineManager:i(366),Pipelines:i(1403),RenderTarget:i(139),Utils:i(12),WebGLPipeline:i(57),WebGLRenderer:i(365),WebGLShader:i(369)},n);t.exports=s},function(t,e,i){var n=i(65),s=i(17)(!1,s={BitmapMaskPipeline:i(367),Events:i(368),GraphicsPipeline:i(370),LightPipeline:i(371),MultiPipeline:i(105),PointLightPipeline:i(372),PostFXPipeline:i(1404),RopePipeline:i(373),SinglePipeline:i(374),UtilityPipeline:i(375)},n);t.exports=s},function(t,e,i){var n=i(0),s=i(195),r=i(2),o=i(1405),a=i(376),h=i(57),l=new n({Extends:h,initialize:function(t){t.renderTarget=r(t,"renderTarget",1),t.fragShader=r(t,"fragShader",o),t.vertShader=r(t,"vertShader",a),t.attributes=r(t,"attributes",[{name:"inPosition",size:2},{name:"inTexCoord",size:2}]),t.batchSize=1,t.vertices=[-1,-1,0,0,-1,1,0,1,1,1,1,1,-1,-1,0,0,1,1,1,1,1,-1,1,0],h.call(this,t),this.isPostFX=!0,this.gameObject,this.colorMatrix=new s,this.fullFrame1,this.fullFrame2,this.halfFrame1,this.halfFrame2,this.renderer.isBooted&&(this.manager=this.renderer.pipelines,this.boot())},boot:function(){h.prototype.boot.call(this);var t=this.manager.UTILITY_PIPELINE;this.fullFrame1=t.fullFrame1,this.fullFrame2=t.fullFrame2,this.halfFrame1=t.halfFrame1,this.halfFrame2=t.halfFrame2,this.set1i("uMainSampler",0)},onDraw:function(t){this.bindAndDraw(t)},copyFrame:function(t,e,i,n,s){this.manager.copyFrame(t,e,i,n,s)},copyToGame:function(t){this.manager.copyToGame(t)},drawFrame:function(t,e,i){this.manager.drawFrame(t,e,i,this.colorMatrix)},blendFrames:function(t,e,i,n,s){this.manager.blendFrames(t,e,i,n,s)},blendFramesAdditive:function(t,e,i,n,s){this.manager.blendFramesAdditive(t,e,i,n,s)},clearFrame:function(t,e){this.manager.clearFrame(t,e)},blitFrame:function(t,e,i,n,s,r){this.manager.blitFrame(t,e,i,n,s,r)},copyFrameRect:function(t,e,i,n,s,r,o,a){this.manager.copyFrameRect(t,e,i,n,s,r,o,a)},bindAndDraw:function(t,e,i,n,s){void 0===i&&(i=!0),void 0===n&&(n=!0);var r=this.gl,o=this.renderer;this.bind(s),this.set1i("uMainSampler",0),e?(r.viewport(0,0,e.width,e.height),r.bindFramebuffer(r.FRAMEBUFFER,e.framebuffer),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,e.texture,0),i&&(n?r.clearColor(0,0,0,0):r.clearColor(0,0,0,1),r.clear(r.COLOR_BUFFER_BIT))):(o.popFramebuffer(!1,!1,!1),o.currentFramebuffer||r.viewport(0,0,o.width,o.height)),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,t.texture),r.bufferData(r.ARRAY_BUFFER,this.vertexData,r.STATIC_DRAW),r.drawArrays(r.TRIANGLES,0,6),e?(r.bindTexture(r.TEXTURE_2D,null),r.bindFramebuffer(r.FRAMEBUFFER,null)):o.resetTextures()}});t.exports=l},function(t,e){t.exports=["#define SHADER_NAME PHASER_POSTFX_FS","","precision mediump float;","","uniform sampler2D uMainSampler;","","varying vec2 outTexCoord;","","void main ()","{"," gl_FragColor = texture2D(uMainSampler, outTexCoord);","}",""].join("\n")},function(t,e,i){var n=i(17),s=i(198),r=n(!1,r={Center:i(397),Events:i(101),Orientation:i(398),ScaleManager:i(409),ScaleModes:i(399),Zoom:i(400)},s.CENTER);r=n(!1,r,s.ORIENTATION),r=n(!1,r,s.SCALE_MODE),r=n(!1,r,s.ZOOM),t.exports=r},function(t,e,i){var n=i(142),s=i(17)(!1,s={Events:i(21),GetPhysicsPlugins:i(413),GetScenePlugins:i(414),SceneManager:i(411),ScenePlugin:i(1408),Settings:i(415),Systems:i(201)},n);t.exports=s},function(t,e,i){var n=i(18),s=i(0),a=i(21),h=i(2),r=i(24),o=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.settings=t.sys.settings,this.key=t.sys.settings.key,this.manager=t.sys.game.scene,this.transitionProgress=0,this._elapsed=0,this._target=null,this._duration=0,this._onUpdate,this._onUpdateScope,this._willSleep=!1,this._willRemove=!1,t.sys.events.once(a.BOOT,this.boot,this),t.sys.events.on(a.START,this.pluginStart,this)},boot:function(){this.systems.events.once(a.DESTROY,this.destroy,this)},pluginStart:function(){this._target=null,this.systems.events.once(a.SHUTDOWN,this.shutdown,this)},start:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",this.key),this.manager.queueOp("start",t,e),this},restart:function(t){var e=this.key;return this.manager.queueOp("stop",e),this.manager.queueOp("start",e,t),this},transition:function(t){void 0===t&&(t={});var e=h(t,"target",!1),i=this.manager.getScene(e);if(!e||!this.checkValidTransition(i))return!1;var n=h(t,"duration",1e3);this._elapsed=0,this._target=i,this._duration=n,this._willSleep=h(t,"sleep",!1),this._willRemove=h(t,"remove",!1);var s=h(t,"onUpdate",null);s&&(this._onUpdate=s,this._onUpdateScope=h(t,"onUpdateScope",this.scene));var r=h(t,"allowInput",!1);this.settings.transitionAllowInput=r;var o=i.sys.settings;return o.isTransition=!0,o.transitionFrom=this.scene,o.transitionDuration=n,o.transitionAllowInput=r,h(t,"moveAbove",!1)?this.manager.moveAbove(this.key,e):h(t,"moveBelow",!1)&&this.manager.moveBelow(this.key,e),i.sys.isSleeping()?i.sys.wake(h(t,"data")):this.manager.start(e,h(t,"data")),this.systems.events.emit(a.TRANSITION_OUT,i,n),this.systems.events.on(a.UPDATE,this.step,this),!0},checkValidTransition:function(t){return!(!t||t.sys.isActive()||t.sys.isTransitioning()||t===this.scene||this.systems.isTransitioning())},step:function(t,e){this._elapsed+=e,this.transitionProgress=n(this._elapsed/this._duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.transitionProgress),this._elapsed>=this._duration&&this.transitionComplete()},transitionComplete:function(){var t=this._target.sys,e=this._target.sys.settings;this.systems.events.off(a.UPDATE,this.step,this),t.events.emit(a.TRANSITION_COMPLETE,this.scene),e.isTransition=!1,e.transitionFrom=null,this._duration=0,this._target=null,this._onUpdate=null,this._onUpdateScope=null,this._willRemove?this.manager.remove(this.key):this._willSleep?this.systems.sleep():this.manager.stop(this.key)},add:function(t,e,i,n){return this.manager.add(t,e,i,n)},launch:function(t,e){return t&&t!==this.key&&this.manager.queueOp("start",t,e),this},run:function(t,e){return t&&t!==this.key&&this.manager.queueOp("run",t,e),this},pause:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("pause",t,e),this},resume:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("resume",t,e),this},sleep:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("sleep",t,e),this},wake:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("wake",t,e),this},switch:function(t){return t!==this.key&&this.manager.queueOp("switch",this.key,t),this},stop:function(t,e){return void 0===t&&(t=this.key),this.manager.queueOp("stop",t,e),this},setActive:function(t,e,i){void 0===e&&(e=this.key);var n=this.manager.getScene(e);return n&&n.sys.setActive(t,i),this},setVisible:function(t,e){void 0===e&&(e=this.key);var i=this.manager.getScene(e);return i&&i.sys.setVisible(t),this},isSleeping:function(t){return void 0===t&&(t=this.key),this.manager.isSleeping(t)},isActive:function(t){return void 0===t&&(t=this.key),this.manager.isActive(t)},isPaused:function(t){return void 0===t&&(t=this.key),this.manager.isPaused(t)},isVisible:function(t){return void 0===t&&(t=this.key),this.manager.isVisible(t)},swapPosition:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.swapPosition(t,e),this},moveAbove:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveAbove(t,e),this},moveBelow:function(t,e){return void 0===e&&(e=this.key),t!==e&&this.manager.moveBelow(t,e),this},remove:function(t){return void 0===t&&(t=this.key),this.manager.remove(t),this},moveUp:function(t){return void 0===t&&(t=this.key),this.manager.moveUp(t),this},moveDown:function(t){return void 0===t&&(t=this.key),this.manager.moveDown(t),this},bringToTop:function(t){return void 0===t&&(t=this.key),this.manager.bringToTop(t),this},sendToBack:function(t){return void 0===t&&(t=this.key),this.manager.sendToBack(t),this},get:function(t){return this.manager.getScene(t)},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(a.SHUTDOWN,this.shutdown,this),t.off(a.POST_UPDATE,this.step,this),t.off(a.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});r.register("ScenePlugin",o,"scenePlugin"),t.exports=o},function(t,e,i){t.exports={Events:i(432),List:i(107),Map:i(99),ProcessQueue:i(208),RTree:i(525),Set:i(148),Size:i(410)}},function(t,e,i){var n=i(17),s=i(1411),r=n(!1,r={CanvasTexture:i(417),Events:i(103),FilterMode:s,Frame:i(106),Parsers:i(419),Texture:i(203),TextureManager:i(416),TextureSource:i(418)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(17),s=i(1413),r=n(!1,r={Components:i(247),Parsers:i(1446),Formats:i(38),ImageCollection:i(572),ParseToTilemap:i(258),Tile:i(83),Tilemap:i(576),TilemapCreator:i(1452),TilemapFactory:i(1453),Tileset:i(121),TilemapLayer:i(577),Orientation:i(29),LayerData:i(119),MapData:i(120),ObjectLayer:i(568)},s.ORIENTATION);t.exports=r},function(t,e,i){var n={ORIENTATION:i(29)};t.exports=n},function(t,e,i){var p=i(26),g=i(61);t.exports=function(t,e,i,n,s,r,o,a){void 0===o&&(o=!0),t<0&&(t=0),e<0&&(e=0);for(var h=p(t,e,i,n,null,a),l=s-t,u=r-e,c=0;c=t&&l.index<=e&&u(l,i)}n&&c(0,0,s.width,s.height,s)}}},function(t,e,i){var a=i(72),h=i(61),l=i(158);t.exports=function(t,e,i,n){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var s=0;s=s.delay&&(n=s.elapsed-s.delay,s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),0>2],s+=o[(3&i[r])<<4|i[r+1]>>4],s+=o[(15&i[r+1])<<2|i[r+2]>>6],s+=o[63&i[r+2]];return n%3==2?s=s.substring(0,s.length-1)+"=":n%3==1&&(s=s.substring(0,s.length-2)+"=="),s}},function(t,e,i){t.exports={Clone:i(77),DeepCopy:i(172),Extend:i(17),GetAdvancedValue:i(13),GetFastValue:i(2),GetMinMaxValue:i(1478),GetValue:i(6),HasAll:i(1479),HasAny:i(449),HasValue:i(125),IsPlainObject:i(7),Merge:i(143),MergeRight:i(1480),Pick:i(567),SetValue:i(472)}},function(t,e,i){var o=i(6),a=i(18);t.exports=function(t,e,i,n,s){void 0===s&&(s=i);var r=o(t,e,s);return a(r,i,n)}},function(t,e){t.exports=function(t,e){for(var i=0;ii[e][0])&&(e=n);return!S(P(t,e-1),P(t,e),P(t,e+1))&&(function(t){for(var e=[],i=t.length,n=0;n!==i;n++)e.push(t.pop());for(n=0;n!==i;n++)t[n]=e[n]}(t),!0)}};var u=[],c=[];function M(t,e){var i=e[0]-t[0],n=e[1]-t[1];return i*i+n*n}function P(t,e){var i=t.length;return t[e<0?e%i+i:e%i]}function R(t,e,i,n){for(var s=i;sn.deltaMax?n.deltaMax:e)/n.delta,n.delta=e),0!==n.timeScalePrev&&(r*=s.timeScale/n.timeScalePrev),0===s.timeScale&&(r=0),n.timeScalePrev=s.timeScale,n.correction=r,n.frameCounter+=1,1e3<=t-n.counterTimestamp&&(n.fps=n.frameCounter*((t-n.counterTimestamp)/1e3),n.counterTimestamp=t,n.frameCounter=0),T.update(i,e,r))},step:function(t,e){T.update(this.engine,t,e)},update60Hz:function(){return 1e3/60},update30Hz:function(){return 1e3/30},has:function(t){var e=t.hasOwnProperty("body")?t.body:t;return null!==u.get(this.localWorld,e.id,e.type)},getAllBodies:function(){return u.allBodies(this.localWorld)},getAllConstraints:function(){return u.allConstraints(this.localWorld)},getAllComposites:function(){return u.allComposites(this.localWorld)},postUpdate:function(){var t,e,i,n;this.drawDebug&&(t=this.debugConfig,e=this.engine,i=this.debugGraphic,n=u.allBodies(this.localWorld),this.debugGraphic.clear(),t.showBroadphase&&e.broadphase.controller&&this.renderGrid(e.broadphase,i,t.broadphaseColor,.5),t.showBounds&&this.renderBodyBounds(n,i,t.boundsColor,.5),(t.showBody||t.showStaticBody)&&this.renderBodies(n),t.showJoint&&this.renderJoints(),(t.showAxes||t.showAngleIndicator)&&this.renderBodyAxes(n,i,t.showAxes,t.angleColor,.5),t.showVelocity&&this.renderBodyVelocity(n,i,t.velocityColor,1,2),t.showSeparations&&this.renderSeparations(e.pairs.list,i,t.separationColor),t.showCollisions&&this.renderCollisions(e.pairs.list,i,t.collisionColor))},renderGrid:function(t,e,i,n){e.lineStyle(1,i,n);for(var s=y.keys(t.buckets),r=0;re.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?n=e.min.y-t.max.y:t.max.y